Cloudflare Workers and Supabase
Too many subrequests by single Worker invocation.
"Too many subrequests by single Worker invocation." means one request to your Cloudflare Worker made more outgoing requests than its limit allows, and every supabase-js call is one fetch to your Supabase project. Workers Free allows 50 subrequests per request and Workers Paid 10,000 by default, which you can raise up to 10 million with limits.subrequests in your Wrangler config. A loop that runs one query per item, such as one .select() per user, reaches 50 fast. Replace the loop with one query: .in() for a list of IDs, a foreign-table embed, or a Postgres function called with .rpc(). supabase-js does not throw here: it returns the message in error.message as "Error: Too many subrequests by single Worker invocation. To configure this limit, refer to https://developers.cloudflare.com/workers/wrangler/configuration/#limits". Checked against Cloudflare's limits docs on 2026-10-27.
Use this from your agent
- Claude Code: 4 read-only tools; cannot see your repo.
claude mcp add --transport http viberaven https://viberaven.dev/mcp - Codex: same server, in ~/.codex/config.toml.
[mcp_servers.viberaven] url = "https://viberaven.dev/mcp" - In your repo: writes Vercel + Supabase check rules for your agent (what it writes).
npx -y viberaven init
Connecting to Postgres directly from serverless functions instead? See why serverless apps use a connection pooler.
What counts as a subrequest
Cloudflare counts every fetch() a Worker makes and every call to Cloudflare services such as R2, KV and D1, and each hop of a redirect chain counts too. With supabase-js that means each .from() query, each .rpc(), each supabase.auth call such as getUser(), and each storage call. Workers Free also allows 1,000 subrequests to Cloudflare's internal services; Supabase is not one of them.
Replace the loop with one query
One query per item turns a page of 60 items into 60 subrequests. Ask for all of them at once:
// 1 subrequest per user: 60 users, 60 subrequests
for (const id of userIds) {
const { data } = await supabase.from('profiles').select('*').eq('id', id).single()
}
// 1 subrequest in all
const { data, error } = await supabase.from('profiles').select('*').in('id', userIds)
// related rows in the same request, through a foreign key
const { data: posts } = await supabase.from('posts').select('id, title, profiles(username)')Raise the limit on Workers Paid
Cloudflare's Wrangler docs list limits.subrequests: 50 is the most on a free account, and paid accounts default to 10,000 and can go up to 10,000,000. Raise it only after the loop is gone, since each subrequest still adds a round trip to Supabase.
// wrangler.jsonc
{
"limits": {
"subrequests": 20000
}
}Error: Too many subrequests.
Reports from 2024 and early 2025, including a Supabase discussion about the error appearing in production and not locally, show the shorter message "Error: Too many subrequests.". Reports from September and October 2026 show the longer message with the link to the limits configuration. Both mean the same limit.
Checklist
How to fix it, then check the fix
- 01Find the route that fails and count the Supabase calls one request makes, loops included.
- 02Replace per-item queries with .in(), an embedded select or one .rpc() call.
- 03Check error on every supabase-js result: this error comes back in error.message, not as a thrown exception.
- 04On Workers Paid, set limits.subrequests in your Wrangler config if the route really needs more.
- 05Deploy and call the route with the largest real input, then confirm in the Worker logs that it finished without the error.
Related
Related guides
Sources
Official docs behind this checklist
- Cloudflare, Workers limits (subrequests)
- Cloudflare, Wrangler configuration (limits)
- Supabase, Querying joins and nested tables
- Supabase, JavaScript reference: in()
- supabase-js source, PostgrestBuilder.ts (fetch errors returned in error.message)
- Supabase discussion 32906, Too many subrequests in production
- GitHub issue with the 2026 message
Browse all launch guides · Read resources · How to make and check your next change
FAQ
FAQ for builders before launch
Is the limit per Worker or per request?
Per invocation: Cloudflare's limits page counts subrequests for each request the Worker handles, so the count starts again with the next request.
Why did it work in development?
A Supabase discussion reports the error only in production. Test the route on a deployed Worker with production sized data before launch.