Spring Boot + RDS Connection Pooling: HikariCP + RDS Proxy
Fast recall
Quick revision
Core answer
maximum-pool-size ~= (number of CPU cores * 2) per service instance, NOT per pod × replicas × 10. Set connection-timeout: 3000, max-lifetime shorter than RDS wait_timeout (e.g., 1800000ms), and leak-detection-threshold: 60000 in non-prod. For Lambda or high-replica environments where connection count explodes past RDS limits, front RDS with RDS Proxy — it multiplexes connections and handles failover. Monitor: HikariCP metrics, pg_stat_activity, and RDS DatabaseConnections CloudWatch metric.Practical connection-pool tuning and awareness of the Lambda + RDS problem
Setting maximum-pool-size=100 per pod with 20 replicas = 2000 connections, overwhelming RDS's max_connections limit
Discuss connection storm during scaling events, failover behavior with pools, RDS Proxy's pinning quirks, and the right formula for pool sizing (it's smaller than people expect)
Interview-ready guide
Interview answer
Connection pooling looks simple but is one of the most common misconfigurations in production Spring Boot services on RDS. The failures are predictable.
The pool-too-big failure
- maximum-pool-size=100 with 20 pods is 2000 connections
- RDS db.t3.medium allows about 85 total connections
- Pods fail to start with "FATAL: too many connections"
- This is the most common mistake
The right pool size is smaller than you think
- Formula: (CPU cores * 2) + 1 per instance; for modern SSD storage
- Spring Boot default of 10 is usually correct
- Intuition: DB connections work serially on the DB side; more than CPU * 2 just causes contention
- Total demand (pods * pool-size * services sharing DB) must stay under ~80% of RDS max_connections
Key HikariCP settings
- maximum-pool-size: 15 per instance (not 100)
- connection-timeout: 3000 — fail fast on pool exhaustion; default 30s stalls requests
- max-lifetime: 1800000 — recycle connections every 30 minutes; must be less than RDS wait_timeout and less than NAT Gateway idle timeout
- leak-detection-threshold: 60000 — logs stack trace if connection held > 60 seconds; non-prod only
- tcpKeepAlive: true — prevents silent idle kill by middleboxes
RDS Proxy for Lambda and high-replica deployments
- Sits in front of RDS; multiplexes client connections into a smaller set of actual DB connections
- Essential for Lambda + RDS — without it, 1000 concurrent Lambdas open 1000 connections and kill RDS
- Useful for 50+ pods with small RDS — absorbs variance without over-provisioning RDS
- Reduces failover window from minutes to ~30 seconds; detects failed primary faster than client pools
RDS Proxy pinning quirks
- Proxy normally multiplexes but certain session state pins the connection to a single client: transactions, temp tables, advisory locks, some prepared statements
- Heavy pinning negates the multiplexing benefit
- Monitor DatabaseConnectionsCurrentlyBorrowed and DatabaseConnectionsCurrentlyInTransaction CloudWatch metrics
Aurora read/write split
- Aurora has a writer endpoint for writes and a reader endpoint for read replicas
- HikariCP points at one; for split reads, use two DataSources and route via @Transactional(readOnly=true)
- Spring's AbstractRoutingDataSource handles this cleanly
Failover behavior
- RDS Multi-AZ failover: DNS resolves to new primary in ~60 seconds
- Existing HikariCP connections break; HikariCP marks invalid on next use
- Requests fail during the gap unless you retry at the application layer
- RDS Proxy cuts this gap to ~30 seconds
Monitoring
- CloudWatch DatabaseConnections on RDS — should stay under 80% of max_connections
- HikariCP metrics via Micrometer: connections.active, connections.pending, connections.timeout
- pg_stat_activity on Postgres for deep visibility: active queries, idle-in-transaction
- Alerts: pool timeouts > 0, RDS connections > 80% of max, idle-in-transaction count spiking
The strategic answer
- Start with Spring Boot default pool (10); monitor; scale up only if connections.pending > 0 sustainably
- Calculate total demand before scaling out pods; hitting max_connections is catastrophic
- Add RDS Proxy for any Lambda + RDS architecture, and for any service with 50+ replicas
- Configure connection-timeout short so pool exhaustion fails fast instead of stalling
- Always set max-lifetime less than wait_timeout to recycle before DB kills connections
Spring Boot + RDS Connection Pooling: HikariCP + RDS Proxy
Direct Answer
Use HikariCP (Spring Boot default) with sensible sizing: maximum-pool-size ~= (number of CPU cores * 2) per service instance, NOT per pod × replicas × 10. Set connection-timeout: 3000, max-lifetime shorter than RDS wait_timeout (e.g., 1800000ms), and leak-detection-threshold: 60000 in non-prod. For Lambda or high-replica environments where connection count explodes past RDS limits, front RDS with RDS Proxy — it multiplexes connections and handles failover. Monitor: HikariCP metrics, pg_stat_activity, and RDS DatabaseConnections CloudWatch metric.
Common Mistakes & Pitfalls
Setting maximum-pool-size=100 per pod with 20 replicas = 2000 connections, overwhelming RDS's max_connections limit
Check your understanding
Answer these without looking back at the article.
- What is RDS Proxy pinning and how do you detect it?
- How do you implement read/write splitting with Aurora in Spring Boot?
- What is HikariCP's leak-detection-threshold and when should you enable it?
- How does RDS Multi-AZ failover affect existing HikariCP connections?
Related interview prep categories
1Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.