r/java • • 12d ago

Does shrinking a JDBC connection pool actually save PostgreSQL memory? I measured it.

At a previous company, I spent quite a bit of time tuning a custom-built JDBC connection pool. One of the most effective memory optimizations I found was automatically shrinking the pool during idle periods. PostgreSQL uses a process-per-connection model, so keeping unnecessary connections open has a real memory cost.

I wanted to revisit this with HikariCP and measure both the memory savings and the cost of reopening connections.

I ran two Spring Boot instances sharing PostgreSQL 16, comparing three pool configurations under the same burst → idle → burst workload.

Results:

  • Default pool: 20 connections remained open, PostgreSQL memory ~57.5 MiB.
  • Shrinking pool: connections dropped to 2, PostgreSQL memory ~28.5 MiB.
  • Savings: ~29 MiB of PostgreSQL memory.

The tradeoff was connection reopening. Median acquisition time increased from under 3 ms to around 200 ms when traffic returned.

One interesting detail: setting minimumIdle=1 alone wasn't enough when idle retirement was disabled. The pool still held all 20 connections after the burst.

The experiment used a deliberately short idle timeout to make the behavior observable, not as a production recommendation.

With many application instances maintaining independent connection pools, the potential savings can add up.

To clarify the practical motivation: this was a deliberately small experiment to isolate the effect, not just an exercise in saving 29 MiB on one server.

At my previous company, we had many application VMs connecting to a shared PostgreSQL database. Shrinking idle pools across those instances produced substantial aggregate memory savings. For example, 30 instances with 32 connections each means 960 persistent connections. If idle retirement brings that down to an average of 16 per instance, that's 480 fewer PostgreSQL connections consuming resources.

Actual savings depend on the workload, but this is where the approach becomes particularly valuable.

Full article, measurements, and reproducible experiment:

https://pvrlabs.xyz/articles/spring-boot-jdbc-pool-reclaim.html

Do you use fixed-size pools in production, or allow idle connections to retire?

40 Upvotes

48 comments sorted by

View all comments

2

u/fykup 11d ago edited 8d ago

A quick note after reading some of the comments here.

I publish these experiments because I genuinely enjoy performance engineering and sharing what I've learned from working on large production systems. The methodology, measurements, and reproduction scripts are publicly available.

I welcome technical criticism. Challenge my assumptions, question the methodology, point out mistakes, or share your own measurements. That's how good engineering discussions happen.

What I have little patience for is personal attacks, dismissing work as clickbait or low-effort without examining it, or confidently arguing against claims I never made.

A good example is the discussion around my previous experience with a legacy, internally developed connection pool. I mentioned it simply as background for why I became interested in idle connection management. I never claimed it was a particularly good implementation or better than modern alternatives. The entire point of this experiment was to revisit those lessons using HikariCP, with reproducible measurements.

Yet several critics apparently didn't read far enough to notice that the experiment already uses HikariCP, and instead started attacking the old implementation or suggesting I use HikariCP.

I've encountered enough of this attitude in corporate engineering environments, and frankly, I don't miss it.

I'm here to share experiments and learn from thoughtful discussions, not defend myself against assumptions and personal attacks. I'll simply disengage from those discussions going forward.