Skip to Content

Basic PgBouncer configuration optimized for Odoo

November 12, 2025 by
Basic PgBouncer configuration optimized for Odoo
John Wolf
| No comments yet

🎯 Objective of this chapter

By the end of this chapter:

  • PgBouncer will bespecifically configured for Odoo

  • You will avoid typical production errors

  • You will have a stable base for advanced tuning

👉 We are not looking for 'maximum performance' yet.

We are looking forstability + predictability.


🧱 Key principle: PgBouncer is not configured 'generically'.

Most guides fail here.

PgBouncer:

  • is not configured the same wayfor all apps

  • it depends on the connection pattern

  • it depends on transactions

Odoo has a very particular pattern📁 Main file.

📁 Main file

Everything we touch is in:

/etc/pgbouncer/pgbouncer.ini


🗂️ [databases] section

Recommended example:

[databases]
odoo = host=127.0.0.1 port=5432 dbname=odoo


Best practices

  • Useone alias per database

  • Do not use * = in production

  • Keep the dbname explicit


⚙️ [pgbouncer] section – Base configuration

🔌 Ports and listening

listen_addr = 0.0.0.0
listen_port = 6432
  • Use 0.0.0.0 only if Odoo is on another host

  • If everything is on the same server:

    listen_addr = 127.0.0.1


🔐 Authentication (recommended)

auth_type = scram-sha-256
auth_file = /etc/pgbouncer/userlist.txt

👉 SCRAM is more secure and stable than md5.


🔄 Pool mode (CRITICAL)

pool_mode = transaction

Why transaction and not session?

  • Odoo frequently opens transactions.

  • session keeps the connection busy.

  • transaction frees the connection when finished.

❌ session = guaranteed starvation.

✅ transaction = efficient reuse.


📊 Pool sizes (initial safe values)

max_client_conn = 500
default_pool_size = 20
reserve_pool_size = 5

What each one means

  • max_client_conn

    Maximum connectionsfrom Odoo to PgBouncer

  • default_pool_size

    Real connections to PostgreSQL per database

  • reserve_pool_size

    Extra connections for brief spikes

👉 These valuesare not final, they are safe to start.


⏱️ Important timeouts

server_idle_timeout = 60
query_timeout = 0
  • server_idle_timeout:

    • closes idle connections

    • frees resources

  • query_timeout = 0:

    • do not break long Odoo queries.

    • Odoo manages its own timeouts.


🧠 Handling problematic transactions

idle_transaction_timeout = 60

Avoid:

  • hanging transactions.

  • workers blocking pools

🧾 Logging (highly recommended)

log_connections = yes
log_disconnections = yes
log_pooler_errors = yes

In production:

  • helps detect saturation

  • allows real debugging

🧪 Recommended full configuration (base)

[databases]
odoo = host=127.0.0.1 port=5432 dbname=odoo

[pgbouncer]
listen_addr = 127.0.0.1
listen_port = 6432

auth_type = scram-sha-256
auth_file = /etc/pgbouncer/userlist.txt

pool_mode = transaction

max_client_conn = 500
default_pool_size = 20
reserve_pool_size = 5

server_idle_timeout = 60
idle_transaction_timeout = 60
query_timeout = 0

log_connections = yes
log_disconnections = yes
log_pooler_errors = yes



🔁 Apply changes

sudo systemctl reload pgbouncer

(Or use restart if you changed auth or ports)

👀 Check that everything is okay

Connect to PgBouncer:

psql -p 6432 -U odoo pgbouncer

And run:

SHOW POOLS;
SHOW STATS;

What you should see:

  • active pools

  • few real connections

  • clients coming in and out


❌ Common errors at this stage

  • pool_mode = session

  • pools too small

  • aggressive timeouts

  • not looking at metrics

  • copying generic configs from the internet


📌 Conclusion

With this configuration:

  • Odoo stops saturating PostgreSQL

  • PgBouncer acts as a buffer

  • The system becomes stable

👉 It is still not optimal, but it is alreadycorrect.

Next chapter ->

Basic PgBouncer configuration optimized for Odoo
John Wolf November 12, 2025
Share this post
Tags
Archive
Sign in to leave a comment