Skip to content

add: per request statement timeout using prefer header#4584

Draft
taimoorzaeem wants to merge 1 commit intoPostgREST:mainfrom
taimoorzaeem:add/per-request-timeout
Draft

add: per request statement timeout using prefer header#4584
taimoorzaeem wants to merge 1 commit intoPostgREST:mainfrom
taimoorzaeem:add/per-request-timeout

Conversation

@taimoorzaeem
Copy link
Member

@taimoorzaeem taimoorzaeem commented Dec 29, 2025

Adds a feature to set statement_timeout using Prefer: timeout header. This also introduces a PGRST129 error which is returned when the timeout preferred exceeds the per-role timeout, which prevents misuse of this feature.

Closes #4381.

  • Implementation
  • Tests
  • Docs

@taimoorzaeem taimoorzaeem force-pushed the add/per-request-timeout branch from d074eb9 to 2c5589f Compare December 29, 2025 16:37
@taimoorzaeem taimoorzaeem marked this pull request as draft December 29, 2025 16:40
@taimoorzaeem taimoorzaeem force-pushed the add/per-request-timeout branch 3 times, most recently from 5f1d601 to 6963e9a Compare January 1, 2026 07:48
@taimoorzaeem taimoorzaeem changed the title [WIP] add: per request statement timeout using prefer header add: per request statement timeout using prefer header Jan 1, 2026
@taimoorzaeem taimoorzaeem marked this pull request as ready for review January 1, 2026 07:48
@steve-chavez
Copy link
Member

We should also fail in case a value exceeds the per role timeout. Otherwise it's abusable.

This failure should happen at the plan level, before hitting the db. I think it will need a new error code.

@taimoorzaeem taimoorzaeem marked this pull request as draft January 2, 2026 08:23
@taimoorzaeem taimoorzaeem force-pushed the add/per-request-timeout branch 5 times, most recently from a82c07f to 0d6370e Compare January 7, 2026 07:13
@taimoorzaeem taimoorzaeem marked this pull request as ready for review January 7, 2026 07:15
@taimoorzaeem taimoorzaeem added the enhancement a feature, ready for implementation label Jan 7, 2026
@taimoorzaeem taimoorzaeem marked this pull request as draft January 12, 2026 07:27
@taimoorzaeem taimoorzaeem force-pushed the add/per-request-timeout branch from 0d6370e to 6481e8e Compare January 13, 2026 05:40
@taimoorzaeem taimoorzaeem marked this pull request as ready for review January 13, 2026 05:41
@taimoorzaeem taimoorzaeem force-pushed the add/per-request-timeout branch from 6481e8e to a37d497 Compare January 15, 2026 14:56
@taimoorzaeem taimoorzaeem force-pushed the add/per-request-timeout branch 2 times, most recently from 1998a61 to cef3feb Compare January 25, 2026 07:09
@taimoorzaeem taimoorzaeem force-pushed the add/per-request-timeout branch 2 times, most recently from cd53ca3 to 356cecf Compare January 28, 2026 07:32
@taimoorzaeem taimoorzaeem marked this pull request as draft January 29, 2026 12:03
@taimoorzaeem taimoorzaeem force-pushed the add/per-request-timeout branch from 356cecf to a1f19e7 Compare February 3, 2026 11:30
@taimoorzaeem taimoorzaeem marked this pull request as draft February 7, 2026 09:34
@taimoorzaeem taimoorzaeem force-pushed the add/per-request-timeout branch 4 times, most recently from 001ee79 to e77acb3 Compare February 11, 2026 14:32
@taimoorzaeem taimoorzaeem force-pushed the add/per-request-timeout branch 2 times, most recently from e52e45f to 77602ac Compare February 14, 2026 06:25
@taimoorzaeem taimoorzaeem marked this pull request as ready for review February 14, 2026 06:27
@taimoorzaeem taimoorzaeem force-pushed the add/per-request-timeout branch 2 times, most recently from 4a92e87 to c8f4f27 Compare February 17, 2026 05:35
@taimoorzaeem taimoorzaeem marked this pull request as draft February 17, 2026 05:40
Adds a feature to set `statement_timeout` using `Prefer: timeout`
header. This also introduces a `PGRST129` error which is returned
when the timeout preferred exceeds the per-role or global timeout.

Signed-off-by: Taimoor Zaeem <taimoorzaeem@gmail.com>
@taimoorzaeem taimoorzaeem force-pushed the add/per-request-timeout branch from c8f4f27 to 7c49b66 Compare February 18, 2026 14:48
@taimoorzaeem taimoorzaeem marked this pull request as ready for review February 18, 2026 14:49
failPreferTimeout Preferences{preferTimeout=(Just (PreferTimeout t)), preferHandling=Just Strict} AppConfig{..} AuthResult{..} =
case roleTimeout of
Nothing -> Right ()
Just rt -> when (t > rt) $ Left $ ApiRequestError $ TimeoutConstraintError rt
Copy link
Collaborator

@mkleczek mkleczek Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check is problematic because it undermines the whole idea of this header.

Who would want to set the timeout header to a value less than the role setting? What for?

The only realistic use case is that a client might want to increase statement_timeout for a particular query.

So sensible limit is greater than the role setting. Don't know: maybe 2x role setting should be the limit? But then - why not simply set the role setting to a greater value?

Thinking about it: it looks like having any limit is contradictory to the idea of this header. OTOH not having a limit is a security vulnerability. No good choice here, I'm afraid.

@taimoorzaeem @steve-chavez WDYT?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check is problematic because it undermines the whole idea of this header.
Thinking about it: it looks like having any limit is contradictory to the idea of this header. OTOH not having a limit is a security vulnerability. No good choice here, I'm afraid.

I think you're right. My idea with the limit was to make the header safe to expose to untrusted clients but that makes it less useful. Also, it might never be totally safe because setting a 1s timeout could force some queries to fail and flood logs on the server.

So this header should fall in the same category as prefer:tx and Accept: application/vnd.pgrst.plan, it can only be exposed to trusted users.

This means it should be gated by a config and that we should remove the statement_timeout limit.

Thoughts?


To expose this header to an untrusted network, a similar thing to https://docs.postgrest.org/en/latest/references/observability.html#securing-the-execution-plan could be used.

@taimoorzaeem taimoorzaeem marked this pull request as draft February 20, 2026 06:02
@taimoorzaeem taimoorzaeem removed the enhancement a feature, ready for implementation label Mar 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Per-request timeout

4 participants