If I'm not wrong, currently there are two ways to have connection pooling in Django: Native Connection Pooling (Django 5.x) Using PGBouncer I want to know that how connection pooling works behind the scene in Django. In FastAPI, there is one "permanent" process that handles all requests. We can have a connection pool using for example asyncpg driver. In its simplest form, it creates like 10 connections to the Postgresql database(using 10 unix socket connections), then when a coroutine request a connection, it gives it from the pool. +-------------------------+ | +------------+ | ---------------> +------------+ | | | | | | | FastAPI | Connection | | ---------------> | Database | | | Pool | | | | | | (asyncpg) | | ---------------> +------------+ | +------------+ | +-------------------------+ But in Django, there is no single permanent process. If we use Gunicorn with sync workers, every worker instantiates a Django application to handle one request at a time. There is no shared memory between them. How can psycopg3 driver creates a connection pool in one worker and all other workers communicate with that? I guess PGBouncer is a separate process that creates connection pool inside its memory, then all Django workers can communicate with that. Django worker ---\ -----\ +------------+ ---------------> +------------+ -----\ | | | | Django worker ------------------> | PBbouncer | ---------------> | Database | -----/ | | | | -----/ +------------+ ---------------> +------------+ Django worker ---/ Am I right to say that the both ways of connection pooling in Django are in-direct and there is an extra latency for the intermediate process? Continue reading...