Skip to content

Redis vs PostgreSQL

1. Decision

Choose Redis as an in-memory datastore for sub-millisecond ephemeral caching, high-velocity session management, rate limiting, and real-time leaderboards; choose PostgreSQL as a primary relational disk-backed system of record for structured domain entities, complex queries, and ACID transactional durability.


2. 30-Second Answer

Redis is an in-memory, single-threaded key-value/data-structure store optimized for microsecond read/write latencies (\(<1\text{ms}\)) and high throughput (\(>100\text{k QPS}\) single node). It supports specialized data structures (Strings, Hashes, Lists, Sets, Sorted Sets, HyperLogLogs, Streams, Bitmaps). PostgreSQL is a persistent, disk-backed relational database providing ACID transactions, MVCC, and complex querying. Redis is primarily used as a caching layer, buffer, or ephemeral state store, whereas PostgreSQL acts as the authoritative source of truth. Using Redis as a primary database carries data loss risks if persistence (RDB/AOF) is misconfigured or RAM limits are reached.


3. Decision Matrix

Option Best For Avoid When Latency Scalability Consistency Operational Complexity
Redis Caching, session store, rate limit counters, pub/sub, real-time leaderboards Large datasets exceeding RAM cost limits, complex multi-entity joins, primary source of truth Sub-millisecond (<1ms) in-memory Vertical RAM; Horizontal via Redis Cluster (16384 hash slots) Single-key immediate; Asynchronous primary-replica replication Low (Standalone); Medium (Cluster/Sentinel)
PostgreSQL Primary storage, complex queries, financial transactions, JSON + SQL relations Sub-millisecond SLAs, raw write throughput exceeding disk I/O limits Low (<5ms disk page hit) Vertical Scale; Read Replicas; Sharding Strict ACID (Serializable, Repeatable Read) Medium

4. Selection Rules

Requirement Best Choice Rationale / Example
Sub-Millisecond Read Latency (<1ms) Redis Pure in-memory data access eliminates disk I/O overhead completely
Primary System of Record / Durability PostgreSQL Write-Ahead Log (WAL) guarantees strict crash-recovery ACID durability
Real-Time Ranked Leaderboard Redis Sorted Sets (ZADD, ZREVRANGE) execute score operations in \(O(\log N)\)
Complex Multi-Table SQL Joins PostgreSQL Optimized query planner for complex relational schemas and foreign keys
Distributed Atomic Rate Limiting Counter Redis INCR + EXPIRE in atomic Redis Lua script prevents concurrency races
Geospatial & Vector Hybrid Relational Queries PostgreSQL PostGIS and pgvector integrate spatial/vector search natively with SQL

5. Tradeoffs

  1. In-Memory RAM Speed vs Disk-Backed Capacity Economics
  2. Gain (Redis): Microsecond performance for all read and write operations.
  3. Lose (Redis): Extremely expensive per gigabyte compared to NVMe SSD storage; total dataset size bounded by node RAM.
  4. Data Structure Operability vs SQL Declarative Expressiveness
  5. Gain (Redis): Rich native primitives (Sets, Sorted Sets, Bitmaps) matching application memory structures.
  6. Lose (Redis): No declarative query language; queries must be explicitly coded via data structure commands or Lua scripts.
  7. Single-Threaded Event Loop Execution vs Multi-Process MVCC Concurrency
  8. Gain (Redis): Zero lock contention; all single-key commands execute atomically without race conditions.
  9. Lose (Redis): Long-running \(O(N)\) operations (KEYS *, huge HGETALL) block the entire event loop, freezing all client traffic.
  10. Persistence Options vs Native Transactional WAL
  11. Gain (Redis): Flexible persistence modes (RDB snapshots, AOF log, or pure cache mode).
  12. Lose (Redis): Async persistence risks losing seconds of data during power loss/crash unless using fsync always (which degrades performance).
  13. Cache Eviction Policies vs Durable Retention
  14. Gain (Redis): Automatic memory management via eviction policies (volatile-lru, allkeys-lru).
  15. Lose (Redis): Risk of unexpected data eviction if configured improperly.

