Smart read replica for PostgreSQL

Cache your hottest reads.
Keep them fresh automatically.

A drop-in Postgres proxy that caches only the data your queries read and keeps it fresh with logical replication. You change one connection string.

Benchmarked by engineers outside PgCache

Two engineers who don't work for us ran their own benchmarks.

Point lookup by id

0.3 ms 0.3 ms

Top products, 10M-row join

2.9 s 0.6 ms

SaaS dashboard page, 8 queries

32.2 ms 5.1 ms

Requests per second, origin at its limit

110 1,370

Measured by Hulunlante Worku and Leonardo Benedet. Neither was paid. Leonardo is one of our design partners. Benchmarks →

“I’m extremely excited about PgCache. I think in the future it will become a standard tool in a backend stack for Postgres.”
Leonardo Benedet DBA, ContaAzul · design partner

How it works

Your app code doesn't change.

1

Run PgCache next to your database

One command starts it in Docker to try it; the same image runs in production. Your database needs logical replication turned on. Try it in one command →

2

Change one connection string

Point your app at PgCache. Writes pass straight through to your database.

# Before
DATABASE_URL=postgres://user@replica:5432/myapp

# After
DATABASE_URL=postgres://user@pgcache:5432/myapp
3

Hot reads come from cache

PgCache caches the working set your queries touch and keeps it fresh as rows change. Cold data is never copied.

Your App
→
PgCache
→
PostgreSQL

PgCache answers cacheable reads from its cache and forwards writes and all other queries to your database.

Will PgCache work for you?

What PgCache handles well, and its current limits.

Works best

Read-heavy apps

Dashboards, listings and reports that repeat the same joins and aggregates. The more queries a page runs, the bigger the gain.

Fresh like a replica

Consistency

Each connection sees its own writes. Other connections see changes after replication lag. READ COMMITTED transactions are served from cache; REPEATABLE READ and SERIALIZABLE go to your database.

Passes through

Writes and volatile queries

Writes, and queries with now() or random() in a WHERE or JOIN, go straight to your database. Primary-key lookups that are already fast gain little.

Not yet

Row-level security and some schema changes

PgCache doesn't apply RLS policies yet, so it doesn't fit reads that depend on them. Dropping a table, or attaching a partition that already holds rows, can serve stale results.

PostgreSQL 16, 17 and 18, with any driver or ORM that speaks the Postgres wire protocol. Full compatibility notes

Not sure where your own queries land? Run the Fit Analyzer on your workload.

Get started with PgCache

Step 1

Check your workload

Paste a pg_stat_statements export or a Postgres log. In about a minute you see which of your queries PgCache would serve from cache.

Check your workload

Runs in your browser. Nothing is uploaded.

Step 2

Get a free workload review

30 minutes with the founders, by video or email. Bring your Fit report or your Postgres problem.

  • What PgCache would serve and save on your workload
  • If it fits, a pilot with hands-on help
Book a free review →

Free. Pick any open time on our calendar.

Run it yourself: Source on GitHub · Try it in one command

Not ready yet? Get updates by email.

No spam. Unsubscribe anytime.