This document describes the scalable PostgreSQL architecture implemented to handle 1 million users for the Vesting Vault platform. The architecture uses read replicas and load balancing to ensure high availability and performance.
- Purpose: Handles all write operations (INSERT, UPDATE, DELETE)
- Configuration: PostgreSQL 15 with replication enabled
- Port: 5432
- Features:
- WAL (Write-Ahead Logging) for replication
- Optimized for write performance
- Automatic backup and point-in-time recovery
- Purpose: Handles all read operations (SELECT queries)
- Count: 2 replicas (configurable)
- Ports: 5433, 5434
- Features:
- Hot standby for real-time replication
- Read-only operations only
- Automatic failover support
- Purpose: Manages connections to the master database
- Port: 6432
- Pool Size: 20 connections
- Mode: Transaction pooling
- Purpose: Manages connections to read replicas
- Port: 6433
- Pool Size: 40 connections
- Mode: Transaction pooling
- Load Balancing: Round-robin between healthy replicas
- Purpose: Automatically routes queries to appropriate database
- Features:
- Read/write splitting based on operation type
- Automatic failover to master for critical reads
- Replica lag monitoring
- Purpose: Handles replica failures and recovery
- Features:
- Health monitoring of all replicas
- Automatic exclusion of failed replicas
- Recovery detection and reintegration
- Purpose: Continuous monitoring of database cluster health
- Port: 3001
- Endpoints:
/health- Current health status/metrics- Prometheus-style metrics/health/cached- Cached health status
- Docker and Docker Compose
- Sufficient disk space for databases (recommended: 100GB+)
- Network bandwidth for replication traffic
-
Environment Setup
cp .env.staging .env.local # Edit .env.local with your configuration -
Deploy the Cluster
chmod +x scripts/deploy-scalable.sh ./scripts/deploy-scalable.sh staging
-
Verify Deployment
# Check health status curl http://localhost:3001/health # View metrics curl http://localhost:3001/metrics
# Enable cluster mode
DB_CLUSTER_MODE=true
# Write database (master)
DB_WRITE_HOST=pgbouncer-write
DB_WRITE_PORT=6432
DB_WRITE_NAME=vesting_vault
DB_WRITE_USER=postgres
DB_WRITE_PASSWORD=your_password
# Read database (replicas)
DB_READ_HOST=pgbouncer-read
DB_READ_PORT=6433
DB_READ_NAME=vesting_vault
DB_READ_USER=postgres
DB_READ_PASSWORD=your_password
# Direct replica connections (for failover)
DB_READ_HOSTS=postgres-replica-1:5432,postgres-replica-2:5432
# Performance tuning
DB_REPLICA_LAG_THRESHOLD=1000- Throughput: Up to 10x improvement with 2 replicas
- Latency: Sub-100ms for cached queries
- Concurrency: 40+ concurrent read connections
- Throughput: Optimized for high-frequency writes
- Latency: <50ms for standard writes
- Durability: Synchronous replication to replicas
- Detection Time: <30 seconds
- Failover Time: <5 seconds
- Recovery Time: Automatic within 5 minutes
- Master database availability
- Replica database availability
- Replication lag (bytes)
- Connection pool utilization
- Query latency (p50, p95, p99)
- Throughput (queries/second)
- Error rates
- Connection pool statistics
- Replica lag > 1MB
- Database availability < 99.9%
- Connection pool utilization > 80%
- Query latency > 1 second
curl http://localhost:3001/healthResponse format:
{
"timestamp": "2024-01-01T00:00:00.000Z",
"master": { "healthy": true },
"replicas": [
{ "index": 0, "healthy": true, "lag": 1024 },
{ "index": 1, "healthy": true, "lag": 2048 }
],
"overall": "healthy"
}curl http://localhost:3001/metricsPrometheus-style metrics for monitoring systems.
Run the comprehensive test suite:
chmod +x scripts/test-scalability.sh
./scripts/test-scalability.sh staging- Read/Write Splitting - Verifies queries go to correct database
- Load Balancing - Tests distribution across replicas
- Replica Lag - Monitors replication performance
- Failover - Tests automatic failover behavior
- Health Monitoring - Validates monitoring systems
- Performance - Benchmarks concurrent operations
- Connection Pooling - Tests pool limits and efficiency
- Data Consistency - Ensures data integrity
- High Availability - Tests resilience to failures
- Stress Test - Validates performance under load
Symptoms: Read operations return stale data
Solutions:
- Check network bandwidth between master and replicas
- Monitor disk I/O on replicas
- Consider reducing write frequency
- Increase
wal_keep_sizeon master
Symptoms: "Too many connections" errors
Solutions:
- Increase pool size in PgBouncer configuration
- Optimize application connection usage
- Implement connection timeouts
- Monitor connection pool metrics
Symptoms: Failed health checks, reduced read capacity
Solutions:
- Check replica logs for errors
- Verify network connectivity
- Restart replica service
- Reinitialize replica from master backup
# Master
docker-compose exec postgres-master psql -U postgres -d vesting_vault -c "SELECT * FROM pg_stat_replication;"
# Replicas
docker-compose exec postgres-replica-1 psql -U postgres -d vesting_vault -c "SELECT pg_last_wal_replay_lsn();"# Write pool
docker-compose exec pgbouncer-write psql -U postgres -d pgbouncer -c "SHOW POOLS;"
# Read pool
docker-compose exec pgbouncer-read psql -U postgres -d pgbouncer -c "SHOW POOLS;"# All services
docker-compose logs -f
# Specific service
docker-compose logs -f postgres-master- Update
docker-compose-scalable.yml - Add new replica configuration
- Update PgBouncer read pool configuration
- Restart services
- Verify replication status
- Stop traffic to replica (PgBouncer)
- Wait for existing connections to drain
- Stop replica service
- Update configuration
- Restart services
- Increase CPU cores for write operations
- Add RAM for larger shared_buffers
- Use SSD storage for better I/O
- Consider partitioning for large tables
- Scale based on read workload
- More replicas = better read performance
- Consider read-specific optimizations
- Use SSL/TLS for all database connections
- Implement network segmentation
- Restrict access to database ports
- Use VPN or private networks
- Strong passwords for all database users
- Separate users for different applications
- Regular password rotation
- Implement connection limits
- Enable transparent data encryption
- Regular backups with encryption
- Audit logging for all operations
- Compliance with data protection regulations
- Continuous Archiving: WAL files shipped to backup storage
- Full Backups: Daily base backups
- Point-in-Time Recovery: Restore to any point in time
- Cross-Region Replication: Disaster recovery
- Master Failure: Promote replica to master
- Replica Failure: Rebuild from master backup
- Partial Corruption: Point-in-time recovery
- Complete Loss: Restore from latest backup
# Memory
shared_buffers = 256MB
effective_cache_size = 1GB
work_mem = 4MB
# WAL for replication
wal_level = replica
max_wal_senders = 3
max_replication_slots = 3
wal_keep_size = 1GB
# Checkpoints
checkpoint_completion_target = 0.9# Read performance
hot_standby = on
max_standby_streaming_delay = 30s
# Recovery
restore_command = 'cp /var/lib/postgresql/archive/%f %p'- Use connection pooling
- Implement proper connection timeouts
- Close connections properly
- Monitor connection usage
- Use appropriate indexes
- Optimize slow queries
- Implement query caching
- Monitor query performance
-
Preparation
- Take full backup
- Schedule maintenance window
- Prepare new infrastructure
-
Setup
- Deploy new cluster
- Configure replication
- Test failover procedures
-
Migration
- Stop application writes
- Final data sync
- Update application configuration
- Switch to new cluster
- Verify all systems
-
Cleanup
- Decommission old instance
- Update monitoring
- Document changes
- Regular health checks
- Automated failover testing
- Performance monitoring
- Capacity planning
- Use read replicas for reporting
- Implement circuit breakers
- Handle replica lag gracefully
- Test with realistic data volumes
- Regular security updates
- Access control reviews
- Audit log analysis
- Incident response planning
- Daily health checks
- Weekly performance reviews
- Monthly security updates
- Quarterly capacity planning
- 24/7 monitoring alerts
- On-call rotation
- Incident response plan
- Communication procedures
This scalable architecture provides the foundation for handling 1 million users while maintaining high performance and availability. The combination of read replicas, connection pooling, and intelligent routing ensures that the Vesting Vault platform can scale efficiently as user demand grows.
Regular monitoring, testing, and optimization are essential to maintain optimal performance. The provided tools and procedures enable the operations team to manage the database cluster effectively.