Implement Supabase rate limiting, backoff, and idempotency patterns.
Use when handling rate limit errors, implementing retry logic,
or optimizing API request throughput for Supabase.
Trigger with phrases like "supabase rate limit", "supabase throttling",
"supabase 429", "supabase retry", "supabase backoff".
Supabase enforces rate limits and quotas across every API surface — PostgREST, Auth, Storage, Realtime, and Edge Functions. Limits scale by plan tier. This skill covers the exact numbers per tier, connection pooling via Supavisor, retry/backoff patterns, pagination to reduce payload, and dashboard monitoring so you can stay within quotas and handle 429 errors gracefully.
Prerequisites
Active Supabase project (any tier)
@supabase/supabase-js v2+ installed
Project URL and anon/service-role key available
Node.js 18+ or equivalent runtime
Instructions
Step 1 — Understand Rate Limits by Tier and Surface
Every Supabase project has per-surface limits that differ by plan. Know these numbers before you architect:
API Request Limits
Metric
Free
Pro
Enterprise
Requests per minute (RPM)
500
5,000
Unlimited (custom)
Requests per day (RPD)
50,000
1,000,000
Unlimited (custom)
Auth Rate Limits
Endpoint
Free
Pro
Signup
30/hour per IP
Higher (configurable)
Sign-in (password)
30/hour per IP
Higher (configurable)
Magic link / OTP
4/hour per user
Configurable
Token refresh
360/hour
360/hour
Auth limits are per-IP and per-user. Configure custom limits in Dashboard > Authentication > Rate Limits.
Storage Bandwidth
Metric
Free
Pro
Storage size
1 GB
100 GB
Bandwidth
2 GB/month
250 GB/month
Max file size
50 MB
5 GB
Upload rate
Shared with API RPM
Shared with API RPM
Realtime Connections
Metric
Free
Pro
Concurrent connections
200
500
Messages per second
100
500
Channel joins
Shared with connection limit
Shared
Edge Functions
Metric
Free
Pro
Invocations/month
500,000
2,000,000
Execution time
150s wall / 50ms CPU
150s wall / 2s CPU
Memory
256 MB
256 MB
Database Connections
Mode
Free
Pro
Direct connections
60
100+
Pooled connections (Supavisor)
200
1,500+
Step 2 — Configure Connection Pooling with Supavisor
Supavisor is Supabase's built-in connection pooler (replaced PgBouncer). It supports two modes:
Transaction mode (port 6543) — recommended for serverless:
import { createClient } from '@supabase/supabase-js'
// Transaction mode: connections returned to pool after each transaction
// Best for: serverless functions, Edge Functions, high-concurrency apps
const supabase = createClient(
'https://your-project.supabase.co',
process.env.SUPABASE_ANON_KEY!,
{
db: {
// Use the pooler connection string with port 6543
// Format: postgresql://postgres.[ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres
}
}
)
// For direct Postgres connections (e.g., Prisma, Drizzle), add pgbouncer=true
// Connection string: postgresql://[email protected]:6543/postgres?pgbouncer=true
Session mode (port 5432) — for LISTEN/NOTIFY and prepared statements:
For securing your Supabase project with RLS policies and API key management, see supabase-security-basics. For optimizing database queries and indexing, see supabase-performance-tuning.