Using Memcached CAS for Safe Concurrent Updates
Learn how Memcached’s compare‑and‑swap (CAS) operation enables safe concurrent updates, with a worked telnet example, limits, and practical verification steps.
26 Apr 2026, 08:43 UTC

Why use CAS in Memcached
When multiple clients may update the same key, a plain set can overwrite changes made by another client. Memcached’s compare‑and‑swap (CAS) operation lets you update a value only if it has not been modified since you last read it, providing a lightweight atomic primitive without server‑side locks.
How CAS works
Each stored item carries a 64‑bit CAS token that changes whenever the item is modified. To use CAS you first retrieve the item with gets, which returns the value and its token. A subsequent cas command includes that token; the server stores the new value only if the token still matches the item’s current token. If another client changed the item in the meantime, the server replies EXISTS and you must fetch a fresh token and retry.
Worked example with a simple client
The following sequence shows the commands you would issue from a telnet (or netcat) session to a local Memcached instance listening on port 11211. Replace <token> with the value returned by gets. Each line must be terminated with \r\n when sent to the server.
set testkey 0 0 5 value gets testkey cas testkey 0 0 6 newval
If the item has not changed, the server replies STORED. If another client modified testkey between gets and cas, the reply is EXISTS. On receiving EXISTS the client should discard the old token, issue a fresh gets to obtain the current token, and repeat the cas command. This retry loop continues until the server returns STORED or a configurable maximum number of attempts is reached.
Limits and common pitfalls
- Per‑item scope: CAS only protects a single key. It cannot provide atomicity across multiple keys; for multi‑key transactions you need application‑level logic or a different store.
- Stale token reuse: Using the same token after an
EXISTSresponse will repeatedly fail. Always obtain a new token withgetsbefore each CAS attempt. - Misinterpreting non‑STORED replies: Treat any response other than
STOREDas a signal to retry (or abort after retries). Do not assume a fatal error. - Short TTL or high eviction: If an item expires or is evicted between
getsandcas, the server returnsNOT_FOUND. Keys with very short lifetimes are poor candidates for CAS unless you refresh them frequently. - Slab fragmentation: Heavy churn can cause frequent evictions, increasing CAS failures. Adjusting the slab growth factor or giving CAS‑relied keys a longer expiration can reduce contention.
Practical way to check the behavior
- Start a Memcached server on a test port, for example:
memcached -p 11212 -t 2 -vv
The-vvflag makes the server print protocol traces to stdout, which helps you see the token values and responses. - Open two terminal windows and connect each with telnet (or netcat) to the server:
telnet localhost 11212
- In the first window run the
setandgetssteps shown above, noting the token. - In the second window, before the first window issues the
cas, run aset testkey 0 0 5\nnew\n to change the value. - Return to the first window and execute the
cascommand with the token obtained earlier. The server should replyEXISTS. - Now issue a fresh
getsin the first window, capture the new token, and repeat thecas. This time the reply should beSTORED.
Observing the EXISTS followed by a successful retry confirms that the CAS token is being validated correctly and that the retry loop is necessary.
Takeaway
Memcached’s CAS gives you a lock‑free way to perform conditional updates on a single key. The key to reliable use is always fetching a fresh token with gets before each cas attempt and retrying on EXISTS (or NOT_FOUND) until the operation succeeds or you decide to abort. Understanding its per‑item nature and the impact of TTL or eviction helps you avoid the common mistakes that turn CAS into a source of spurious failures.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.