AlgoInsight

Free lesson · System Design Advanced

Memcached vs Redis - The Honest Comparison

Hard10 min readsystem-designadvanced

If you ask the internet "should I use Memcached or Redis?", the answer is almost always Redis. Redis has more features, more data structures, more community mindshare. Stack Overflow answers default to Redis. Tutorials default to Redis. Cloud providers push Redis. The conversation feels settled.

It's not. The "just use Redis" answer is correct for about 70% of use cases - the ones where you need sorted sets, pub/sub, persistence, Lua scripting, or any of Redis's richer data structures. But for the remaining 30% - where you need a pure, fast, dead-simple cache - Memcached is not just an acceptable alternative. It's often the better choice. And at massive scale, the difference between "acceptable" and "better" translates to millions of dollars in infrastructure cost and thousands of hours of operational complexity.

This lesson is the comparison I wish someone had given me before I defaulted to Redis on a project that would have been better served by Memcached.

The Fundamental Design Difference

graph TD
    subgraph "Memcached: A Cache"
        MC_DESIGN["Design philosophy:<br/>──────────────────<br/>In-memory hash table.<br/>That's it.<br/><br/>Keys map to byte blobs.<br/>No data structures.<br/>No persistence.<br/>No replication.<br/>No scripting.<br/><br/>The server is simple.<br/>The client is smart.<br/>(client-side sharding,<br/>consistent hashing,<br/>serialization)"]
        
        MC_THREAD["Threading model:<br/>──────────────────<br/>Multi-threaded from birth.<br/><br/>One listener thread accepts<br/>connections. Worker threads<br/>handle requests in parallel.<br/><br/>Uses ALL CPU cores on the<br/>machine naturally.<br/><br/>A 16-core server runs 16<br/>parallel request handlers."]
    end
    
    subgraph "Redis: A Data Structure Server"
        REDIS_DESIGN["Design philosophy:<br/>──────────────────<br/>In-memory data structure store.<br/><br/>Strings, lists, sets, sorted sets,<br/>hashes, streams, bitmaps,<br/>HyperLogLog, geospatial indexes.<br/><br/>Persistence (RDB + AOF).<br/>Replication (leader-follower).<br/>Pub/Sub. Lua scripting.<br/>Transactions. Cluster mode.<br/><br/>The server is smart.<br/>The client is simple."]
        
        REDIS_THREAD["Threading model:<br/>──────────────────<br/>Single-threaded command<br/>execution (by design).<br/><br/>One thread processes all<br/>commands sequentially.<br/><br/>Redis 6+ added I/O threads<br/>for network read/write,<br/>but command execution<br/>is still single-threaded.<br/><br/>A 16-core server uses 1 core<br/>for commands. 15 cores idle."]
    end
This diagram contrasts the fundamental designs of Memcached and Redis. Memcached is a simple in-memory hash table - keys map to byte blobs with no data structures, persistence, or replication. The server is simple while the client handles sharding and serialization. Memcached is multi-threaded from birth, using all CPU cores naturally. Redis is a rich data structure server with strings, lists, sets, sorted sets, persistence, replication, scripting, and cluster mode. The server is smart while the client is simple. Redis uses single-threaded command execution - even on a 16-core server, only one core processes commands.

Important: The threading model is the single most important architectural difference. Memcached is multi-threaded. Redis is single-threaded for command execution. On a modern 16-core server, Memcached uses all 16 cores for request handling. Redis uses 1 core for command execution and leaves 15 idle (unless you run multiple Redis instances per server, which adds operational complexity). For pure cache workloads where every operation is a simple GET or SET, Memcached extracts more throughput from the same hardware.

The Honest Comparison Table

