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.
No export handy? See a sample report.
At your laptop? Check your own workload.
- PostgreSQL 16–18
- No code changes
- v0.7.0
- Source on GitHub
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.”
How it works
Your app code doesn't change.
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 →
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
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.
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.
Read-heavy apps
Dashboards, listings and reports that repeat the same joins and aggregates. The more queries a page runs, the bigger the gain.
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.
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.
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.
No export handy? See a sample report
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
Prefer email? [email protected]
Already curious? How pilots work
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.