Redis vs Postgres: When You Actually Need Both, Measured
Sagar Tayde · · 8 min read
Redis vs Postgres is usually framed as a fight, but most production apps run both: Postgres as the database that keeps the truth, Redis as fast memory beside it. The real question is whether your app needs the second one yet. This guide is for developers deciding whether to add Redis to a Postgres app, or to drop it. We measured the same key-value operations on both, on the same laptop, and the result surprises many people: for a single lookup, Postgres is already fast. Redis earns its place under heavy load and for other jobs, which we list with the numbers.
On this page
- What each one is for
- We measured the same operations on both
- What the numbers really say
- Where Redis earns its place
- What Postgres can do instead
- A simple decision guide
- Running both without trouble
- FAQ
What each one is for
| Postgres | Redis | |
|---|---|---|
| Role | The system of record | Fast working memory |
| Data lives | On disk, cached in memory | In memory, optionally saved to disk |
| Durability | Every committed write survives a crash | The last moments before a crash can be lost |
| Queries | SQL: joins, filters, aggregates, transactions | Lookups by key, plus data-structure commands |
| Built-in expiry | No | Yes, per key |
| Strong at | Relationships, correctness, reporting | Counters, sessions, rate limits, queues, pub/sub |
Neither replaces the other well. Postgres is a poor place for data that should vanish on a timer; Redis is a poor place for anything you cannot afford to lose or need to query in new ways later.
We measured the same operations on both
Setup. On one laptop: Postgres 16.15 running natively on Windows, and Redis 8.10.3 in a Linux
virtual machine (WSL2), both loaded with 100,000 keys holding 100-byte values (a Postgres table with a
text primary key). The client was Node.js 24 with ioredis and pg, one connection each, sending 5,000
operations one after another with random keys, after a warm-up. We repeated each test three times; the
table shows the third run, and the other two were within a few hundredths of a millisecond. Measured 7
November 2026.
| Operation | Median | 99th percentile |
|---|---|---|
Redis PING (round trip only) |
0.306 ms | 0.794 ms |
Redis GET |
0.335 ms | 0.687 ms |
Redis SET |
0.334 ms | 0.717 ms |
Postgres SELECT 1 (round trip only) |
0.123 ms | 0.330 ms |
Postgres SELECT v FROM kv WHERE k = $1 |
0.151 ms | 0.372 ms |
| Postgres upsert, normal table | 0.315 ms | 0.629 ms |
Postgres upsert, UNLOGGED table |
0.174 ms | 0.408 ms |
One caution on reading this table: Redis sat behind a virtual machine boundary and Postgres did not, so Redis’s round trip was about 0.2 ms slower before it did any work. That is why we include a do-nothing command for each. Compare each operation with its own round trip, not the two databases’ raw numbers.

