From M365 MSP to M365 E7 MSP: Your Playbook is Here
June 27, 2026Take control of your PostgreSQL maintenance
June 27, 2026Author: Mohamed Baioumy
Technology: Azure Database for PostgreSQL (Flexible Server & Single Server)
Category: Connectivity | Performance | Application Design
Introduction
Connection pooling is a critical component of application performance when connecting to Azure Database for PostgreSQL. Creating a new PostgreSQL connection is an expensive operation that consumes CPU, memory, and networking resources. Reusing existing connections through a connection pool significantly reduces connection latency, improves throughput, and helps applications scale more efficiently.
Many Java applications use HikariCP, one of the most popular high-performance JDBC connection pools. While HikariCP provides excellent performance out of the box, improperly configured connection pool settings can lead to issues such as:
- Connection pool exhaustion
- Stale or invalid connections
- Increased connection acquisition latency
- Excessive connection creation and destruction
- Database resource contention
- Application timeouts
This article summarizes generic guidance and best practices for configuring HikariCP when working with Azure Database for PostgreSQL Flexible Server and Azure Database for PostgreSQL Single Server.
Understanding Key HikariCP Parameters
1. Maximum Lifetime (maxLifetime)
The maxLifetime property controls how long a connection can remain in the pool before HikariCP retires it and creates a new one.
Why It Matters
Connections can become stale over time due to:
- Network interruptions
- Infrastructure updates
- Connection state changes
- TCP idle behavior
Recycling connections periodically helps prevent applications from using long-lived connections that may no longer be healthy.
Recommended Practice
Avoid configuring the value too low.
When maxLifetime is set aggressively, HikariCP continuously destroys and recreates connections, resulting in:
- Additional authentication overhead
- Increased connection establishment latency
- Higher CPU utilization
- Reduced application throughput
A reasonable starting point is:
spring.datasource.hikari.maxLifetime=1800000
30 minutes (1,800,000 ms) is commonly used and aligns well with many production workloads. Depending on workload characteristics, values between 30 minutes and 1 hour are generally suitable
Avoid
maxLifetime=300000
(5 minutes)
This often causes unnecessary connection churn without providing additional benefits.
2. Minimum Idle Connections (minimumIdle)
The minimumIdle setting defines how many idle connections HikariCP should keep ready for immediate use.
Why It Matters
A pool with available idle connections can serve application requests immediately without waiting for new connections to be established.
However, maintaining too many idle connections consumes unnecessary database resources.
Recommended Practice
For most workloads:
minimumIdle = maximumPoolSize
Or
minimumIdle slightly lower than maximumPoolSize
This ensures sufficient connections are already available during traffic spikes while avoiding excessive connection creation delays.
Example
maximumPoolSize=20
minimumIdle=15
Avoid
maximumPoolSize=20
minimumIdle=20
only when the application experiences long periods of inactivity and conserving resources is more important than immediate responsiveness.
3. Idle Timeout (idleTimeout)
The idleTimeout property determines how long an unused connection remains in the pool before being removed.
Why It Matters
Connections that sit idle for extended periods consume resources on both:
- The application server
- Azure Database for PostgreSQL
However, removing idle connections too quickly causes the application to repeatedly establish new connections.
Recommended Practice
Keep the default value unless there is a specific requirement.
spring.datasource.hikari.idleTimeout=600000
which equals:
10 minutes (600,000 ms)
This setting provides a good balance between resource utilization and responsiveness. [Re: EXT: R…0040002947 | Outlook]
The timeout should also be comfortably longer than any expected short application idle periods.
Avoid
idleTimeout=10000
(10 seconds)
Such aggressive settings often result in unnecessary connection creation cycles.
4. Maximum Pool Size (maximumPoolSize)
This parameter determines the maximum number of concurrent database connections the application can maintain.
Why It Matters
This is often the most important HikariCP setting.
If the Pool Is Too Small
Applications may experience:
Connection is not available, request timed out
because all available connections are already in use. Similar scenarios have been observed during customer investigations involving Hikari pool exhaustion.
If the Pool Is Too Large
Applications can overwhelm the database server with excessive concurrent sessions, resulting in:
- Connection contention
- Increased context switching
- Higher memory consumption
- Reduced overall performance
Recommended Practice
Pool size should be based on:
- Database compute configuration
- CPU core count
- Query execution duration
- Application concurrency requirements
- Workload characteristics
There is no universal value that fits every workload.
Start conservatively:
maximumPoolSize=10
or
maximumPoolSize=20
maximumPoolSize=20
and increase only after load testing demonstrates a need for additional concurrency.
Fixed-Size Pool Recommendation
For many production workloads, a fixed-size pool provides the simplest and most predictable behavior.
Configure:
maximumPoolSize=20
minimumIdle=20
or omit minimumIdle entirely so it defaults to maximumPoolSize. HikariCP commonly recommends maintaining a fixed-size pool for responsiveness during demand spikes.
Benefits
- Faster connection acquisition
- Predictable performance
- Reduced connection creation latency
- Better handling of traffic spikes
When using a small fixed-size pool, there is often little need to aggressively tune:
- minimumIdle
- idleTimeout
Instead, simply recycle connections using:
maxLifetime
maxLifetime
Additional Recommendations
Enable TCP Keepalive
One common cause of stale connections is network devices silently dropping inactive TCP sessions.
For PostgreSQL applications, consider enabling TCP keepalive:
tcpKeepAlive=true
tcpKeepAlive=true
The HikariCP project specifically recommends enabling TCP keepalive to prevent rare situations where pools can lose valid connections.
Monitor Connection Usage
Track:
- Active connections
- Idle connections
- Connection acquisition time
- Pool exhaustion events
- Database connection counts
These metrics help identify whether pool sizing is appropriate.
Investigate Long-Running Queries
Connection pool problems are often symptoms rather than root causes.
A frequent scenario is:
- A query becomes slow.
- Connections remain occupied longer.
- The pool becomes exhausted.
- Applications start timing out.
When analyzing HikariCP issues, always review:
- Query performance
- Blocking situations
- Database resource utilization
- Application connection handling logic
Sample Production Configuration
spring.datasource.hikari.maximumPoolSize=20
spring.datasource.hikari.minimumIdle=15
spring.datasource.hikari.maxLifetime=1800000
spring.datasource.hikari.idleTimeout=600000
spring.datasource.hikari.connectionTimeout=30000
spring.datasource.hikari.keepaliveTime=60000
spring.datasource.hikari.maximumPoolSize=20
spring.datasource.hikari.minimumIdle=15
spring.datasource.hikari.maxLifetime=1800000
spring.datasource.hikari.idleTimeout=600000
spring.datasource.hikari.connectionTimeout=30000
spring.datasource.hikari.keepaliveTime=60000
This configuration provides a solid starting point for many Azure Database for PostgreSQL workloads and can be adjusted based on application-specific requirements.
a { text-decoration: none; color: #464feb; } tr th, tr td { border: 1px solid #e6e6e6; } tr th { background-color: #f5f5f5; }
Conclusion
HikariCP is extremely efficient when configured appropriately. The goal is not to maximize the number of connections, but rather to maintain a healthy balance between application responsiveness and database resource consumption.
As a general rule:
- Use a reasonable maxLifetime (30–60 minutes)
- Keep enough idle connections available for traffic spikes
- Avoid aggressive idleTimeout values
- Size the pool based on workload characteristics, not guesses
- Consider fixed-size pools for predictable performance
- Monitor connection usage and query performance regularly
By following these practices, applications connecting to Azure Database for PostgreSQL can achieve improved scalability, lower latency, and more reliable connectivity.
References
Connection pooling best practices – Azure Database for PostgreSQL
Performance best practices for using Azure Database for PostgreSQL – Connection Pooling