Is Supabase Down? How to Check and What to Do
Is Supabase Down? How to Check and What to Do
Supabase has rapidly become the go-to backend for modern applications, powering over 1 million databases with its open-source Firebase alternative. When Supabase goes down, it's not just a database outage — it can take out authentication, real-time subscriptions, file storage, and edge functions all at once.
With 590+ monthly searches for "is Supabase down," developers regularly find themselves wondering whether it's their code or the platform.
Here's how to tell the difference and what to do about it.
How to Check if Supabase is Actually Down
Step 1: Check Official Status
Supabase Status Page: status.supabase.com
Supabase breaks their status into components:
- API Gateway (PostgREST, GoTrue, Storage, Realtime)
- Database (Postgres instances)
- Auth (GoTrue / Supabase Auth)
- Storage (S3-backed file storage)
- Realtime (WebSocket subscriptions)
- Edge Functions (Deno-based serverless)
- Dashboard (management console)
- Supabase CLI
⚠️ Important: Supabase runs projects in specific AWS regions. An outage in us-east-1 won't affect eu-west-1. Your project's region matters.
Step 2: Check API Status Check
Real-time monitoring: apistatuscheck.com/api/supabase
Independent monitoring gives you a second data point when Supabase's own status page is lagging.
Step 3: Check Community Reports
- Twitter/X: Search "Supabase down"
- Discord: Supabase Discord — the #help channel lights up during outages
- GitHub: github.com/supabase/supabase/issues — check for outage-related issues
- Reddit: r/Supabase
Step 4: Test Your Specific Project
# Check if your project's API is responding
curl -s -o /dev/null -w "%{http_code}" \
https://YOUR_PROJECT_REF.supabase.co/rest/v1/ \
-H "apikey: YOUR_ANON_KEY"
# Check database connectivity directly
psql "postgresql://postgres:YOUR_PASSWORD@db.YOUR_PROJECT_REF.supabase.co:5432/postgres" \
-c "SELECT 1;"
# Check auth service
curl -s -o /dev/null -w "%{http_code}" \
https://YOUR_PROJECT_REF.supabase.co/auth/v1/health
# Check realtime
curl -s -o /dev/null -w "%{http_code}" \
https://YOUR_PROJECT_REF.supabase.co/realtime/v1/health
# Check storage
curl -s -o /dev/null -w "%{http_code}" \
https://YOUR_PROJECT_REF.supabase.co/storage/v1/health
Common Supabase Issues (That Aren't Platform Outages)
Database Connection Limits
The #1 Supabase "outage" that isn't one.
- Free tier: 60 direct connections max
- Pro tier: 200 direct connections max
- Symptom: "too many clients already" or connection timeouts
Fix:
// Use connection pooling (Supavisor) instead of direct connections
// Connection string format:
// Direct: postgresql://postgres:pw@db.xxx.supabase.co:5432/postgres
// Pooled: postgresql://postgres:pw@db.xxx.supabase.co:6543/postgres
// ^^^^
// Note port 6543 (pooler) vs 5432 (direct)
// In your Supabase client, use the pooled connection for serverless:
const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY, {
db: { schema: 'public' },
auth: { persistSession: true },
})
Project Paused (Free Tier)
- Symptom: Everything returns errors, dashboard says "paused"
- Cause: Free tier projects pause after 1 week of inactivity
- Fix: Go to dashboard → Restore project. Takes 1-2 minutes.
- Prevention: Upgrade to Pro ($25/mo) or set up a cron job that pings your project
Row Level Security (RLS) Blocking Queries
- Symptom: Queries return empty results or 401 errors, but data exists
- Not an outage: Your RLS policies are working as designed
- Debug: Check your policies in Dashboard → Authentication → Policies
- Quick test: Use the service role key (server-side only!) to bypass RLS and confirm data exists
Auth Token Issues
- Expired JWT: Default access tokens expire after 1 hour
- Symptom: Requests suddenly fail with 401 after working fine
- Fix: Ensure your client refreshes tokens automatically:
// Supabase JS client handles this automatically, but verify:
const { data: { session } } = await supabase.auth.getSession()
// If null, the session expired and wasn't refreshed
// Force refresh:
const { data, error } = await supabase.auth.refreshSession()
Edge Function Cold Starts
- Symptom: First request to an edge function takes 3-10 seconds
- Not an outage: Cold starts are normal for serverless functions
- Mitigation: Keep functions warm with a cron ping, or accept the first-request latency
DNS and SSL Issues
- Custom domains: If using a custom domain for your Supabase project, DNS misconfiguration can cause connection failures
- SSL mode: Ensure your client uses
sslmode=requirefor database connections
What to Do When Supabase is Actually Down
Immediate Response
- Identify which services are affected: Database? Auth? Storage? Realtime? All of them?
- Check your region: Is it a global outage or region-specific?
- Don't restart your project: This won't help during a platform outage and may make recovery slower
Database is Down
Your Postgres database is the most critical component. If it's unreachable:
- Read replicas: If you have read replicas in another region, fail over read traffic
- Connection pooling: Switch to Supavisor (port 6543) if you weren't already — it handles connection drops more gracefully
- Cache layer: If you have Redis/Upstash in front of your database, cached data still serves
- Queue writes: Store failed writes in a client-side queue and retry when the database recovers
// Simple write queue for Supabase outages
const writeQueue = [];
async function resilientInsert(table, data) {
try {
const { error } = await supabase.from(table).insert(data);
if (error) throw error;
return { success: true };
} catch (err) {
// Queue for retry
writeQueue.push({ table, data, timestamp: Date.now() });
console.warn(`Queued write to ${table} — Supabase may be down`);
return { success: false, queued: true };
}
}
// Drain queue when connection recovers
async function drainWriteQueue() {
while (writeQueue.length > 0) {
const item = writeQueue[0];
try {
await supabase.from(item.table).insert(item.data);
writeQueue.shift(); // Remove on success
} catch {
break; // Still down, stop draining
}
}
}
Auth is Down
If Supabase Auth (GoTrue) is unreachable:
- Existing sessions still work: JWTs are self-contained — your app can verify them locally without calling Supabase Auth
- New signups/logins will fail: No way around this unless you have a fallback auth provider
- Cache user data: Don't fetch user profiles from Supabase Auth on every request — cache them
- Graceful degradation: Show a "login temporarily unavailable" message instead of a generic error
Storage is Down
- CDN cache: If your files are served through a CDN (Cloudflare, Vercel), cached files still serve
- Fallback URLs: Keep backup copies of critical assets (logos, config files) on a separate CDN
- Upload queue: Queue file uploads and process them when storage recovers
Realtime is Down
- Polling fallback: Switch from WebSocket subscriptions to HTTP polling:
// Instead of realtime subscription, poll every 5 seconds
const pollInterval = setInterval(async () => {
const { data } = await supabase.from('messages').select('*').order('created_at', { ascending: false }).limit(10);
updateUI(data);
}, 5000);
- Notify users: "Real-time updates paused. Page will refresh periodically."
Building Supabase Resilience
Multi-Region Setup
- Primary: Supabase project in your main region
- Read replicas: Available on Pro plan for read scaling and geographic distribution
- Backup database: Consider a separate Neon or PlanetScale database for critical data backup
Caching Strategy
Don't hit Supabase on every request:
- Edge caching: Vercel/Cloudflare caches for public data
- Redis/Upstash: Server-side caching for frequent queries
- Client-side: React Query / SWR with stale-while-revalidate
Backup Automation
# Daily Supabase database backup
# Use pg_dump with your direct connection string
pg_dump "postgresql://postgres:PASSWORD@db.PROJECT_REF.supabase.co:5432/postgres" \
--format=custom \
--file="backup-$(date +%Y%m%d).dump"
# Or use Supabase CLI
supabase db dump --project-ref YOUR_PROJECT_REF > backup.sql
Health Monitoring
// Supabase health check endpoint for your monitoring
app.get('/health/supabase', async (req, res) => {
const checks = {};
// Database
try {
const { data, error } = await supabase.from('_health').select('*').limit(1);
checks.database = error ? 'error' : 'ok';
} catch { checks.database = 'unreachable'; }
// Auth
try {
const resp = await fetch(`${SUPABASE_URL}/auth/v1/health`);
checks.auth = resp.ok ? 'ok' : 'error';
} catch { checks.auth = 'unreachable'; }
// Storage
try {
const resp = await fetch(`${SUPABASE_URL}/storage/v1/health`);
checks.storage = resp.ok ? 'ok' : 'error';
} catch { checks.storage = 'unreachable'; }
const allOk = Object.values(checks).every(v => v === 'ok');
res.status(allOk ? 200 : 503).json({ status: allOk ? 'healthy' : 'degraded', checks });
});
Supabase Alternatives for Failover
| Service | Best For | Migration Effort | Pricing |
|---|---|---|---|
| Firebase | Mobile-first apps | Moderate (different API) | Generous free tier |
| PlanetScale | MySQL-based apps | High (different DB) | Free tier available |
| Neon | Serverless Postgres | Low (same Postgres) | Free tier available |
| Appwrite | Self-hosted BaaS | Moderate | Free (self-hosted) |
| AWS Amplify | AWS ecosystem | High | Pay-per-use |
| Convex | Real-time first | High (different paradigm) | Free tier available |
| Pocketbase | Single-binary backend | Moderate | Free (self-hosted) |
Closest drop-in replacement: Neon — it's also Postgres, so your schema and queries work unchanged. Different auth/storage, but the database layer transfers directly.
Stay Updated
- Monitor Supabase status: apistatuscheck.com/api/supabase
- Subscribe to alerts: Get notified when Supabase goes down
- Supabase Status RSS: status.supabase.com → Subscribe
- Supabase Discord: discord.supabase.com — fastest community reports
Last updated: February 2, 2026. We monitor Supabase and 50+ APIs 24/7 at API Status Check.
Monitor Your APIs
Check the real-time status of 100+ popular APIs used by developers.
View API Status →