Migrating production infrastructure? Get up to ₹10,000 in migration credits. Apply now
voroaBlog
Key Value

Redis vs Postgres: When You Actually Need Both, Measured

· · 8 min read

Redis vs Postgres, measured: per-operation latency for lookups, writes and counters, and when to use both

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

Advertisement

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.

Bar chart: time each server spent on the work beyond its own round trip - Redis GET about 0.03 ms, Postgres primary-key SELECT about 0.03 ms, Postgres unlogged upsert about 0.05 ms, Postgres normal upsert about 0.19 ms

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:

  1. A primary-key read costs Postgres about 0.03 ms. Redis’s GET cost 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.
  2. 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 UNLOGGED table, which skips that step, cost about 0.05 ms. Redis writes were close to its round trip.
  3. 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:

  • UNLOGGED tables 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 LOCKED turns a table into a reliable job queue that many workers can pull from without stepping on each other.
  • LISTEN / NOTIFY sends 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 LOCKED in 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.

Advertisement