Dimension Memcached Redis Winner For Cache Workloads
Throughput (single server) 200K-600K ops/sec (multi-threaded, all cores) 100K-200K ops/sec per instance (single-threaded) Memcached
Latency ~100-200μs median ~100-200μs median Tie
Memory efficiency Slab allocator - some waste from slab classes but no per-key overhead Per-key metadata overhead (~56 bytes for a string key) Memcached (for simple values)
Data structures Byte blobs only (strings) Strings, lists, sets, sorted sets, hashes, streams, bitmaps, HyperLogLog Redis
Persistence None - pure volatile cache RDB snapshots + AOF append-only file Redis
Replication None built-in (client-side) Leader-follower replication Redis
Clustering Client-side consistent hashing Redis Cluster (server-side hash slots) Redis (operationally simpler)
Eviction LRU per slab class Multiple policies (LRU, LFU, random, TTL-based) Redis (more control)
Max value size 1 MB default (configurable) 512 MB Redis
Max key size 250 bytes 512 MB Redis
Protocol Text + binary protocol (simpler) RESP protocol (richer) Tie
Operational complexity Minimal - no config files, no persistence, no replication to manage Moderate - persistence config, replication lag, cluster resharding Memcached

Where Redis Wins (and You Shouldn't Use Memcached)

graph TD
    subgraph "Redis Territory"
        R1["You need data structures<br/>──────────────────<br/>Sorted sets for leaderboards<br/>Lists for queues<br/>Sets for unique visitors<br/>HyperLogLog for cardinality<br/><br/>Memcached can't do any of this<br/>without serializing/deserializing<br/>the entire structure on every op"]
        
        R2["You need persistence<br/>──────────────────<br/>Cache warming after restart<br/>Session store that survives reboot<br/>Any data you can't recompute<br/>from a backend database<br/><br/>Memcached loses everything<br/>on restart. By design."]
        
        R3["You need pub/sub or streams<br/>──────────────────<br/>Event broadcasting<br/>Change data capture consumers<br/>Real-time notifications<br/><br/>Memcached has no<br/>messaging capability"]
        
        R4["You need atomic operations<br/>on complex types<br/>──────────────────<br/>ZADD (add to sorted set)<br/>LPUSH/RPOP (queue operations)<br/>HINCRBY (hash field increment)<br/><br/>These are atomic in Redis<br/>In Memcached: GET, modify<br/>in client, SET - race condition"]
    end
This diagram shows where Redis clearly wins. If you need data structures like sorted sets for leaderboards or sets for unique visitors, Memcached can't do it without full serialization on every operation. If you need persistence so cached data survives restarts, Memcached loses everything by design. If you need pub/sub or streams for event broadcasting, Memcached has no messaging capability. If you need atomic operations on complex types like incrementing a hash field, Redis does it atomically while Memcached requires a get-modify-set cycle that creates race conditions.

Where Memcached Wins (and Redis Is Overkill)

graph TD
    subgraph "Memcached Territory"
        M1["Pure read-through / write-through cache<br/>──────────────────<br/>Cache database query results<br/>Cache API responses<br/>Cache rendered HTML fragments<br/><br/>Simple GET/SET with TTL<br/>No data structures needed<br/>No persistence needed<br/>(source of truth is the DB)<br/><br/>Memcached does this faster<br/>per dollar of hardware"]
        
        M2["Multi-core utilization matters<br/>──────────────────<br/>Your cache server has 32 cores<br/>Memcached uses all 32<br/>Redis uses 1 (or you run 32<br/>Redis instances with 32x<br/>the operational complexity)<br/><br/>At Facebook's scale:<br/>thousands of cache servers,<br/>each fully utilized"]
        
        M3["Operational simplicity matters<br/>──────────────────<br/>No persistence = no disk I/O spikes<br/>No replication = no replication lag<br/>No cluster = no resharding<br/>No config file = nothing to misconfigure<br/><br/>Memcached is a process that<br/>allocates memory and serves<br/>GET/SET requests. That's it.<br/>Ops teams love it."]
        
        M4["Memory efficiency for<br/>small values<br/>──────────────────<br/>Redis: ~56 bytes overhead per key<br/>Memcached: ~56 bytes per slab item<br/>but slab allocation means less<br/>fragmentation for uniform-sized values<br/><br/>1 billion 100-byte cached values:<br/>Redis: ~150 GB (value + overhead)<br/>Memcached: ~120 GB (slab efficiency)"]
    end
This diagram shows where Memcached wins. For pure read-through and write-through caching of database results or API responses - simple GET/SET with TTL where the database is the source of truth - Memcached does it faster per dollar. For multi-core utilization where a 32-core server should use all 32 cores, Memcached uses them all while Redis uses one. For operational simplicity where no persistence means no disk I/O spikes and no replication means no lag to monitor. And for memory efficiency with small uniform values where slab allocation reduces fragmentation.

Tip: The "Facebook test" is the quickest way to evaluate your use case. Facebook runs Memcached at enormous scale - billions of cache lookups per second across thousands of servers. Their workload is overwhelmingly "cache a database row by key, serve it until TTL expires, then fetch from the database again." If your workload looks like Facebook's - simple key-value lookups with a database as the source of truth - Memcached is proven at a scale that few Redis deployments have matched. If your workload requires data structures, persistence, or pub/sub, you're not in Facebook's use case and Redis is the right choice.

The Cost Argument at Scale

At small scale, the difference doesn't matter. A single Redis instance handles 100K ops/sec. A single Memcached instance handles 200K-600K ops/sec. Either one is enough for most applications. The cost difference is negligible.

At scale, it matters enormously. Consider a caching layer that needs to serve 10 million ops/sec:

Approach Servers Needed CPU Cores Used Annual Cost (r6g.2xlarge)
Memcached (multi-threaded, 8 cores each) ~20 servers 160 cores (all used) ~$70K
Redis (single-threaded, 1 core each) ~80 instances across ~10 servers 80 cores used, 80 idle ~
75K (more instances, more overhead)
Redis Cluster (6-node minimum per shard) Complex - shard count × 6 Significant overhead ~$200K+

These numbers are approximate, but the direction is consistent: for pure cache workloads, Memcached extracts more throughput per dollar because it uses all CPU cores on each server. Redis's single-threaded model means you either waste cores or run multiple instances per server with the associated operational overhead.

Interview: "Would you use Redis or Memcached for this caching layer?" is a question that tests nuance, not brand loyalty. The weak answer: "Redis, because it has more features." The strong answer: "It depends on the workload. If we need simple key-value caching with the database as the source of truth - like caching user profiles or product data - Memcached gives us better multi-core utilization and lower operational complexity. If we need sorted sets for ranking, pub/sub for invalidation, or persistence for cache warming, Redis is the right choice. For this specific design, the workload is [describe it], so I'd choose [justified choice]." The interviewer is testing whether you can match technology to requirements, not whether you know which one is more popular.

The Production War Story

At Amazon, I worked with a team that ran 60 Redis instances as a pure cache layer for product catalog data. Every Redis instance was a single-threaded process on a c5.4xlarge (16 cores). Each instance used 1 core. The other 15 cores were idle. The team ran 4 Redis instances per server to use 4 of the 16 cores - still wasting 75% of their CPU capacity.

The cache workload was exclusively GET and SET with a 5-minute TTL. No sorted sets, no lists, no pub/sub, no persistence. Every evicted key was re-fetched from DynamoDB. It was, in every sense, a pure caching workload that didn't use a single Redis feature beyond GET and SET.

We migrated to Memcached. Each c5.4xlarge server ran a single Memcached process that used all 16 cores. Throughput per server increased 4x. The fleet shrank from 15 servers (60 Redis instances) to 4 servers (4 Memcached instances). The operational surface area dropped from 60 processes to monitor, 60 replication streams (they had Redis replication enabled despite not needing persistence), and 60 alerting endpoints to 4 processes with zero replication.

Monthly infrastructure cost dropped by

8,000. Operational overhead dropped by roughly 10 hours per month in Redis cluster management, failover testing, and persistence tuning that was unnecessary for a volatile cache. The migration took 3 weeks - the hardest part was updating the client library from Jedis to a Memcached client, not any architectural change.

The lesson: Redis is a better product than Memcached. But "better product" doesn't mean "better choice for every workload." When your workload is pure caching, Memcached's simplicity and multi-threading are genuine advantages worth evaluating.

Six Takeaways

  1. Memcached is multi-threaded; Redis is single-threaded for command execution. For pure cache workloads, Memcached uses all CPU cores while Redis uses one. This is the most consequential architectural difference.

  2. Redis wins when you need data structures, persistence, or pub/sub. Sorted sets, lists, streams, Lua scripting, RDB/AOF persistence, leader-follower replication - Memcached has none of these. If your workload needs any of them, use Redis.

  3. Memcached wins for pure volatile caching at scale. When every operation is GET/SET with a TTL and the database is the source of truth, Memcached delivers more throughput per server at lower operational complexity.

  4. At small scale, the difference is negligible. A single Redis or Memcached instance handles more traffic than most applications need. The cost and throughput advantages of Memcached only matter at hundreds of thousands of ops/sec and above.

  5. Operational simplicity is an underrated advantage. No persistence means no disk I/O spikes. No replication means no replication lag. No cluster mode means no resharding. For a volatile cache, these "missing features" are actually reduced operational burden.

  6. Match the technology to the workload, not to the popularity. "Just use Redis" is the safe default but not always the right one. In a system design interview, articulating when Memcached is better demonstrates deeper understanding than always recommending Redis.

Exercises

Exercise: Starter: You're building a cache for a web application that stores rendered HTML fragments by page URL. The cache is purely volatile - fragments are regenerated from a template engine on cache miss. The server has 8 CPU cores. (a) Would you choose Memcached or Redis? Justify based on the workload characteristics. (b) Estimate the throughput difference: Memcached using all 8 cores vs Redis using 1 core. (c) What Redis features would change your answer? List three specific features that, if needed, would make Redis the better choice. (d) The cache needs to store 500,000 HTML fragments averaging 10 KB each. Calculate the total memory required and whether it fits on a single server with 64 GB RAM.

Exercise: Intermediate: Your caching layer currently runs 40 Redis instances across 10 servers, serving 2 million ops/sec of pure GET/SET traffic. No data structures, no persistence, no pub/sub. (a) Calculate the current CPU utilization per server (40 single-threaded instances ÷ 10 servers, each with 16 cores). (b) Design the Memcached replacement: how many Memcached instances do you need? How many servers? What's the CPU utilization per server? (c) Write the migration plan: how do you cut over from Redis to Memcached without downtime? Consider: dual-write period, client library changes, cache warming strategy, and rollback plan. (d) The finance team asks "how much will we save?" Calculate the monthly infrastructure cost reduction.

Exercise: Advanced: Facebook's Memcached deployment (described in the 2013 "Scaling Memcache at Facebook" paper) serves billions of requests per second across multiple data centers. (a) Facebook uses client-side consistent hashing for sharding. Compare this to Redis Cluster's server-side hash slots. What are the trade-offs in failure handling, rebalancing, and client complexity? (b) Facebook's mcrouter proxy sits between application servers and Memcached instances, handling request routing, connection pooling, and failover. Design a similar proxy layer: what routing decisions does it make, how does it handle a Memcached server failure, and how does it prevent thundering herd on cache miss? (c) Facebook uses Memcached alongside MySQL, not instead of it. The consistency model is "cache-aside with lease-based invalidation." Design this invalidation mechanism: how does a cache entry get invalidated when the underlying MySQL row changes? How do leases prevent thundering herd during invalidation? (d) Your company runs both Redis (for sorted sets and pub/sub in the recommendation engine) and Memcached (for pure caching of API responses). Design the unified monitoring strategy: what metrics per Memcached instance vs per Redis instance? How do you compare health across the two systems?

Back to System Design Advanced