All posts
·6 min read

Scaling Postgres for Cartnest

PostgreSQLDistributed SystemsBackend

Cartnest started as a straightforward FastAPI backend with a single Postgres instance. It worked — until it didn't. As I modelled real trading traffic, reads on the product catalog and transaction history became the bottleneck long before writes did.

Cartnest — where the scaling challenges began.
Cartnest platform

Cartnest — where the scaling challenges began.

Reads and writes want different things

The first realization was that a single node forces reads and writes to compete for the same resources. Splitting them apart — a primary for writes, replicas for reads — let each scale on its own terms.

app  ->  primary (writes)
     ->  replica 1 (reads)
     ->  replica 2 (reads)

Fragmenting the heavy tables

Replicas help reads, but they don't shrink a hot table. For the transactions table I introduced fragmentation so that no single partition carried the whole load.

  • Partition by time so recent data stays hot and small
  • Keep foreign keys local to a fragment where possible
  • Measure before and after — never assume the split helped

Distributed systems don't make problems disappear. They move them somewhere you can reason about.

What I'd do differently

I'd reach for observability first. Half of the wins came from finally seeing which queries were slow, not from the architecture itself.