codeflash-internal/django
Kevin Turcios add5f4a76a
feat: migrate from psycopg2 to psycopg3 with connection pooling (#2489)
## Summary
- Replaces `psycopg2-binary` with `psycopg[binary,pool]>=3.1.8,<4` for
native async connection pooling
- Sets `conn_max_age=0` (persistent connections don't work correctly
under ASGI) and configures psycopg3's `ConnectionPool` with `min_size=2,
max_size=10`
- Changes `log_features` to use `@sync_to_async(thread_sensitive=False)`
so concurrent calls dispatch to different threads, each getting a
separate connection from the pool

## Why
With psycopg2, all `sync_to_async` calls from the same coroutine shared
a single thread and Postgres connection. Parallel DB calls via
`TaskGroup` were serialized at the connection level — zero improvement.
Benchmarks confirmed that with psycopg3's pool, 5 parallel calls now get
5 different threads and 5 different `pg_backend_pid`s. Parallel
`aexists` operations showed **15.6% improvement** (208ms → 175ms).

## Test plan
- [x] 538 tests pass, 0 failures, 12 skipped (pre-existing)
- [x] Ruff lint clean
- [x] Benchmark confirms multiple connections: 5 unique threads, 5
unique pg_pids
- [ ] Verify in staging that connection pool behaves correctly under
sustained load
2026-03-27 05:33:33 -05:00
..
aiservice feat: migrate from psycopg2 to psycopg3 with connection pooling (#2489) 2026-03-27 05:33:33 -05:00
.dockerignore local setup (#1898) 2025-11-17 12:35:09 -08:00