All posts
No-Code & Tools

Supabase Edge Function 504? Fix Timeouts Without Just Increasing Retries

A practical way to find why a Supabase Edge Function times out and decide whether to optimise the request or move the work out of the request path.

Elvis Onunwa16 September 20266 min readLast updated: 16 September 2026
Supabase Edge Function 504? Fix Timeouts Without Just Increasing Retries

TL;DR

  • A Supabase Edge Function 504 means the function did not begin a response within the request idle window; more retries can multiply the underlying work.
  • Measure where time is spent before changing architecture: boot, database, external API, computation or serial loops.
  • Keep short request-response work synchronous; move genuinely long or batch work into a job/queue pattern with explicit status and idempotency.
  • Test failure and retry behaviour before calling the fix production-ready.
On this page⌄

A Supabase Edge Function that returns 504 Gateway Timeout is not automatically a sign that Supabase is too slow or that you need a bigger plan.

It means you need to find which part of the request consumed the time.

Supabase’s current Edge Function limits say a function must begin a response within a 150-second request idle timeout. Its troubleshooting documentation points to common causes including slow external APIs, inefficient database queries, large dependencies, CPU-heavy work and cold starts.

The useful debugging question is therefore not “how do I make the timeout longer?” It is:

Should this work finish inside one HTTP request at all?

That distinction matters especially in AI-built products. It is easy to ask an agent to “fix the timeout” and end up with more retries, longer polling or duplicated operations while the underlying architecture stays wrong.

First map the request path

Write the operation as a chain:

client → Edge Function → authentication → database reads → external services → database writes → response

Then add timing around each boundary.

If the request spends 120 seconds waiting for an external API, rewriting your SQL will not solve the real problem. If 100 records are processed one after another, changing the frontend spinner will not solve it either.

Supabase recommends checking Function logs and boot events first, then looking for slow dependencies, API calls, computation and queries. See the current Edge Function timeout troubleshooting guide.

Know which limit you are actually hitting

The hosted platform currently documents several different limits, including a 150-second request idle timeout, a worker wall-clock lifetime and a CPU-time limit. They describe different things.

The 504 troubleshooting page is particularly important: an internal 504 means the function failed to initiate a response within the 150-second request window. Supabase says this request idle limit cannot currently be increased.

See Supabase Edge Function limits and its 504 troubleshooting documentation.

Do not design around a number copied from an old tutorial. Platform limits change.

Check for serial work before changing architecture

A common pattern looks harmless:

  1. fetch 100 records;
  2. loop through them;
  3. call another service for record one;
  4. wait;
  5. write its result;
  6. repeat 99 more times;
  7. return only when everything is finished.

That turns small pieces of latency into one long request.

Before moving everything to a queue, check whether independent I/O can safely run concurrently, whether one database operation can replace dozens of round trips, whether you are selecting more data than needed, and whether the external service supports batching.

But concurrency is not a magic fix either. Sending 100 requests at once can hit rate limits or create a different failure mode.

Separate user response time from job completion time

Some operations simply should not keep the browser waiting.

Imports, report generation, bulk notifications, large media processing and multi-step AI jobs are examples where a better flow may be:

request accepted → job created → quick response with job ID → worker processes job → status stored → client checks/subscribes → result becomes available

Now the product has two explicit states: the request was accepted and the work completed.

That is much easier to reason about than a spinner attached to a request that may time out while downstream work is still happening.

Supabase supports background tasks for work that can continue after a response, but those tasks still live within the platform’s worker limits. For jobs that can exceed those limits or require robust retry/rate-control behaviour, design a proper durable job boundary rather than assuming background execution makes a task unlimited.

Do not add retries until the operation is idempotent

This is the production trap I care about most.

Imagine the function:

  • creates a payment record;
  • sends an email;
  • updates an entitlement;
  • then times out before the client sees success.

The user presses Retry.

If the operation has no idempotency protection, you can now have two emails, duplicate rows or repeated external side effects.

A timeout is therefore not just a performance problem. It can become a state-integrity problem.

Before enabling automatic retries, decide what uniquely identifies the operation, what “already completed” means, which steps are safe to repeat, and how partial failure is recorded.

That same principle appears in payment systems, imports, booking flows and webhook processing: retries should converge on the correct state rather than duplicate it.

When the database is the bottleneck

Do not fetch an entire table into an Edge Function merely to perform work PostgreSQL can express directly.

Supabase’s troubleshooting guidance recommends selecting only required columns and limiting results instead of broad select('*') queries on large tables.

For multi-row state changes, consider whether a database function or transaction can perform the operation closer to the data and atomically. Keep privileged operations server-side and preserve your RLS/auth model rather than bypassing security to gain speed.

If the problem is actually an RLS policy loop rather than latency, use my Supabase RLS infinite recursion guide. If the function returns 401 before your code behaves as expected, use the Edge Function 401 guide.

A practical timeout debugging sequence

Before changing the architecture, capture one failing request and answer these questions:

Question What it tells you
Did the function boot normally? Whether startup/dependencies deserve attention.
How long did each database call take? Whether query shape or round trips dominate.
How long did each external API call take? Whether the bottleneck is outside Supabase.
Is work performed serially in a loop? Whether latency is being multiplied.
Did any side effect complete before timeout? Whether retries can corrupt state.
Does the job genuinely need more than one request window? Whether it belongs behind a job boundary.

Only then choose between optimisation and redesign.

For AI-built apps, ask the agent for evidence

Do not prompt:

Fix my Supabase timeout.

Give the agent the failing invocation timestamp, status code, function logs, timing around major calls, approximate input size, external services involved and whether retries have already caused duplicate work.

Then ask it to identify the first boundary that consumes unexpected time and propose the smallest safe change.

That is the same production discipline behind my AI-built app production checklist: AI can generate the code quickly, but somebody still has to reason about failure states, retries and ownership of state.

If an AI-built MVP has reached the point where auth, Edge Functions, payments and background jobs interact in ways that are hard to reason about, my MVP development service focuses on that production layer. You can also contact me for an audit before rebuilding the whole product.

Sources

Frequently asked questions

Questions, answered.

Why does my Supabase Edge Function return 504?

Supabase currently returns 504 when an Edge Function does not initiate a response within the 150-second request idle timeout. Slow external APIs, inefficient database queries, large dependencies, CPU-heavy work and serial batch operations can all contribute.

Can I increase the Supabase Edge Function timeout?

The current 150-second request idle timeout cannot be increased. If the work genuinely needs longer, redesign the request so it acknowledges quickly and processes the long job separately.

Should I just retry a timed-out function?

Not until the operation is safe to repeat. A client timeout does not prove that every downstream side effect stopped, so blind retries can duplicate emails, payments, records or other work.

NEED HELP WITH THE BUILD?

Turn what you learned here into a clearer website or MVP.

Share the goal, current stage, and constraints. I’ll help you identify the smallest responsible next step.

Continue reading

Related notes.