Comment by aobdev
12 hours ago
Every single connection to Postgres is a new process, which requires a fork and new memory allocation (at least 10MB plus whatever you need for your query).
PgBouncer opens a pool of connections and then reuses them each time a client asks for a connection. This reduces latency (no more fork) and overhead (reuse memory).
If it's designed well, your application also opens a pool of connections and re-uses them each time the code needs a DB connection.
The issue is language ecosystems that don't use client side connection pooling because they're single threaded (node, Python). So scaling up the number of web server threads means scaling the number of Postgres processes, which are expensive.
Python has threads and connection pools work fine on async workers as well.
This solves the latency but not the overhead--you'll end up with a full pool of connections for each running instance of your application.
How many running instances do you need though? e.g. Scala web frameworks should be able to do thousands of RPS on a single core without the application developer really trying to optimize anything, and I always hear that even Ruby, Python, etc. are also fast enough to be IO bound so you should just need 2 copies for redundancy, right? Then give each like 8-16 connections.
If I'm implementing my own connection pool, I'll certainly make the number of connections configurable.
1 reply →