AI & Agent Dev Bug Sandbox logo
AI & Agent Dev Bug Sandbox
Back to Radar

Hosted Supavisor Transaction Pooler Drops Pipelined Replies Causing Postgres.Js Client To Hang Indefinitely

The hosted Supabase transaction pooler (port 6543) reproduces dropped pipelined PostgreSQL replies when a postgres.js client with prepare:false and max_pipeline:1 sends concurrent unprepared queries. One ParseComplete/ParameterDescription reply is lost and the client promise never resolves, matching Supavisor issues #1061 and fixes #1079/#1176. The deployed pooler version may not include those fixes.

highConfidence 85%Supavisor

Origin Analysis

Supavisor releases the backend connection after receiving an earlier ReadyForQuery while replies from a later pipelined extended-query batch are still outstanding. This mismanagement of pipeline state causes dropped protocol frames when multiple Parse/Describe/Sync sequences are sent before the prior batch completes.
1. Use a hosted Supabase transaction-pooler connection string on port 6543. 2. Create a postgres.js client: `const sql = postgres(process.env.DATABASE_URL, { max: 1, prepare: false, ssl: 'require', max_pipeline: 1 })` 3. Run six distinct unprepared read-only SELECT queries concurrently with `Promise.all([read1(sql), read2(sql), read3(sql), read4(sql), read5(sql), read6(sql)])`. 4. Capture frontend Parse/Describe/Sync and backend ParseComplete/ParameterDescription/ReadyForQuery messages. 5. Observe that 11 Parse/Describe sequences are sent but only 10 ParseComplete/ParameterDescription replies return, leaving one client promise permanently unresolved.

Fixing Code Block

Edge Case Audit

If the client-side workaround (max_pipeline:0 plus a small ordering patch for sql.begin) is used, it disables pipelining and can reduce query throughput; additionally, the sql.begin reservation hook may not run correctly without that patch. Server-side upgrade to a fixed Supavisor version should be rolled out gradually with canary tenants, monitoring for protocol counter balance, and a rollback plan to the previous pooler version. Concurrency/multi-tenant shared instances may behave differently; ensure the patch does not retain backends for too long, which could exhaust the pool under high load.

Ecosystem Topology