Problem
pog.transaction calls pgo:checkout(Name) with no timeout option, which defaults to pgo_pool's hardcoded ?TIMEOUT of 5000ms:
% pog_ffi.erl line 113
checkout(Name) when is_atom(Name) ->
case pgo:checkout(Name) of %% <-- no timeout passed
Meanwhile, pog.query passes the timeout correctly:
% pog_ffi.erl line 90-94
Options = #{
pool => Name,
pool_options => [{timeout, Timeout}] %% <-- timeout passed
},
pgo:query(Sql, Arguments, Options)
This means queue_target and queue_interval pool config have no effect on transaction checkout. Any serverless database (Neon, Supabase) with >5s cold starts, or cross-region connections with high latency, will hit TransactionQueryError(QueryTimeout) on transactions while regular queries work fine.
Reproduction
// This works — timeout is passed through to pgo:query
pog.query("SELECT 1")
|> pog.timeout(30_000)
|> pog.execute(db)
// This fails with QueryTimeout after exactly 5s — timeout is not configurable
pog.transaction(db, fn(tx) {
// ... any queries ...
})
Suggested fix
Pass a configurable timeout to pgo:checkout/2 in the transaction path:
checkout(Name, Timeout) when is_atom(Name) ->
case pgo:checkout(Name, [{timeout, Timeout}]) of
{ok, Ref, Conn} -> {ok, {Ref, Conn}};
{error, Error} -> {error, convert_error(Error)}
end.
And expose it in the Gleam API, perhaps as a second argument to pog.transaction or via the pool config.
Context
Discovered while deploying a Gleam/wisp app on connecting to a distant PostgreSQL. Regular queries worked, but transactions with multiple round-trips exceeded the 5s hardcoded limit.
Problem
pog.transactioncallspgo:checkout(Name)with no timeout option, which defaults to pgo_pool's hardcoded?TIMEOUTof 5000ms:Meanwhile,
pog.querypasses the timeout correctly:This means
queue_targetandqueue_intervalpool config have no effect on transaction checkout. Any serverless database (Neon, Supabase) with >5s cold starts, or cross-region connections with high latency, will hitTransactionQueryError(QueryTimeout)on transactions while regular queries work fine.Reproduction
Suggested fix
Pass a configurable timeout to
pgo:checkout/2in the transaction path:And expose it in the Gleam API, perhaps as a second argument to
pog.transactionor via the pool config.Context
Discovered while deploying a Gleam/wisp app on connecting to a distant PostgreSQL. Regular queries worked, but transactions with multiple round-trips exceeded the 5s hardcoded limit.