Postgres connection pool on Kubernetes in 1 minute

TL;DR: How to deploy pgbouncer on Kubernetes to allow use more database connections

PGBouncer on Kubernetes in just one minute!


If you develop apps using frameworks such as Django o RoR, you have probably faced the following problem/error.

FATAL: sorry, too many clients already

As you know, these kind of frameworks uses a database connection pool with the objective of to reduce the database connection latency.

That’s is great always which your database is optimized to have a lot of connections.

As you can infer, it’s not the case of Postgres.

Each Postgres connection uses about 10 MB, altough most of the time they are idle.

With the microservices boom or gRPC streams, things get worse. We have a lot of idle connections but Postgres requests a lot of resources for nothing, to put in a idle state.

PgBouncer to the rescue

There are serveral options to solve the multiple connections problem but all of them use the same pattern: a proxy in the middle.

The idea is that you connect your consumer software to a proxy which allows a lot of “cheap” connections, and this proxy connects with the Postgres database only when your app really need to perform any database action.

One of these solutions is PgBouncer.

It’s the oldest solution and its adopted widely.

Pgbouncer in your K8S cluster

To put pgbouncer in your cluster is easy as pie.

We use the following docker image/project: edoburu/pgbouncer

To use just we need to define a config and a secret K8S resources. We need to provide it the following Postgres database connection:

  • DB_HOST: the K8S service name of your Postgres pod/deployment.
  • DB_USER: the Postgres database user.
  • DB_PASSWORD: the Postgres database user (you should store it as a secret).
  • POOL_MODE: specific pgbouncer parameter. We use “transaction” mode because we only want to connect to Postgres when we really need it.
  • SERVER_RESET_QUERY: before a connection can be reused by other client, it’s important to reset any previous session set. DISCARD ALL if ok for Postgres 8.3+

Taking into account the above, the deployment manifest can be something as below

We can apply it using the standard CLI command (remember to create the config and/or secrets before!)

$ kubectl apply -f pgbouncer-deployment.yaml

Now, you just need to create the service to consume it.

We apply again the service manifest

$ kubectl apply -f pgbouncer-service.yaml

And that’s all!

Now you can use it, just change your DB_HOST environment variable in your app deployment from postgres-service to pgbouncer-service (replace them with your real service names).

If you need to configure other settings such as max connections, logging, etc, check out Github edoburo readme page.

CTO @ & Beyond-Full-stack developer #go #python #kubernetes

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store