The "PGRST001: Connection to the database was lost" error occurs when PostgREST (Supabase's REST API layer) cannot maintain a connection to your PostgreSQL database. This typically happens due to network issues, database server problems, connection pool exhaustion, or infrastructure maintenance. The error returns HTTP status 503 (Service Unavailable) and indicates a temporary loss of database connectivity.
The "PGRST001: Connection to the database was lost" error is a PostgREST error code that indicates Supabase's REST API layer (PostgREST) has lost its connection to your PostgreSQL database. PostgREST is the component that translates HTTP requests into SQL queries and returns JSON responses. This error falls under "Group 0 - Connection" errors in PostgREST and has an HTTP status of 503 (Service Unavailable). Unlike PGRST000 (which indicates configuration issues or non-running services), PGRST001 specifically means that PostgREST could not connect with the database due to an internal error after the connection was initially established. The error typically occurs when: 1. **Network connectivity issues** - Temporary network disruptions between PostgREST and PostgreSQL 2. **Database server problems** - PostgreSQL instance is restarting, overloaded, or experiencing issues 3. **Connection pool exhaustion** - All available database connections are in use 4. **Infrastructure maintenance** - Supabase platform maintenance or updates 5. **Firewall/security changes** - Network security rules blocking connections This is usually a temporary error that resolves when connectivity is restored, but persistent occurrences indicate underlying infrastructure issues that need investigation.
First, verify if this is a platform-wide issue by checking Supabase's status:
1. Check Supabase Status Page:
- Visit [status.supabase.com](https://status.supabase.com)
- Look for any ongoing incidents or maintenance
- Check if other users are reporting similar issues
2. Wait and retry:
- Many PGRST001 errors are temporary and resolve within minutes
- Implement exponential backoff in your application:
async function retryWithBackoff(operation, maxRetries = 5) {
let lastError;
for (let i = 0; i < maxRetries; i++) {
try {
return await operation();
} catch (error) {
lastError = error;
if (error.message.includes('PGRST001')) {
// Wait exponentially longer each retry
const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s, 8s, 16s
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
throw lastError;
}3. Monitor error patterns:
- Check if errors occur at specific times (e.g., during backups)
- Note if errors affect all endpoints or specific ones
- Track error frequency and duration
Check your database connection usage and optimize connection pooling:
1. Check active connections in Supabase Dashboard:
- Go to your project → Database → Connection Pooler
- Monitor "Database Connections" and "Pooler Client Connections"
- Look for connection spikes or sustained high usage
2. Check connection limits:
-- Check max_connections setting
SHOW max_connections;
-- Check current connection count
SELECT count(*) FROM pg_stat_activity;
-- Check connections by database
SELECT datname, count(*) as connections
FROM pg_stat_activity
GROUP BY datname
ORDER BY connections DESC;3. Optimize connection pooling:
- Use Supabase's connection pooler (enabled by default)
- For serverless/edge functions, use transaction mode (port 6543)
- For traditional servers, use session mode
- Implement connection reuse in your application:
// Reuse Supabase client instead of creating new instances
// In serverless environments, cache the client outside handler
let cachedClient = null;
export async function handler() {
if (!cachedClient) {
cachedClient = createClient(
process.env.SUPABASE_URL,
process.env.SUPABASE_ANON_KEY
);
}
return cachedClient;
}4. Close idle connections:
-- Check for idle connections
SELECT pid, datname, usename, state, query_start, state_change
FROM pg_stat_activity
WHERE state = 'idle'
ORDER BY state_change;
-- Kill long-idle connections (use with caution)
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle'
AND state_change < NOW() - INTERVAL '10 minutes';Long-running or inefficient queries can hold connections open:
1. Identify slow queries:
-- Find slow-running queries
SELECT pid, usename, datname, query, now() - query_start as duration
FROM pg_stat_activity
WHERE state = 'active'
AND query_start IS NOT NULL
ORDER BY duration DESC
LIMIT 10;
-- Check for queries with locks
SELECT blocked_locks.pid AS blocked_pid,
blocked_activity.query AS blocked_query,
blocking_locks.pid AS blocking_pid,
blocking_activity.query AS blocking_query
FROM pg_catalog.pg_locks blocked_locks
JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
JOIN pg_catalog.pg_locks blocking_locks ON blocking_locks.locktype = blocked_locks.locktype
AND blocking_locks.database IS NOT DISTINCT FROM blocked_locks.database
AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
AND blocking_locks.pid != blocked_locks.pid
JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
WHERE NOT blocked_locks.granted;2. Add query timeouts:
// Set statement timeout at connection level
const supabase = createClient(
process.env.SUPABASE_URL,
process.env.SUPABASE_ANON_KEY,
{
db: {
schema: 'public',
// Set 30 second timeout
searchPath: 'public',
// Use connection string with options
connection: {
statement_timeout: '30000' // 30 seconds in milliseconds
}
}
}
);3. Optimize common queries:
- Add indexes on frequently queried columns
- Use LIMIT to prevent large result sets
- Implement pagination for large datasets
- Use EXPLAIN ANALYZE to identify bottlenecks
Verify network connectivity and firewall rules:
1. Test database connectivity:
# Test basic connectivity to Supabase
ping db.your-project.supabase.co
# Test PostgreSQL port (5432 for direct, 6543 for pooler)
nc -zv db.your-project.supabase.co 5432
nc -zv db.your-project.supabase.co 6543
# Test with psql (if you have credentials)
psql "postgresql://postgres:[YOUR-PASSWORD]@db.your-project.supabase.co:5432/postgres"2. Check firewall rules:
- Ensure your application's outbound traffic can reach Supabase
- Verify no firewall is blocking ports 5432 or 6543
- Check if you're behind a corporate proxy that might interfere
- For IPv6 issues, try using Supavisor session mode or IPv4 add-on
3. DNS resolution:
# Check DNS resolution
nslookup db.your-project.supabase.co
dig db.your-project.supabase.co
# Flush DNS cache if needed
sudo systemd-resolve --flush-caches # Linux
sudo killall -HUP mDNSResponder # macOS
ipconfig /flushdns # Windows4. Network timeouts:
- Increase network timeouts in your application
- Implement proper error handling and retries
- Consider using a CDN or edge locations closer to Supabase region
If connection issues persist, consider scaling your database:
1. Upgrade database plan:
- Free tier: 500 MB database, 2 concurrent connections
- Pro tier: 8 GB database, 100 concurrent connections
- Enterprise: Custom limits and dedicated resources
2. Enable connection pooling features:
- Supavisor: Supabase's managed connection pooler (enabled by default)
- Transaction mode: For serverless/edge functions (port 6543)
- Session mode: For traditional applications
- Dedicated pooler: Available on paid plans
3. Monitor resource usage:
-- Check CPU and memory usage
SELECT * FROM pg_stat_database WHERE datname = current_database();
-- Check disk space
SELECT pg_database_size(current_database());
-- Check for resource contention
SELECT * FROM pg_stat_activity WHERE wait_event_type IS NOT NULL;4. Contact Supabase support:
- For Pro and Enterprise plans, contact support for assistance
- Provide error logs, timestamps, and reproduction steps
- Share connection metrics and query patterns
Add comprehensive error handling to your application:
1. Implement circuit breaker pattern:
class CircuitBreaker {
constructor(failureThreshold = 5, resetTimeout = 60000) {
this.failureThreshold = failureThreshold;
this.resetTimeout = resetTimeout;
this.failureCount = 0;
this.lastFailureTime = null;
this.state = 'CLOSED'; // CLOSED, OPEN, HALF_OPEN
}
async execute(operation) {
if (this.state === 'OPEN') {
if (Date.now() - this.lastFailureTime > this.resetTimeout) {
this.state = 'HALF_OPEN';
} else {
throw new Error('Circuit breaker is OPEN');
}
}
try {
const result = await operation();
if (this.state === 'HALF_OPEN') {
this.reset();
}
return result;
} catch (error) {
this.recordFailure();
throw error;
}
}
recordFailure() {
this.failureCount++;
this.lastFailureTime = Date.now();
if (this.failureCount >= this.failureThreshold) {
this.state = 'OPEN';
}
}
reset() {
this.failureCount = 0;
this.lastFailureTime = null;
this.state = 'CLOSED';
}
}2. Add comprehensive logging:
// Log database connection errors with context
function logDatabaseError(error, context = {}) {
console.error({
timestamp: new Date().toISOString(),
error: error.message,
code: error.code,
severity: 'ERROR',
context: {
...context,
supabaseProject: process.env.SUPABASE_PROJECT_ID,
environment: process.env.NODE_ENV
}
});
}
// Use in your application
try {
await supabase.from('users').select('*');
} catch (error) {
logDatabaseError(error, {
operation: 'select_users',
table: 'users'
});
// Implement fallback logic
}3. Set up monitoring alerts:
- Monitor error rates for PGRST001 errors
- Set up alerts for sustained connection issues
- Track database connection pool usage
- Monitor query performance and timeouts
## Understanding PostgREST Connection Architecture
PostgREST (PostgreSQL REST) is the REST API layer that Supabase uses to expose your PostgreSQL database as a RESTful API. The connection flow works as follows:
1. Client Request → PostgREST → PostgreSQL Connection Pool → PostgreSQL Database
### Connection Pooling Strategies
Supabase offers different connection pooling options:
1. Direct Connection (port 5432):
- IPv6 by default, may require IPv4 add-on
- Limited by PostgreSQL max_connections
- Not recommended for serverless/edge functions
2. Supavisor Session Mode:
- Connection pooling with session semantics
- Better for traditional server applications
- Reuses connections across requests
3. Supavisor Transaction Mode (port 6543):
- Ideal for serverless/edge functions
- Connections are released after each transaction
- Prevents connection exhaustion in serverless environments
### Database Connection Limits
| Plan | Max Connections | Pooler Connections | Notes |
|------|----------------|-------------------|-------|
| Free | 20 | 500 | Limited concurrent operations |
| Pro | 500 | 2,000 | Suitable for most applications |
| Enterprise | Custom | Custom | Dedicated resources |
### Troubleshooting Persistent PGRST001 Errors
If PGRST001 errors persist despite following the steps above:
1. Check PostgreSQL logs:
-- Enable more verbose logging temporarily
ALTER DATABASE your_database SET log_connections = on;
ALTER DATABASE your_database SET log_disconnections = on;
ALTER DATABASE your_database SET log_min_duration_statement = 1000;2. Monitor connection states:
-- Detailed connection analysis
SELECT
state,
count(*) as count,
now() - min(state_change) as oldest_state,
now() - max(state_change) as newest_state
FROM pg_stat_activity
WHERE datname = current_database()
GROUP BY state
ORDER BY count DESC;3. Check for connection leaks in application code:
- Ensure database clients are properly closed/disposed
- Use connection pools with appropriate size limits
- Implement connection timeout and idle timeout settings
- Monitor connection creation/destruction patterns
### Infrastructure Considerations
1. Region Selection: Choose a Supabase region close to your users
2. VPC Peering: For Enterprise plans, consider VPC peering for more reliable networking
3. Read Replicas: Distribute read traffic to reduce load on primary database
4. Connection Multiplexing: Use PgBouncer or similar for efficient connection reuse
### Performance Tuning
1. Connection Pool Sizing:
// Optimal pool size formula
// pool_size = (core_count * 2) + effective_spindle_count
// For serverless: Use transaction mode instead2. Query Optimization:
- Use prepared statements for frequently executed queries
- Implement query caching where appropriate
- Use materialized views for complex, read-heavy queries
- Partition large tables to improve query performance
### Security Considerations
1. Network Security:
- Use SSL/TLS for all database connections
- Implement IP allowlisting if needed
- Regularly rotate database credentials
2. Connection Security:
- Use different database roles for different access levels
- Implement connection time limits
- Monitor for suspicious connection patterns
### Monitoring and Alerting Setup
Recommended monitoring metrics:
- Database connection count (active/idle)
- Connection error rate (PGRST001 specifically)
- Query response time percentiles
- Connection pool utilization
- Network latency to database region
Set up alerts for:
- Sustained PGRST001 error rates (> 5% for 5 minutes)
- Connection pool exhaustion (> 80% utilization)
- Query timeout increases (> 2x baseline)
- Regional latency spikes (> 200ms increase)
email_address_not_authorized: Email sending to this address is not authorized
Email address not authorized for sending in Supabase Auth
reauthentication_needed: Reauthentication required for security-sensitive actions
Reauthentication required for security-sensitive actions
no_authorization: No authorization header was provided
How to fix "no authorization header was provided" in Supabase
otp_expired: OTP has expired
How to fix 'otp_expired: OTP has expired' in Supabase
bad_oauth_state: OAuth state parameter is missing or invalid
How to fix 'bad_oauth_state: OAuth state parameter missing' in Supabase