Memory for the same data: Redis used 17.9 MB of RAM for the 100,000 keys; the Postgres table and its index took 18.8 MB, on disk and cached in memory when used often.
What the numbers really say
Subtract each server’s round trip and you see the work itself:
- A primary-key read costs Postgres about 0.03 ms. Redis’s
GETcost about the same beyond its round trip. For “fetch the row with this ID” at low concurrency, a cache in front of Postgres barely changes how long one request waits. We measured latency with one connection, not capacity: under many concurrent clients Postgres spends far more CPU per lookup than Redis, and that is where a cache in front of it often pays off. We did not measure that here. - A durable write costs Postgres about 0.19 ms more than its round trip, because it records the
change safely before answering. That cost depends heavily on the disk; ours was a laptop SSD, and
cloud volumes are often slower. The same upsert on an
UNLOGGEDtable, which skips that step, cost about 0.05 ms. Redis writes were close to its round trip. - The network dwarfs all of it. From a server in Mumbai we measured about 9 ms to a store in the Mumbai region at another provider (on the same private network it is far less) and about 86 ms to Singapore (see our free Redis hosting comparison). A 9 ms round trip is about fifty times the slowest database work we measured, so the region matters far more than which database it is.
So “put Redis in front of Postgres to make reads fast” is clearly right for expensive queries and for high-concurrency read load, and much less important for occasional simple lookups by key.
Where Redis earns its place
These are the jobs where Redis is clearly the better tool, even when Postgres is fast:
- Heavy read load. Many concurrent requests for the same hot data cost Postgres far more CPU than Redis. A cache lets the database spend its capacity on queries only it can answer.
- Expensive results. A query that joins five tables and takes 300 ms is worth caching. Compute once, store the result with an expiry, serve it in a millisecond.
- Data that should disappear on a timer. Sessions, one-time codes, rate-limit windows. Redis deletes expired keys for you; Postgres needs a cleanup job. Our Redis TTL guide covers the traps.
- Very frequent small writes to the same rows. Counters, view counts, “last seen” timestamps. In
Postgres every update writes a new row version and must later be cleaned up; a busy counter becomes a
hot spot. In Redis it is one
INCR. - Background job queues. Libraries such as BullMQ, Sidekiq and Celery run on Redis. See our Redis job queue guide.
- Fan-out to many servers. Pub/Sub delivers a message to every connected instance, which is how chat and live dashboards stay in sync across servers.
- Protecting the database from spikes. A cache absorbs a burst of identical reads so they never reach Postgres.
What Postgres can do instead
If you would rather run one system for now, Postgres covers more than people expect:
UNLOGGEDtables for cache-like data. Faster writes, as measured above, at the cost of being emptied after a crash. The CREATE TABLE documentation describes the trade-off.SELECT ... FOR UPDATE SKIP LOCKEDturns a table into a reliable job queue that many workers can pull from without stepping on each other.LISTEN/NOTIFYsends simple notifications between connected clients.- A scheduled cleanup (
DELETE ... WHERE expires_at < now()) stands in for key expiry at modest volumes.
Each of these is a reasonable starting point. Each becomes awkward at high volume, which is usually the moment to add Redis.
A simple decision guide
- New app, modest traffic: start with Postgres alone. Add Redis when you have a specific job from the list above, not “for speed”.
- Slow pages: find the slow query first. If it is a lookup by key, add an index. If it is genuinely expensive, cache its result in Redis.
- Sessions: fine in Postgres at low volume; move them to Redis with an expiry when they become a large share of your writes.
- Background jobs: Redis with a queue library, or
SKIP LOCKEDin Postgres if you want one system. - Anything you cannot lose: Postgres, always.
Running both without trouble
- Postgres is the source of truth. Anything in Redis should be rebuildable from Postgres, or be something you can afford to lose.
- Set expiries on cached data, so a missed invalidation corrects itself.
- Invalidate on write. When you update a row, delete its cache key in the same code path.
- Keep them together. Put both in the same region as your app; a cache in another region is slower than no cache.
On Voroa, a managed PostgreSQL database and a Redis-compatible key value store run side by side in Mumbai, next to the web services you deploy, each with a free size to start. The store’s details are in the Key Value guide, and its sizes on the managed Redis page.
FAQ
Is Redis faster than Postgres? For the work itself, both handled a single lookup by key in about 0.03 ms in our one-connection test; under heavy concurrent load Redis serves many more lookups per CPU core, which we did not measure. Redis is faster for writes that do not need to be durable and for counters. The network round trip, not the database, set most of the time.
Should I use Redis as my main database? Usually not. It keeps data in memory, can lose the last moments before a crash, and cannot run the queries a relational database can. Use it beside Postgres.
Can Postgres replace Redis?
For small apps, often yes: unlogged tables for cache-like data, SKIP LOCKED for queues, LISTEN and
NOTIFY for notifications. At high volumes Redis is simpler and faster.
Do I need Redis for sessions? Not at first. Postgres handles sessions fine at modest traffic. Redis helps when session writes become a large share of your database load, and its expiry clears old sessions automatically.
How do I keep Redis and Postgres in sync? Treat Postgres as the truth, write there first, then delete or update the Redis key. Give cached keys an expiry so any missed update corrects itself.
Which is cheaper to run? For the same data, our test used similar memory in both. Redis must hold everything in memory, while Postgres keeps data on disk and caches what is used, so large datasets are usually cheaper in Postgres.
Measured 7 November 2026 with Postgres 16.15 and Redis 8.10.3 on a laptop. Found something out of date? Write to support@getvoroa.com.