Query completes on Azure PostgreSQL but client keeps running (state = idle in transaction / ClientRead)
Environment
- Service: Azure Database for PostgreSQL – Flexible Server (General Purpose, D2ds_v5, 2 vCores, 8 GiB RAM, 1024 GiB storage)
- Client OS: Windows 11 / WSL 2
- PostgreSQL version: 15.12
Problem
I connect from PyCharm and run fairly simple DDL / DML statements against a large table (~28 GB). While the query is active:
- Portal metrics show CPU at 70–80 %.
After < 10 minutes the CPU drops to ~2 %, suggesting the server has finished its part.
In pg_stat_activity
the backend transitions from active
➝ idle in transaction
with wait_event = ClientRead
, then either sits there for a long time or disappears altogether.
- Meanwhile the Python process never returns (no error, just hangs); I eventually have to stop it manually.
- I reproduced the exact same pattern in DataGrip: the query hangs indefinitely, yet once CPU falls to ~2 % the new table already shows up in the schema browser, confirming the server work is done.
What I’ve ruled out
No blocking locks (pg_locks
, pg_blocking_pids()
are empty).
Nothing new appears in pg_stat_statements
or any pg_stat_progress_*
view.
The same query completes instantly on a smaller subset of the table (~17 GB).
- The table has been vacuumed and analyzed (
VACUUM ANALYZE
).
Questions
- Why does the server report the session as idle / finished while the client still thinks it is fetching data?
- Could result-set size, TCP keep-alive settings, or Azure gateway time-outs be responsible?
- Which PostgreSQL or Flexible Server parameters might explain this behaviour?
Any insights or similar experiences would be greatly appreciated—especially ways to detect sooner that the backend has already sent all rows.