跪拜 Guibai
← Back to the summary

HikariCP Connection Pool Tuning That Won't Crash Your Database

Connection Pool Parameter Governance: How to Configure HikariCP for Stability in KingbaseES Scenarios

An application being able to connect to a database is only the first step. Under real concurrent access, the connection pool is the most critical buffer layer between the application and the database. If the pool is too small, interfaces will queue; if too large, the database will be dragged down by numerous connections; unreasonable timeout settings will cause request pile-ups; undetected connection leaks will make the system run slower and slower.

Spring Boot defaults to using HikariCP as the connection pool. This article focuses on a local Windows 11 development environment and a KingbaseES database on a CentOS 7.6 server, explaining how to understand, configure, and verify the key parameters of HikariCP. The example connection continues to use the kb_app and app_user created in the first article. image.png

@[toc]


1. Why You Can't Just Use Defaults

Many projects only write this when first connecting to a database:

spring:
  datasource:
    url: jdbc:kingbase8://192.168.10.101:54321/kb_app
    username: app_user
    password: App_user_123

This indeed allows the application to start and access interfaces. But the default connection pool parameters may not suit your business:

A connection pool is not better just because it's larger; it must be designed together with the application thread count, the database's maximum connections, and the average business SQL execution time.

2. First, Check How Many Connections the Database Can Handle

Before tuning HikariCP, first check the maximum connection count inside the KingbaseES database:

SHOW max_connections;

image.png

Note: For the session status views used below for observation, please refer to your current KingbaseES version and product manual; if the view names or field names differ, you can first confirm them in ksql using \d, graphical tool metadata, or the administrator's manual before substituting.

Next, check the current connection status:

SELECT state, COUNT(*)
FROM sys_stat_activity
GROUP BY state
ORDER BY COUNT(*) DESC;

image.png

If the view names or fields differ in your environment, the actual version shall prevail. The core idea is to confirm two things:

For example, if the database's maximum connection count is 100, but the same database also serves background tasks, reporting tools, operations tools, and other applications, then a single application cannot monopolize all connections. A relatively safe starting point is to give a single application 10 to 30 connections first, then adjust based on stress test results.

3. HikariCP Core Parameters

A basic configuration example:

spring:
  datasource:
    url: jdbc:kingbase8://192.168.10.101:54321/kb_app
    username: app_user
    password: App_user_123
    hikari:
      pool-name: kb-app-pool
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 3000
      idle-timeout: 600000
      max-lifetime: 1800000
      validation-timeout: 2000
      leak-detection-threshold: 10000

Explanations follow one by one.

1. maximum-pool-size

The maximum connection count determines how many database connections this application can occupy simultaneously at most.

Don't arbitrarily set it to 100; you should consider:

For example, if there are 4 application instances, each configured with maximum-pool-size=50, theoretically they could occupy up to 200 database connections. Many connection exhaustion problems are amplified by configurations like this.

2. minimum-idle

The minimum idle connection count indicates how many idle connections the connection pool tries to retain.

In a development environment, it can be smaller, for example, 2 to 5. In a production environment, it should be determined based on traffic fluctuations. If the business has obvious peak times, retaining a certain number of idle connections can reduce the cost of temporary connection establishment, but don't let idle connections remain excessive for long periods.

3. connection-timeout

The maximum waiting time to acquire a connection from the pool. In the example, it is configured as 3000 milliseconds.

This parameter is not recommended to be too long. If an interface cannot get a connection, it means the system is already congested. Letting a request hang for 30 seconds before failing will only drag down application threads. Generally, you can start from 3 to 5 seconds and then adjust based on business tolerance.

4. idle-timeout

The survival time for idle connections. Idle connections exceeding this time may be reclaimed.

If the business has long low-peak periods, it can be appropriately shortened to reduce idle connection occupation. Don't frequently reclaim and then frequently create, otherwise it will increase the pressure of database connection establishment.

5. max-lifetime

The maximum lifecycle of a connection. After exceeding this time, the connection will be replaced by the pool.

This value should be less than the time at which network devices, databases, or middle layers might actively disconnect. A common starting point is 30 minutes. Don't set it to infinite.

6. leak-detection-threshold

The connection leak detection threshold. If a connection is borrowed and not returned for longer than the specified time, a warning log will be printed.

