Scaling Postgres for Startups: What to Do Before You Shard
Sharding is the last resort, not the first move. A single well-tuned Postgres instance takes most startups much further than they expect. Here's the order of operations we follow before splitting the database.
Step 1: Fix Your Queries First
Most "database is slow" problems are query problems:
- Turn on
pg_stat_statementsand find your top 10 slowest queries by total time - Add the indexes those queries actually need — composite indexes in the right column order
- Kill N+1 patterns at the application layer before blaming the database
- Use
EXPLAIN ANALYZEand read it, don't guess
Step 2: Connection Management
Postgres handles connections expensively. A few hundred direct connections will bring it to its knees.
- Put PgBouncer in front in transaction-pooling mode
- Right-size your pool — more connections is not more throughput
- Separate read and write pools so analytics queries don't starve writes
Step 3: Read Replicas
When reads dominate, scale them out before touching writes:
- Route reporting and read-heavy endpoints to replicas
- Accept and design for replication lag — read-your-writes where it matters
- Keep the primary focused on transactional writes
Step 4: Partitioning
When a single table gets huge, partition before you shard:
- Range-partition time-series tables by month
- Drop old partitions instead of running massive DELETEs
- Keep indexes per-partition small and fast
Step 5: Only Then, Consider Sharding
If you have exhausted the above and still hit limits, shard by a stable tenant key — and accept the operational complexity that comes with it.
The Numbers
A properly tuned single Postgres instance comfortably handles tens of thousands of transactions per second for most B2B SaaS workloads. Sharding adds complexity that most startups never actually need.