6. Interview Counter Questions

  1. Why shouldn't you use Redis as your primary system-of-record database?
  2. How does Redis single-threaded architecture achieve 100,000+ QPS per instance?
  3. How do Redis persistence options (RDB vs AOF) compare, and what are their performance tradeoffs?
  4. How do you implement a distributed lock in Redis (Redlock algorithm vs single instance)?
  5. What happens when Redis reaches its maxmemory limit, and how do eviction policies work?
  6. How does Redis Cluster partition keys using Hash Slots (16,384 slots)?
  7. How do you prevent cache stampedes (thundering herd) when a key in Redis expires?
  8. How does Redis Lua scripting guarantee atomicity, and what is its major performance pitfall?
  9. When would you use Redis Streams instead of PostgreSQL LISTEN/NOTIFY or Apache Kafka?
  10. How do you maintain data consistency between PostgreSQL primary database and Redis cache?

7. Gold Standard Answers

  1. RAM is volatile and expensive. Redis asynchronous persistence (RDB/AOF) trades durability for latency; hardware crashes can lose un-flushed writes. Redis lacks relational constraints, foreign keys, and complex transactional isolation required for core domain data.
  2. Redis uses an efficient non-blocking I/O multiplexing event loop (epoll/kqueue) operating entirely in RAM. Because data lives in memory, processing commands takes nanoseconds, avoiding context switching and thread locking overhead.
  3. RDB (Redis Database) takes compact point-in-time binary snapshots (fast restarts, but potential data loss between snapshot intervals). AOF (Append-Only File) logs every write command (higher durability, but larger file size and slower startup). Standard practice: use both.
  4. Single instance: SET resource_key my_random_token NX PX 30000 deleted via Lua script verifying token. Redlock uses 5 independent Redis nodes; lock acquired if majority (3/5) grant lock within drift timeout. Redlock is controversial due to clock drift assumptions.
  5. Redis executes the configured maxmemory-policy: noeviction (returns errors on writes), allkeys-lru / volatile-lru (evicts least recently used keys), or allkeys-lfu (evicts least frequently used keys).
  6. Redis Cluster divides key space into 16,384 logical Hash Slots. Partition Key slot calculated via CRC16(key) mod 16384. Shards own subsets of slots. Hash tags {user100}:profile force related keys into the same slot for multi-key operations.
  7. Use Probabilistic Early Expiration (XFetch algorithm), distributed locks (mutex around DB fetch), or background worker refresh jobs before TTL expiration to prevent simultaneous cache misses hitting Postgres.
  8. Lua scripts execute atomically within the single-threaded event loop, blocking all other incoming commands until execution finishes. Pitfall: slow or infinite loops in Lua scripts freeze the entire Redis server instance.
  9. Use Redis Streams for lightweight, low-latency log-based message queues with consumer groups when data retention fits in RAM. Use Kafka when message persistence, replayability across weeks, and terabyte scale are required.
  10. Use Cache-Aside pattern with invalidation: Write to Postgres DB first, then delete key from Redis. Alternatively, use Change Data Capture (Debezium CDC) reading Postgres WAL to asynchronously invalidate Redis keys.

8. Common Mistakes

  • Running KEYS * in a production Redis instance, blocking the single-threaded event loop and dropping all application traffic.
  • Using Redis as a primary database without configuring AOF persistence or secondary replica failover.
  • Updating Redis cache before writing to PostgreSQL DB, creating permanent cache inconsistency when DB writes fail.
  • Storing massive multi-megabyte payloads in a single Redis key, causing network memory bottlenecks.
  • Forgetting to set a TTL on dynamic cache keys, leading to uncontrolled RAM growth and memory eviction crashes.

9. Keywords

Redis, PostgreSQL, In-Memory, Event Loop, Single-Threaded, Hash Slots, RDB, AOF, Redlock, Lua Scripting, maxmemory, Eviction Policy, LRU, LFU, Cache-Aside, Debezium CDC.


10. Cheat Sheet

  • Core Difference: Redis = In-memory sub-millisecond state/cache; PostgreSQL = Disk-backed ACID relational system of record.
  • Concurrency: Redis = Single-threaded I/O multiplexing event loop; PostgreSQL = Multi-process MVCC concurrency model.
  • Latency: Redis < 1ms; PostgreSQL 2-10ms (page cache hits vs NVMe disk I/O).
  • Data Primitives: Redis = Strings, Hashes, Lists, Sets, Sorted Sets (ZADD), Streams, HyperLogLogs.
  • Cluster Sharding: Redis Cluster divides key space into 16,384 Hash Slots; use {hashtag} for multi-key atomic ops.
  • Consistency Pattern: Write to Postgres first -> Invalidate Redis key second (Cache-Aside pattern).

11. Related Decisions