High Availability for Self-Hosted Supabase: Architecture Guide

Learn how to architect self-hosted Supabase for high availability with multi-node PostgreSQL, connection pooling, and failover strategies.

Cover Image for High Availability for Self-Hosted Supabase: Architecture Guide

When you're running self-hosted Supabase in production, a single Docker Compose setup on one server isn't going to cut it. One server failure means your entire application goes down—and that's not acceptable for serious production workloads.

The good news? Supabase's architecture actually makes high availability achievable. The challenging part is understanding which components need redundancy and how to set it all up. In this guide, we'll walk through building a production-ready Supabase deployment that can survive server failures without losing data or significant uptime.

Understanding Supabase's Component Architecture

Before diving into high availability strategies, you need to understand what you're actually running. Supabase isn't a single application—it's approximately 12 interconnected services:

Stateful Components (Critical for HA):

  • PostgreSQL - Your database, the heart of everything
  • Storage - File storage backed by S3-compatible object storage

Stateless Components (Easier to Scale):

  • GoTrue - Authentication service
  • PostgREST - REST API layer
  • Realtime - WebSocket connections for live updates
  • Kong - API gateway and routing
  • Studio - Admin dashboard
  • Edge Functions runtime - Deno-based serverless functions

The distinction between stateful and stateless is crucial. Stateless services can simply be replicated behind a load balancer—if one instance dies, traffic routes to another. Stateful services require careful replication strategies to avoid data loss and inconsistency.

The PostgreSQL Challenge

PostgreSQL is where high availability gets complicated. Unlike spinning up another container, database replication requires:

  1. Data synchronization between nodes
  2. Failover detection when the primary goes down
  3. Automatic promotion of a replica to primary
  4. Client reconnection to the new primary

Option 1: Managed PostgreSQL

The simplest approach is separating your database from Supabase entirely. Use a managed PostgreSQL service with built-in high availability:

  • AWS RDS - Multi-AZ deployment with automatic failover
  • Google Cloud SQL - Regional instances with automatic failover
  • DigitalOcean Managed Databases - Standby nodes with automatic failover
  • Aiven - Managed PostgreSQL with HA options

This approach works because Supabase can connect to any external PostgreSQL instance. You configure your connection string to point to the managed service, and the cloud provider handles replication, failover, and backups.

Trade-off: You're adding a cloud dependency. If you chose self-hosting for data sovereignty or cost reasons, using a managed database partially defeats that purpose. But it dramatically simplifies operations.

Option 2: Patroni for Self-Managed Clustering

For true self-hosting, Patroni is the go-to solution for PostgreSQL high availability. It manages a cluster of PostgreSQL nodes and handles:

  • Automatic failover when the primary fails
  • Distributed consensus using etcd, Consul, or ZooKeeper
  • Automatic replica provisioning
  • Rolling upgrades

A minimal production-ready setup requires:

3x PostgreSQL nodes with Patroni
3x etcd nodes (can colocate with PostgreSQL)
1x HAProxy or pgBouncer for connection routing

The three-node requirement isn't arbitrary. Distributed consensus requires a quorum—a majority of nodes must agree. With three nodes, you can lose one and still have a functioning cluster. With two nodes, you have no fault tolerance.

Option 3: Pigsty for Enterprise Deployments

Pigsty is an open-source PostgreSQL distribution that bundles high availability, monitoring, and Supabase integration. It handles:

  • Multi-node PostgreSQL with automatic failover
  • MinIO cluster for object storage
  • Monitoring with Prometheus and Grafana
  • Single-command deployment

For teams without deep PostgreSQL expertise, Pigsty provides a more turnkey solution than building Patroni clusters from scratch. The trade-off is less flexibility and a steeper learning curve for the Pigsty ecosystem itself.

Connection Pooling with Supavisor

Once you have multiple database nodes, you need intelligent connection routing. Supavisor is Supabase's cloud-native connection pooler, and it's available for self-hosting.

Why connection pooling matters for HA:

  1. Connection efficiency - PostgreSQL connections are expensive. Pooling multiplexes thousands of client connections into a smaller pool of database connections.

  2. Failover handling - When a database node fails, Supavisor can route connections to the new primary automatically.

  3. Load distribution - Read queries can be distributed across replicas, reducing primary load.

# Example Supavisor configuration
supavisor:
  image: supabase/supavisor:latest
  environment:
    - DATABASE_URL=postgresql://user:pass@primary:5432/postgres
    - POOL_SIZE=100
    - MAX_CLIENT_CONNECTIONS=10000

Supavisor monitors pool processes across nodes. If a node fails, that process ID is removed from the cluster, and tenant clients automatically start a new pool as they reconnect.

Scaling Stateless Services

The stateless Supabase components—Auth, PostgREST, Realtime, Storage API—can be scaled horizontally with standard techniques:

Load Balancer Setup

Place a load balancer in front of your Supabase services:

                    ┌─────────────────┐
                    │  Load Balancer  │
                    │  (HAProxy/Nginx)│
                    └────────┬────────┘
                             │
        ┌────────────────────┼────────────────────┐
        │                    │                    │
   ┌────▼────┐          ┌────▼────┐          ┌────▼────┐
   │ Supabase│          │ Supabase│          │ Supabase│
   │ Node 1  │          │ Node 2  │          │ Node 3  │
   └─────────┘          └─────────┘          └─────────┘

