Skip to Content

Pool mode in PgBouncer: session vs transaction (for Odoo)

November 6, 2025 by
Pool mode in PgBouncer: session vs transaction (for Odoo)
John Wolf
| No comments yet

The point that defines whether PgBouncer saves you or breaks you

PgBouncer can be the difference between a stable Odoo and a nightmare of timeouts. But it all starts with a decision that many overlook:

pool_mode defines when PgBouncer returns a real connection to the pool.

If you choose poorly, you not only improve nothing:you can worsen the system.

🧠 What does pool_mode actually do

PgBouncer receives many “client” connections (Odoo) and manages a smaller number of “server” connections (PostgreSQL).

pool_mode defineshow longa real PostgreSQL connection is “reserved” for a client.

  • If you reserve it for too long → you run out of pool.

  • If you release it quickly → you reuse connections and PostgreSQL breathes.

1) pool_mode = session

How it works

Insession, PgBouncer assigns a real connection to a client and keeps itfor the entire session.

In practice:

  • Odoo opens a connection

  • PgBouncer assigns a connection to PostgreSQL

  • that connection remains “occupied” for that client

  • even if the client is idle

Por qué suele fallar en Odoo

Odoo does not behave like an app that opens/closes perfect sessions. In production, it mixes:

  • short requests

  • users who leave tabs open

  • long polling (depending on your stack)

  • crons

  • workers with irregular loads

Typical result with session:

  • the pool “freezes”

  • clients start to wait for a connection

  • they appearintermittent timeouts

  • PostgreSQL may not be at 100%, but Odoo feels dead

Translation:with session, PgBouncer can become a “bottleneck” if your connections are held.

2) pool_mode = transaction (recomendado para Odoo)

How it works

In modetransaction, PgBouncer assigns a real connectiononly while the transaction lasts.

When the transaction ends:

  • the real connection returns to the pool

  • another client immediately reuses it

Por qué encaja con Odoo

Odoo works based on:

  • frequent transactions

  • ORM operations that open/close transactions per request/action

This makes transaction the natural mode for:

  • maximizing reuse

  • maintaining few real connections

  • stabilizing latency

  • avoiding pools hijacked by idle clients

✅ Base recommendation:

pool_mode = transaction

🚨 ¿Hay riesgos usando transaction?

Yes, but they are controllable.

In transaction, there is an important rule:

  • you should not rely on persistent session state in PostgreSQL(certain SET, temporary tables, session-level prepared statements, etc.)

In standard Odoo, it usually works well.

If you have very specific modules or unusual integrations, it is advisable to validate with tests.

🔥 Cómo se ve el fallo en la vida real

When the session is poorly chosen:

  • users report slowness "at times"

  • some screens load, others die

  • restarting Odoo "fixes" it

  • it comes back after a while

Cuando transaction está bien aplicado:

  • the system becomes predictable

  • latency drops in spikes

  • PostgreSQL stops inflating in RAM

  • the "firefighter mode" is reduced

✅ Recomendación práctica (para empezar bien)

If you are implementing PgBouncer for Odoo and want stability:

  1. Use pool_mode = transaction

  2. Adjust pools with real numbers (next chapter)

  3. Monitor with SHOW POOLS; and SHOW STATS;

🔗 Enlaces internos

📌 Conclusión

If you take away only one idea from this chapter:

For Odoo, transaction is almost always the correct mode.

session may seem "safe", but in production is where starvation and timeouts arise.

Pool mode in PgBouncer: session vs transaction (for Odoo)
John Wolf November 6, 2025
Share this post
Archive
Sign in to leave a comment