Performance Tuning
After this lesson, you will be able to:
- Optimize PostgreSQL configuration for an HA cluster.
- Setup connection pooling with PgBouncer.
- Implement load balancing with HAProxy.
- Scale reads with multiple replicas.
- Tune queries and indexes.
- Monitor and troubleshoot performance issues.
1. PostgreSQL Configuration Tuning
1.1. Memory settings
shared_buffers
effective_cache_size
work_mem
maintenance_work_mem
1.2. Checkpoint tuning
1.3. WAL settings
1.4. Query planner
1.5. Connection settings
1.6. Autovacuum tuning
1.7. Logging for performance
1.8. Apply configuration
2. Connection Pooling with PgBouncer
2.1. Why connection pooling?
Problem without pooling:
Solution with PgBouncer:
2.2. Install PgBouncer
2.3. Configure PgBouncer
Pool modes explained:
2.4. User authentication
2.5. Start PgBouncer
2.6. Test connection
2.7. Application configuration
2.8. Monitor PgBouncer
3. Load Balancing with HAProxy
3.1. HAProxy architecture
3.2. Install HAProxy
3.3. Configure HAProxy
Configuration explained:
- Port 5000: Write traffic → Primary node
- Health check: Patroni REST API port 8008
- If primary fails, backup (replica) can take over
- Backup = only used if primary down
- Port 5001: Read traffic → Replicas (round-robin)
- Health check:
/replicaendpoint - Primary as backup (if all replicas down)
- Load balanced across healthy replicas
- Health check:
- Port 7000: HAProxy stats page
3.4. Patroni REST API endpoints for health checks
3.5. Start HAProxy
3.6. Test load balancing
3.7. Application usage
3.8. Monitor HAProxy
4. Read Scaling Strategies
4.1. Add more read replicas
4.2. Cascading replication
4.3. Application-level read routing
4.4. Monitoring read distribution
5. Query Optimization
5.1. Enable pg_stat_statements
5.2. Identify slow queries
5.3. EXPLAIN ANALYZE
5.4. Create indexes
5.5. Index maintenance
6. Best Practices
✅ DO
- Start with conservative settings: Tune incrementally.
- Monitor before and after: Measure impact of changes.
- Use connection pooling: Essential for web applications.
- Separate read and write traffic: Scale reads independently.
- Create appropriate indexes: Based on query patterns.
- Regular VACUUM: Keep table statistics updated.
- Use EXPLAIN ANALYZE: Understand query execution.
- Set statement_timeout: Prevent runaway queries.
- Monitor pool saturation: Scale PgBouncer if needed.
- Test configuration changes: In staging first.
❌ DON'T
- Don't over-allocate work_mem: Multiply by max connections!
- Don't create too many indexes: Slow down writes.
- Don't ignore autovacuum: Will cause bloat.
- Don't skip connection pooling: Connection overhead hurts.
- Don't use session pooling: Transaction mode better.
- Don't forget to analyze: Stale statistics = bad plans.
- Don't tune blindly: Understand what you're changing.
- Don't set shared_buffers too high: >25% RAM wasteful.
7. Lab Exercises
Lab 1: PostgreSQL tuning
Tasks:
- Benchmark current performance with pgbench.
- Tune memory settings (
shared_buffers,work_mem). - Tune checkpoint settings.
- Re-run pgbench and compare results.
- Document improvements.
Lab 2: Setup PgBouncer
Tasks:
- Install PgBouncer on primary node.
- Configure transaction pooling.
- Update application to use PgBouncer.
- Monitor connection counts (before/after).
- Load test and measure improvement.
Lab 3: HAProxy load balancing
Tasks:
- Install and configure HAProxy.
- Setup write and read endpoints.
- Test routing (write→primary, read→replicas).
- Simulate failover, verify HAProxy adapts.
- Monitor traffic distribution.
Lab 4: Query optimization
Tasks:
- Enable
pg_stat_statements. - Run sample workload.
- Identify top 10 slowest queries.
- Use
EXPLAIN ANALYZEto understand plans. - Create indexes to optimize.
- Measure improvement.
8. Summary
Performance Tuning Checklist
- Tune
shared_buffers(25% RAM) - Set
effective_cache_size(50-75% RAM) - Adjust
work_memcarefully - Optimize checkpoints
- Lower
random_page_costfor SSD - Enable
pg_stat_statements - Setup PgBouncer connection pooling
- Configure HAProxy load balancing
- Create indexes based on queries
- Monitor and iterate
Key Concepts
✅ Connection Pooling: Reduces connection overhead dramatically.
✅ Load Balancing: Distributes read traffic across replicas.
✅ Read Scaling: Add replicas to handle read load.
✅ Query Optimization: Indexes + EXPLAIN ANALYZE.
✅ Configuration Tuning: Balance memory, I/O, and CPU.
Next Steps
Lesson 19 will cover Logging and Troubleshooting:
- PostgreSQL log analysis
- Patroni log interpretation
- etcd troubleshooting
- Common issues and solutions
- Debug techniques and tools