Each node runs the full Supabase stack (except PostgreSQL, which is in a separate cluster). Health checks ensure traffic only routes to healthy nodes.

Realtime Considerations

The Realtime service requires special attention. It maintains WebSocket connections and Postgres logical replication slots. When scaling Realtime:

  • Use sticky sessions (session affinity) for WebSocket connections
  • Configure max_slot_wal_keep_size to prevent disk space issues from WAL buildup
  • Monitor channel limits (default: 100 channels per tenant, 200 concurrent users per channel)

Realtime doesn't guarantee message delivery, which is by design. For critical events, implement acknowledgment logic in your application rather than assuming every message arrives.

Storage High Availability

Supabase Storage supports S3-compatible backends, making high availability straightforward:

Option 1: Cloud Object Storage

  • AWS S3 (built-in redundancy across availability zones)
  • Google Cloud Storage
  • DigitalOcean Spaces
  • Backblaze B2

Option 2: Self-Hosted MinIO Cluster

MinIO provides S3-compatible storage that you can run yourself. For high availability:

4x MinIO nodes minimum (can tolerate 2 failures)
Distributed across availability zones or racks
Object-level erasure coding for data protection

If you're using Pigsty, it can deploy a MinIO cluster alongside PostgreSQL, simplifying the architecture.

Monitoring and Observability

High availability isn't just about redundancy—it's about knowing when something fails before users notice. For self-hosted Supabase, you'll need to set up monitoring separately from the managed dashboard.

Essential Metrics

Database health:

  • Replication lag between primary and replicas
  • Connection pool utilization
  • Query latency (p50, p95, p99)
  • WAL file count and disk usage

Service health:

  • HTTP response times for each service
  • Error rates by service
  • Memory and CPU utilization
  • Container restart counts

Realtime specific:

  • Active WebSocket connections
  • Channel count by tenant
  • Message throughput

Logging Considerations

Supabase's self-hosted logging uses Logflare with Vector for log routing. For production, the official recommendation is to use the BigQuery backend rather than PostgreSQL for logs. The PostgreSQL backend isn't optimized for high-volume inserts, and critically—if your main Postgres has issues, you won't be able to debug them because Logflare would be down too.

Consider running your observability stack on completely separate infrastructure. You can check our monitoring guide for detailed setup instructions.

Minimum Production Requirements

Based on Pigsty's recommendations and community experience, here's what a production-ready high-availability setup looks like:

3-4 Node Deployment:

  • 3x PostgreSQL nodes with Patroni (or managed PostgreSQL)
  • 3x etcd nodes (can colocate with PostgreSQL)
  • 2-3x Supabase service nodes behind load balancer
  • 4x MinIO nodes (or S3-compatible cloud storage)
  • 1x Load balancer (consider HA pair)

Achievable SLAs:

  • RTO (Recovery Time Objective): < 30 seconds
  • RPO (Recovery Point Objective): Zero data loss with synchronous replication

Estimated costs:

  • Hetzner: ~€200-300/month for the full stack
  • AWS: ~$800-1200/month depending on instance sizes
  • DigitalOcean: ~$400-600/month

Compare this to Supabase Cloud pricing at scale—the self-hosted route can be significantly cheaper, but you're trading money for operational complexity.

When High Availability Isn't Worth It

Honest assessment: not everyone needs this level of infrastructure. High availability makes sense when:

  • Downtime directly costs money (e-commerce, SaaS with SLAs)
  • You have DevOps capacity to manage the complexity
  • Scale justifies the investment (500K+ MAU or equivalent)
  • Compliance requires it (financial services, healthcare)

If you're running a side project, early-stage startup, or internal tool, a single-node setup with regular backups and tested restore procedures is often sufficient. You can add high availability later when the business justifies it.

How Supascale Simplifies This

Building high availability from scratch requires significant PostgreSQL expertise and ongoing maintenance. Supascale handles the operational complexity of self-hosted Supabase:

  • Automated backups to S3-compatible storage with one-click restore
  • Custom domains with automatic SSL certificates
  • OAuth configuration through a simple UI instead of environment variable juggling
  • Selective service deployment so you only run what you need

While Supascale doesn't replace the need for a properly architected PostgreSQL cluster for true HA, it eliminates the day-to-day operational burden of managing Supabase services themselves. You can focus on your database infrastructure while Supascale handles project management, backups, and configuration.

Next Steps

  1. Assess your requirements - Do you actually need HA, or are regular backups sufficient?
  2. Choose your database strategy - Managed PostgreSQL, Patroni, or Pigsty
  3. Set up monitoring first - You can't manage what you can't measure
  4. Test failover scenarios - Regularly simulate failures to validate your setup
  5. Document runbooks - When 3 AM incidents happen, you'll thank yourself

For teams getting started with self-hosted Supabase, check out our deployment guide first. High availability is a progression—start simple, monitor everything, and add redundancy as your needs grow.

Ready to simplify your self-hosted Supabase management? Try Supascale with a one-time purchase for unlimited projects.


Further Reading