Memcached does one thing: store opaque bytes under a key in RAM, and give them back fast. It has no persistence, no replication, no query language, no data structures, no built-in security boundary. That is not a shortcoming to be engineered around - it is the design. A cache whose failure mode is “the data is gone, fetch it again” earns its place by being too simple to fail in interesting ways.
The memory model
Memory is pre-allocated at startup into slab classes - fixed-size buckets for different value sizes. A 90-byte value lands in a 96-byte slab; the leftover space is internal fragmentation. Each slab class runs its own LRU: when memory fills, only the least-recently-used items of that size class are evicted.
Two operational consequences:
- Eviction is per-slab, not global - a flood of small values cannot evict your large values, but it will evict your other small values.
- Slab classes cannot re-balance memory between themselves (older releases) - a workload whose
item sizes drift over time can strand memory in the wrong class until restarted with different
-f(growth factor) tuning.
The protocol
Plain text or binary protocol over TCP, single-digit-microsecond-class operations:
get/gets,set,add,replace,append,prepend,delete,incr/decr,touch.cas(check-and-set):getsreturns a token;caswrites only if the token still matches - the primitive that lets you do read-modify-write without a race.statsexposes hits, evictions, memory, and slab histograms - the diagnostic entry point.
Multi-get (get k1 k2 ...) is where the real throughput comes from: one round trip, many keys.
Distribution: the client is the cluster
There is deliberately no server-side clustering. The client library hashes keys across your
memcached instances - typically consistent hashing (ketama or variants) so adding or
removing a node remaps only ~1/N of keys. Losing a node loses only its slice of cache; the penalty
is a miss, not an outage.
This is the fundamental difference from Redis: no replication means no failover machinery, no persistence means no RDB/AOF to manage, and no structures means no temptation to build stateful features on top of your cache.
Security posture
Memcached speaks unauthenticated plaintext. SASL exists but is rarely deployed. The operational rule is network-level isolation: bind to localhost or a private interface, firewall it, never expose it. An open memcached on a routable interface is an amplifier for reflection attacks and a data leak - treat it like an unlocked back door, because it is one.
What actually breaks
- Thundering herd on expiry: a hot key expires, ten thousand requests miss simultaneously, and
the database behind it falls over. The fix is stale-while-revalidate semantics in the client, or
a mutex/
caspattern so only one worker recomputes. - Slab imbalance: workload shifted to different value sizes; memory sits stranded in the wrong
slab class while useful items evict.
stats slabsshows the imbalance; fix is restart with a better growth factor or migrate item sizes. - Eviction surprise in multi-tenant use: two applications sharing one instance evict each other unpredictably - separate instances for separate tenants.
- Treating it as a store: data vanishes on restart or eviction. Anything you cannot regenerate is in the wrong place.
Where Memcached is the wrong choice
If you need persistence, replication, data structures, pub/sub, Lua, or atomic counters across keys, the tool is Redis (or its fork Valkey). If the cached data is expensive enough that losing it hurts, a cache with durability - or the database itself - is the answer. Memcached earns its place where the requirement is exactly “fast, shared, disposable” and nothing more.
Memcached release support
1 supported| Release | Latest | Released | End of life | Status |
|---|---|---|---|---|
1.6 | 1.6.45 | Mar 2020 | not published | Supported |
Data as of 2026-10-01 from endoflife.date. Refresh with node scripts/fetch-versions.mjs.
Where Memcached sits
How this component relates to the rest of the stack. Items without a link are not covered here yet.