Skip to content

feat: Add automatic retries for transient Postgrest errors#1246

Open
thagikura wants to merge 3 commits intosupabase-community:masterfrom
thagikura:feature/postgrest-retry
Open

feat: Add automatic retries for transient Postgrest errors#1246
thagikura wants to merge 3 commits intosupabase-community:masterfrom
thagikura:feature/postgrest-retry

Conversation

@thagikura
Copy link
Copy Markdown
Contributor

@thagikura thagikura commented Apr 9, 2026

What kind of change does this PR introduce?

Feature

Closes #1243

What is the current behavior?

All Postgrest requests fail immediately on transient errors (HTTP 503/520, network failures) with no retry
mechanism. This is problematic for intermittent infrastructure issues where a retry would succeed.

What is the new behavior?

Idempotent requests (GET, HEAD) are automatically retried with exponential backoff on transient errors:

  • Retries on HTTP 503 (Service Unavailable) and 520 (Unknown Error)
  • Retries on network errors (connection failures, timeouts)
  • Exponential backoff: 1s, 2s, 4s delays (max 30s)
  • Default max 3 retries, configurable via Postgrest.Config.maxRetries
  • Per-query opt-out via noRetry() in the request builder
  • x-retry-count header sent on retried requests
  • Non-idempotent methods (POST, PATCH, DELETE) are never retried
// Retries enabled by default for GET requests
val result = supabase.from("messages").select()

// Disable retries for a specific query
val result = supabase.from("messages").select {
    noRetry()
}

// Configure max retries globally
install(Postgrest) {
    maxRetries = 5  // default is 3
}

Additional context

Matches the retry behavior in supabase-js (PR supabase/supabase-js#2072). The retry logic catches both
RestException (for retryable HTTP status codes) and HttpRequestException (for network errors) since they
represent different failure modes in the supabase-kt HTTP stack.

Idempotent requests (GET, HEAD) that fail with network errors or
HTTP 503/520 are now automatically retried with exponential backoff.

- Default: 3 retries with delays of 1s, 2s, 4s (max 30s)
- Configurable via Postgrest.Config.maxRetries
- Per-query opt-out via noRetry() in the request builder
- x-retry-count header sent on retried requests
- Non-idempotent methods (POST, PATCH, DELETE) are not retried
- Catches RestException for retryable HTTP status codes and
  HttpRequestException for network errors

Closes supabase-community#1243
Comment thread Postgrest/src/commonTest/kotlin/RetryTest.kt Outdated
@thagikura
Copy link
Copy Markdown
Contributor Author

228d293
@jan-tennert thanks. Addressed in the commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

parity(postgrest): add automatic retries for transient errors [from supabase-js]

3 participants