Running a straightforward benchmark, ten thousand SET operations, one at a time, through each system’s standard Python client, produces a result that looks decisive: Memcached completes the batch in 67 milliseconds, Redis takes 410 milliseconds, a roughly sixfold difference that would seem to settle the “which is faster” question outright. That number is real, and it’s also badly misleading, because it’s measuring something closer to per-request round-trip overhead in an unpipelined client than either system’s actual capability.
Switching Redis to use pipelining, batching many commands into fewer network round trips, the exact same ten thousand SET operations drop to about 80 milliseconds, a 125,000 operations-per-second rate that closely matches what the official redis-benchmark tool reports independently. The apparent sixfold gap mostly evaporates once Redis is actually used the way it’s meant to be used. What’s left after that correction is a real, smaller, and more interesting difference worth understanding properly rather than settling for either the naive number or a generic “they’re both fast” shrug.
What Each One Actually Is
Memcached is a purely in-memory key-value store, built for one job specifically: caching simple values, strings or serialized blobs, with extremely low overhead per operation. It has no data structures beyond a flat key-to-value mapping, no persistence to disk under any configuration, and no built-in replication, and every one of those omissions is a deliberate design choice that keeps its implementation simple and its per-operation cost low.
Redis is also an in-memory store, but it supports a genuinely rich set of native data structures beyond simple strings, hashes, lists, sets, sorted sets, and more, along with optional persistence to disk, built-in replication, and a pub/sub messaging system. This additional capability comes with more internal complexity than Memcached’s intentionally minimal design, which is part of why the properly-measured throughput comparison below doesn’t come out as a clean win for either system.
The Real Benchmark Numbers, Measured Directly
Running identical operations against both systems, installed and tested directly for this piece, produced three genuinely different pictures depending on how each client actually used its connection:
| Test | Redis | Memcached |
|---|---|---|
| Naive, one operation per round trip (10,000 SETs) | 24,369 ops/sec | 149,294 ops/sec |
| Redis pipelined / official benchmark tool | 125,211 – 129,870 ops/sec | — |
| Batched (Redis pipeline vs Memcached set_multi) | 125,211 ops/sec | 493,152 ops/sec |
The honest conclusion from these numbers isn’t “Redis is slow” or “Memcached is faster,” it’s that both systems are capable of very high throughput, and the naive, unpipelined first test was measuring client round-trip overhead far more than either server’s actual capacity. Once both are used correctly, with batching, Memcached does show a genuine, real edge for this specific, narrow workload, pure simple-string key-value operations with no additional structure, roughly four times the throughput of pipelined Redis in this measurement. That edge reflects Memcached’s simpler, more specialized internal design doing exactly the one job it was built for, without the additional bookkeeping Redis’s richer feature set requires even when that extra capability isn’t being used for a given operation.
This is why so many “Redis vs Memcached” benchmarks online are misleading
A benchmark that only tests naive, one-at-a-time operations without pipelining or batching for either system produces a number that says more about how well each client library or test script was written than about which cache is actually faster for real, well-implemented usage. Any benchmark comparison worth trusting should specify whether pipelining or batching was used, and testing your own actual usage pattern, however you genuinely intend to call these systems in production, matters more than any generic published number, including the ones in this piece.
What Redis Can Do That Memcached Fundamentally Cannot
Beyond raw throughput, Redis’s native data structures solve entire categories of problems that require considerably more application-side logic to replicate on top of Memcached’s flat key-value model. A hash lets a specific field within a stored object be incremented atomically without reading, modifying, and rewriting the entire value, confirmed directly: incrementing a “visits” counter inside a user hash twice produces the correctly updated value without ever touching the rest of that user’s stored data.
HSET user:1 name "Alice" visits 0
HINCRBY user:1 visits 1
HINCRBY user:1 visits 1
-- user:1 now: {name: "Alice", visits: "2"}, updated without rewriting the whole hash
Sorted sets provide a genuinely different capability with no real Memcached equivalent at all: a leaderboard, adding scores for three players and retrieving them in ranked order comes back correctly sorted directly from the data structure itself, with no application-side sorting logic required. Lists support queue-style operations, pushing and popping values in order, useful for simple job queues or activity feeds. Sets support membership testing and set operations like intersection, finding shared tags between two posts directly through SINTER rather than fetching both tag lists into application code and computing the intersection manually.
None of this is something Memcached can do without significant application-side work to serialize and manually manage equivalent structures inside plain string values, and every one of those manual implementations reintroduces exactly the kind of read-modify-write race condition risk that Redis’s native atomic operations on these structures avoid by design.
Persistence: The Difference That Matters Most for Some Use Cases
Memcached has genuinely no persistence option under any configuration. A server restart, a crash, a deployment that recycles the process, means every cached value is gone, with no way to preserve or recover it. This is a deliberate design choice, not a missing feature to be added later, and it reflects Memcached’s positioning purely as an ephemeral cache sitting in front of a real, durable data store, never as anything resembling a source of truth.
Redis supports two persistence mechanisms, RDB snapshots (periodic point-in-time dumps of the dataset to disk) and AOF (an append-only log of every write operation, replayable to reconstruct the dataset), either or both of which can be enabled depending on the durability guarantees a given use case actually needs. This makes Redis viable for use cases beyond pure caching, a message queue, a session store where losing data on restart would be a genuine problem, a rate limiter’s counters that should survive a server restart, in ways Memcached fundamentally cannot support regardless of configuration.
Architecture: Single-Threaded vs Multi-Threaded
Memcached is multi-threaded by design, distributing incoming requests across multiple worker threads to take advantage of multiple CPU cores directly. Redis’s core command execution has historically been single-threaded, a deliberate design choice that avoids the complexity and potential race conditions of concurrent data structure access, relying instead on its command execution being fast enough per-operation that a single thread handling commands sequentially remains highly performant. Redis 6.0 introduced optional multi-threaded I/O specifically for network handling, reading and writing to sockets, while keeping the actual command execution itself single-threaded, a middle ground that improves network-bound throughput without introducing concurrent access complexity into the core data operations.
In practice, this architectural difference matters less than it might seem for typical caching workloads, since a single Redis instance’s single-threaded command execution is still extremely fast in absolute terms, as the benchmark numbers above demonstrate. It matters more for CPU-intensive operations on very large data structures, where Memcached’s multi-threading can parallelize work that Redis’s single command-execution thread cannot.
Choosing Between Them
Pure, simple caching, storing and retrieving straightforward values with no need for structure beyond a flat key-value mapping, is where Memcached’s specialized simplicity and measured raw throughput edge genuinely matter, and it remains a completely reasonable, often preferable choice for exactly this narrow job, particularly at very high request volumes where every bit of per-operation overhead compounds.
Anything needing Redis’s native data structures, a leaderboard, a job queue, atomic counters, set operations, anything needing data to survive a restart, or anything needing pub/sub messaging, session storage with durability, or use as the backing store for the kind of distributed rate limiting covered in this site’s rate limiting algorithms comparison, points clearly toward Redis, since Memcached simply has no path to supporting these use cases without substantial custom application logic layered on top.
Real Scenarios
A high-traffic website caching rendered page fragments or database query results
Either works well here, and Memcached’s simplicity and measured throughput edge for pure key-value operations make it a genuinely strong, focused choice if nothing beyond simple caching is needed.
A real-time leaderboard or ranking feature
Redis, without much debate, given sorted sets solve exactly this problem natively, with correctly ranked retrieval built directly into the data structure rather than requiring custom sorting logic in application code.
A distributed rate limiter needing shared state across multiple servers
Redis, since the atomic increment and expiration operations needed for correct distributed rate limiting depend on data structure features Memcached doesn’t provide, a connection covered directly in this site’s rate limiting comparison.
A session store where losing sessions on a cache restart would be disruptive
Redis, specifically for its persistence options, since Memcached’s complete lack of any persistence mechanism means every active session would be lost on any restart or crash, a real operational risk Redis’s RDB or AOF persistence directly addresses.
Common Mistakes
Trusting a naive, unpipelined benchmark as representative of real-world performance, exactly the mistake the introduction’s first measurement demonstrates, produces a comparison that says more about client library round-trip overhead than either system’s genuine capability, and it’s worth being skeptical of any published Redis-versus-Memcached benchmark that doesn’t specify whether pipelining or batching was used for both sides.
Using Redis purely as a simple key-value cache while never taking advantage of its native data structures, effectively paying for capability that isn’t being used, sometimes makes sense for consistency (running one caching technology rather than two across an infrastructure), but it’s worth recognizing explicitly as a deliberate trade-off rather than an oversight, particularly given Memcached’s measured throughput edge for that exact narrow use case.
Assuming Redis’s persistence makes it a safe primary data store rather than treating it as it’s generally meant to be used, primarily as a cache or a fast, secondary data layer alongside a genuine relational or document database, risks real data loss or consistency issues if Redis’s persistence configuration isn’t tuned deliberately and understood thoroughly for the specific durability guarantees a use case actually requires.
And running either system without appropriate memory limits and eviction policy configuration invites an out-of-memory crash under real production load, since both are in-memory stores with a finite capacity, and neither behaves gracefully by default if that capacity is exceeded without an eviction policy explicitly configured to handle it.
FAQ
Is Redis always slower than Memcached?
Not universally, and the naive benchmark showing a sixfold gap in this piece was measuring client overhead rather than true capability. Once properly pipelined, Redis’s throughput is genuinely high, though Memcached still showed a real, measured edge for pure simple key-value operations specifically once both were properly batched.
Can Memcached store complex data structures like Redis?
Not natively. Memcached only stores flat string or binary values, so anything resembling a structured object needs to be serialized into a single value and deserialized on every read, with no atomic partial-update capability the way Redis hashes provide.
Does Redis’s persistence mean it never loses data?
No. RDB snapshots capture data at specific intervals, meaning writes since the last snapshot can be lost on a crash, while AOF offers stronger durability at some performance cost. The right configuration depends on how much data loss is actually acceptable for a given use case.
Why does Memcached use multiple threads while Redis mostly doesn’t?
Memcached’s simpler data model makes multi-threaded concurrent access straightforward to implement safely. Redis’s richer data structures and the atomicity guarantees it provides on operations against them are simpler to guarantee correctly with single-threaded command execution, a deliberate trade-off rather than an oversight.