Connecting Spring Boot to PlanetScale using JDBC is surprisingly straightforward, but the key isn’t just getting it to work, it’s understanding how PlanetScale’s architecture demands specific connection pool configurations that many default Spring Boot setups miss entirely.

Let’s see it in action. Here’s a minimal application.properties to get you started:

spring.datasource.url=jdbc:mysql://your-planetscale-host:3306/your-database?sslMode=VERIFY_IDENTITY&sslCa=/path/to/your/ca.pem
spring.datasource.username=your-username
spring.datasource.password=your-password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# --- Crucial PlanetScale Tuning ---
spring.jpa.hibernate.ddl-auto=none
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.connection.provider_class=com.zaxxer.hikari.HikariCPConnectionProvider
spring.jpa.properties.hibernate.hikari.connectionTimeout=30000
spring.jpa.properties.hibernate.hikari.idleTimeout=600000
spring.jpa.properties.hibernate.hikari.maxLifetime=1800000
spring.jpa.properties.hibernate.hikari.maximumPoolSize=5
spring.jpa.properties.hibernate.hikari.minimumIdle=2

Now, imagine a simple User entity and a UserRepository interface:

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    // getters and setters
}
public interface UserRepository extends JpaRepository<User, Long> {
}

And a service to use it:

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    @Transactional
    public User createUser(String username) {
        User user = new User();
        user.setUsername(username);
        return userRepository.save(user);
    }

    public List<User> getAllUsers() {
        return userRepository.findAll();
    }
}

When you run your Spring Boot application, Spring Boot’s auto-configuration will kick in. It sees the spring.datasource.url, username, and password properties. It then finds the com.mysql.cj.jdbc.Driver and sets up a DataSource. By default, if you’re using Spring Boot 2.x or later, it’ll use HikariCP as the connection pool.

The spring.datasource.url is the direct line to your PlanetScale database. The sslMode=VERIFY_IDENTITY and sslCa=/path/to/your/ca.pem are non-negotiable for PlanetScale. You must download your database’s CA certificate from the PlanetScale dashboard and provide the correct path. Without proper SSL verification, PlanetScale will reject your connection.

The real magic for PlanetScale lies in the HikariCP properties. PlanetScale is a distributed SQL database, and its architecture means connections can be more ephemeral than a traditional single-node MySQL instance. You don’t want your connection pool holding onto idle connections for too long, only to have them silently dropped by PlanetScale’s infrastructure.

  • hibernate.hikari.connectionTimeout=30000: How long a client will wait for a connection from the pool. 30 seconds is generous.
  • hibernate.hikari.idleTimeout=600000: How long an idle connection can stay in the pool before being retired. 10 minutes (600,000 ms) is a common sweet spot; it’s long enough to reuse connections but short enough to avoid stale ones.
  • hibernate.hikari.maxLifetime=1800000: The maximum amount of time a connection can live, regardless of whether it’s idle or in use. 30 minutes (1,800,000 ms) is a good balance; it ensures connections are periodically refreshed.
  • hibernate.hikari.maximumPoolSize=5: This is critical. PlanetScale has connection limits per branch. For development or small applications, keeping this low is essential. Don’t let your application hog connections. Start small and scale up only if necessary and if you’ve confirmed your PlanetScale plan allows it. For many simple apps, 5 is plenty.
  • hibernate.hikari.minimumIdle=2: Ensures there are always a couple of warm connections ready to go, reducing latency for the first few requests.

The spring.jpa.hibernate.ddl-auto=none is a safety measure. PlanetScale’s schema management is best handled through its branching and deployment workflow, not by Hibernate trying to auto-create or update tables on startup.

The reason maximumPoolSize is so important is tied to PlanetScale’s sharding and connection handling. Unlike a single monolithic database server, PlanetScale’s infrastructure might route your connection through different network paths or even different underlying compute resources over time. If your pool is too large and connections are left idle for extended periods, they might become stale from PlanetScale’s perspective even if HikariCP thinks they’re fine. By setting idleTimeout and maxLifetime appropriately, you ensure that connections are regularly cycled, reducing the chance of hitting a stale or dropped connection that the pool isn’t aware of. Furthermore, PlanetScale databases have a finite number of concurrent connections available per plan. Over-allocating your pool can lead to connection refused errors, even if your application isn’t actively executing many queries.

You’ll next want to explore PlanetScale’s schema diffing and deployment workflows, as relying on ddl-auto will prevent you from leveraging its core strengths.

Want structured learning?

Take the full Planetscale course →