Redis vs Memcached
Redis and Memcached are both in-memory caches, but they have diverged dramatically in scope. Memcached (2003) was purpose-built as a distributed LRU cache. Its design is deliberately minimal: string keys, opaque byte values, slab allocator for memory efficiency, no persistence, no replication. It uses a simple text-based protocol (or binary protocol). Memcached's architecture is share-nothing: clients use consistent hashing to distribute keys across nodes. There is no server-side awareness of the cluster. When a node fails, those keys are lost. This simplicity makes Memcached fast and memory-efficient for its narrow use case. Redis (2009) started as a simple key-value store but grew into a data structures server. A Redis string can hold up to 512 MB. A sorted set enables leaderboards. A list enables job queues. A stream enables event sourcing. Pub/Sub enables real-time messaging. Lua scripts run atomically. Redis Cluster (Redis 3.0+) provides server-side sharding with replication and automatic failover. Redis Sentinel provides HA without Cluster. Persistence: Redis supports RDB (point-in-time snapshot) and AOF (append-only file). Memcached has no persistence. This is the most important difference for anything beyond a pure cache: if your cache contains computed state, session data, or rate limit counters, you probably want Redis's durability options. In 2026, Redis is the near-universal choice. Memcached's advantages — simpler memory model, marginally better CPU efficiency at very high throughput with simple string values — are relevant only at extreme scale. Most teams that still run Memcached are doing so for historical reasons.
Redis is a multi-model in-memory data store: strings, hashes, lists, sets, sorted sets, streams, bitmaps, HyperLogLog, and geospatial indexes. It supports persistence (RDB + AOF), pub/sub, Lua scripting, and clustering. Memcached is a pure LRU cache: slab-allocated string key-value pairs, no persistence, no data structures, no replication. Redis is the default choice for almost everything. Memcached retains an edge only at extreme memory efficiency for simple string caching at multi-terabyte scale.
| Feature | Redis | Memcached |
|---|---|---|
| Data structures | String, Hash, List, Set, Sorted Set, Stream, Bitmap, HyperLogLog, Geo | String (opaque bytes) only |
| Persistence | RDB snapshot + AOF (append-only log). Configurable. | None. All data lost on restart. |
| Replication | Primary-replica replication. Redis Sentinel for HA. Redis Cluster for sharding. | None. Clients shard using consistent hashing. |
| Pub/Sub | Yes – SUBSCRIBE/PUBLISH. RESP3 adds push type for shared-connection pub/sub. | No |
| Lua scripting | Yes – EVAL/EVALSHA for atomic multi-step operations | No |
| Transactions | MULTI/EXEC (optimistic locking via WATCH) | No |
| TTL / eviction | Per-key TTL (EXPIRE, PEXPIRE). Configurable eviction policies: LRU, LFU, allkeys, volatile. | Per-key TTL. LRU eviction only. |
| Memory model | jemalloc. Object encoding optimization (ziplist for small hashes/lists). | Slab allocator. Fixed slab classes. Very predictable memory fragmentation. |
| Max value size | 512 MB per string | 1 MB (configurable, but 1 MB is practical limit) |
| Clustering | Redis Cluster: 16384 hash slots, server-side routing, automatic failover | Client-side consistent hashing only. No server coordination. |
| Protocol | RESP2 / RESP3 (text-based, binary-safe, typed) | Text protocol or binary protocol. Simpler than RESP. |
| Multi-threading | Single-threaded command processing (I/O threads added in Redis 6). No race conditions by design. | Multi-threaded. Multiple cores utilized for command processing. |
| Streams | XADD/XREAD/XGROUP – Kafka-like consumer groups on in-memory streams | No |
| Geospatial | GEOADD/GEODIST/GEORADIUS – geospatial indexing via sorted sets | No |
| Search | Redis Stack: RediSearch full-text search module | No |
| Managed cloud | Redis Cloud, AWS ElastiCache for Redis, Azure Cache for Redis, Google Memorystore | AWS ElastiCache for Memcached, Google Memorystore for Memcached |
When to use Redis
Redis is the right choice for: session storage, rate limiting counters, leaderboards (sorted sets), job queues (List + BRPOP, or Redis Streams), pub/sub messaging, distributed locks (SET NX PX + Redlock), computed cache with persistence requirements, geospatial lookups, or any use case that benefits from data structures beyond simple strings. In practice, Redis is the default choice for all new projects unless there is a specific reason to choose otherwise.
When to use Memcached
Memcached makes sense only for: pure string/blob caching at very large scale where the slab allocator's predictable memory model matters, multi-threaded workloads that need to saturate multiple CPU cores with simple get/set operations, or existing production Memcached deployments where migration cost exceeds the benefit. For new projects, the reasons to choose Memcached over Redis are vanishingly rare.
Common Mistakes
- Storing session data in Memcached without persistence – Memcached has no persistence. A node restart or failure loses all session data. Users get logged out unexpectedly. Use Redis with AOF persistence for session storage.
- Using Redis pub/sub for durable message delivery – Redis pub/sub is fire-and-forget. Messages sent when no subscriber is connected are lost permanently. For durable messaging, use Redis Streams (with consumer groups) or Kafka.
- Not setting maxmemory and an eviction policy – Redis without a maxmemory limit will grow until the host OOMs. Always set maxmemory and maxmemory-policy (allkeys-lru for caches, volatile-lru for mixed cache+persistent data).
- Using KEYS command in production – KEYS * is O(N) and blocks the event loop. Use SCAN for iterating keys in production. This applies to Memcached as well (stats cachedump is similarly dangerous).
- Treating Memcached multi-threading as a reason to choose it over Redis – Redis 6+ added threaded I/O for reading/writing network sockets, closing most of the throughput gap. Redis's single-threaded command execution is an advantage for atomicity, not a limitation.
FAQ
Is Redis faster than Memcached?
For simple get/set operations, Memcached's multi-threaded architecture can achieve slightly higher throughput on multi-core hardware. Redis's single-threaded command processing reaches ~1 million ops/sec on a single node, which is sufficient for the vast majority of workloads. Redis 6+ I/O threading closes much of the gap. For complex data structures, Redis has no Memcached equivalent.
Can Redis replace Memcached completely?
Yes, for virtually all use cases. The only scenario where Memcached retains a meaningful advantage is multi-terabyte simple string caching where Memcached's slab allocator minimizes memory fragmentation. For anything involving data structures, persistence, pub/sub, or clustering with automatic failover, Redis is strictly better.
What is the Redis Memcached compatibility layer?
Redis does not natively speak the Memcached protocol. There are third-party proxies (Twemproxy / Nutcracker, mcrouter) that can route Memcached protocol requests to Redis backends, but this approach adds complexity. For a proper migration, rewrite the cache client to use a Redis client library.