ThisCalculator

Everyday

When to Scale PostgreSQL: Signs & Steps

Updated · Standard formula, shown below

When to Scale PostgreSQL: Signs & Steps

This guide helps you identify when a vanilla PostgreSQL deployment is reaching its limits and needs scaling. You’ll learn the key performance indicators to watch, how to interpret them, and the practical steps to take before your database becomes a bottleneck. No prior scaling experience is needed, just access to your PostgreSQL instance and basic monitoring tools.

What You’ll Need

  • Access to your PostgreSQL server (psql or a GUI like pgAdmin)
  • Basic knowledge of SQL queries
  • Optional: monitoring tools like pg_stat_statements, Prometheus, or Grafana (but not required)

Step-by-Step

  1. Check CPU and memory usage. Run top or htop on the server. If CPU is consistently above 80% during normal load, or memory usage is near 100% with swapping occurring, your instance may be undersized. Also check PostgreSQL’s shared_buffers setting (typically 25% of RAM) to see if it’s adequate.
  2. Monitor connection counts. Run SELECT count(*) FROM pg_stat_activity; to see active connections. If you’re hitting the max_connections limit (default 100), clients will get errors like “too many connections.” This is a common sign you need to scale up or pool connections.
  3. Watch for slow queries. Enable pg_stat_statements (add to shared_preload_libraries and restart) to track query execution times. Look for queries that take more than a few hundred milliseconds during normal load. If slow queries are frequent, your data may be too large for indexes or the server is undersized.
  4. Check disk I/O and storage. Use iostat or pg_stat_user_tables to see if reads/writes are high. If disk latency is consistently high (e.g., >20ms) or you’re running out of storage space, scaling is needed. Also check if your table bloat is excessive (using pgstattuple extension).
  5. Examine replication lag (if applicable). In a primary/replica setup, run SELECT now() - pg_last_xact_replay_timestamp() AS lag; on the replica. If lag grows steadily, the replica can’t keep up, indicating you need a stronger replica or a different replication method.
  6. Review cache hit ratio. Run SELECT sum(blks_hit) / (sum(blks_hit) + sum(blks_read)) AS hit_ratio FROM pg_stat_database;. If it’s below 95%, your working set doesn’t fit in memory, and scaling up RAM or adding replicas can help.
  7. Decide on scaling strategy. If you see issues, choose: scale up (increase CPU/RAM/disk on the same server) for vertical growth, or scale out (add read replicas, use partitioning, or move to a distributed solution) for horizontal growth. Start with the simplest solution that addresses the bottleneck.

Common Mistakes

  • Scaling based on average load — PostgreSQL can handle spikes, but sustained high load is the real problem. Look at peak usage, not just averages.
  • Ignoring query optimization — Sometimes a single slow query is the issue, not the server. Always tune queries and indexes before scaling.
  • Over-provisioning — Adding more resources than needed wastes money and can hide underlying inefficiencies.
  • Not monitoring before scaling — You need baseline data to know if scaling actually helped. Set up monitoring before making changes.
  • Scaling writes with read replicas — Read replicas only help with read-heavy workloads. For write-heavy workloads, you need to scale up or partition.

Tips

  • Use pg_stat_statements to identify the heaviest queries and optimize them first — this often delays the need to scale.
  • Consider connection pooling (e.g., PgBouncer) before scaling, as it reduces connection overhead.
  • Regularly run VACUUM and ANALYZE to keep statistics fresh and avoid table bloat.
  • Set up alerts for key metrics like CPU, memory, disk, and connection count so you know when to act.
  • Test scaling changes in a staging environment first to avoid surprises in production.

Troubleshooting

  • If you scale up but still see issues: Check if the bottleneck is actually network or application-level, not the database. Use EXPLAIN ANALYZE on slow queries to see if they’re doing full table scans.
  • If you hit max_connections: Increase max_connections (but beware of memory usage), or better, implement connection pooling. Also check for leaked connections in your application.
  • If disk I/O is high: Consider moving to SSD if you’re on HDD, or add more RAM to increase cache. Also check for missing indexes causing excessive reads.
  • If replication lag is high: Check the replica’s hardware — it may be slower than the primary. Also consider using synchronous replication for critical data, but note it adds latency.
  • If you’re unsure what to do: Start with pg_tune (a tool that suggests configuration based on hardware) to get a baseline, then re-evaluate after a week of monitoring.

Frequently Asked Questions

How do I know if my PostgreSQL is “vanilla”?

Vanilla means you’re using the standard PostgreSQL distribution without extensions like Citus or TimescaleDB. If you’re using the default config and no major extensions, it’s vanilla.

Can I scale PostgreSQL without downtime?

Yes, for read replicas you can add them with minimal downtime. For vertical scaling (adding RAM/CPU), you may need to restart the server, but you can use tools like pg_repack to minimize downtime.

What’s the difference between scaling up and scaling out?

Scaling up means increasing the resources of a single server (e.g., more RAM, faster CPU). Scaling out means adding more servers (e.g., read replicas, sharding). Scaling up is simpler but has limits; scaling out is more complex but offers more capacity.

Is it better to scale or optimize first?

Always optimize first. Many performance issues are due to poor queries or missing indexes. Optimize until you have a clear bottleneck that can’t be fixed with tuning, then scale.

How often should I check these metrics?

At least weekly for a production database, but daily if you’re experiencing issues. Use automated monitoring to get alerts for critical thresholds.

What is a good cache hit ratio?

Above 99% is ideal, but 95% is acceptable for most workloads. If it’s below 95%, your working set doesn’t fit in memory, and you should consider scaling up RAM or adding replicas.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.