It is recommended to enable this in development and testing environments, for example, 10 seconds or 30 seconds. Whether to enable it in production requires a comprehensive evaluation of log volume and performance impact. When code has unclosed connection issues, the warning logs from this parameter can directly pinpoint the call stack.

4. How to Estimate the Maximum Connection Count

A simple estimation approach can be used:

Single instance max connections = Target concurrent requests * Database occupation time per request / Total request time

Example:

Then the number of requests simultaneously occupying database connections is approximately:

100 * 40 / 200 = 20

At this point, the single-instance connection pool maximum can be initially set to 20 to 30, then observed through stress testing. This estimation is not an absolute formula, but it is more reliable than directly setting it to 100.

5. Observing Connection Pool Effects on the Database Side

After the application starts, we need to check inside the database to see exactly where these connections are coming from. You can execute the following SQL:

SELECT usename, application_name, client_addr, state, COUNT(*)
FROM sys_stat_activity
GROUP BY usename, application_name, client_addr, state
ORDER BY COUNT(*) DESC;

image.png

Actually, I suggest using the ApplicationName parameter in the JDBC URL to set an identifier for the application. This makes it much easier to see the connection source from the database side:

jdbc:kingbase8://192.168.10.101:54321/kb_app?ApplicationName=kb-app-demo

After you set this, the sys_stat_activity.application_name field will display the corresponding application name. Generally, if there are multiple applications or multiple instances sharing the same database, this method is particularly useful.

So you need to focus on these things:

If the application establishes a large number of connections right after starting, check the minimum-idle parameter. If a large number of requests report connection acquisition timeouts during stress testing, you need to investigate SQL execution time, the connection pool upper limit, and the application's thread count.

6. Connection Pool and Application Thread Pool Must Be Considered Together

When many projects tune the database connection pool, they often only look at the connection pool itself, ignoring the Web container's thread pool. This is a problem.

Why does this happen? Think about it. If Tomcat's maximum thread count is 100, and Hikari's maximum connection count is only 10, then in a situation where a large number of interfaces need to access the database, those 90 threads might have to queue up waiting for connections.

The reverse is also true. If Tomcat's maximum thread count is 100, and Hikari's maximum connection count is also 100, if the database cannot handle so many connections, the database itself will become the bottleneck.

So what is a more robust approach?

7. Recommended Configuration for Development Environment

For a local Windows 11 development environment, the configuration can be conservative:

spring:
  datasource:
    hikari:
      pool-name: kb-dev-pool
      maximum-pool-size: 5
      minimum-idle: 1
      connection-timeout: 3000
      idle-timeout: 300000
      max-lifetime: 1800000
      leak-detection-threshold: 10000

Actually, in a development environment, the focus is really not on throughput. The focus is on discovering connection leaks, incorrect account permissions, and SQL errors as early as possible.

8. Suggestions for Testing and Production Environments

For a testing environment, you can refer to this:

spring:
  datasource:
    hikari:
      pool-name: kb-test-pool
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 3000
      idle-timeout: 600000
      max-lifetime: 1800000
      leak-detection-threshold: 30000

For a production environment, it must be based on stress test results. I do not recommend copying directly. At least you must confirm the following points:

9. Common Configuration Mistakes

1. Thinking a Larger Maximum Connection Count is Always Better

If the connection count is too large, the pressure on database scheduling increases. Very often, reducing slow SQLs is much more effective than increasing the connection count.

2. Setting a Very Long Connection Acquisition Timeout

This will cause user requests to hang continuously and also occupy application threads. When the system is congested, it should actually fail fast and then trigger an alert.

3. Not Enabling Leak Detection in the Development Environment

The earlier a connection leak is discovered, the lower the cost. In a development environment, leak detection should be turned on.

4. Not Aggregating Connection Counts Across Multiple Application Instances

30 connections per instance, 10 instances means 300 connections. When scaling out applications, you must recalculate the database's connection budget.

10. Summary

HikariCP's parameters are not isolated configurations. You must consider them together with the database's maximum connection count, the number of application instances, the Web thread pool, and the average SQL execution time. A robust approach is to start conservatively, then verify with stress testing, observe database sessions, and finally adjust gradually.

In the next article, we will move closer to production issues. When the connection count suddenly spikes and interfaces start to hang, how to investigate from three lines simultaneously: database sessions, the application thread pool, and connection pool logs.