cas / gets — Compare-And-Swap
Optimistic locking: update a key only if it hasn't changed since you read it.
Code
# gets returns a unique cas token as the last value
gets counter
# VALUE counter 0 2 14
# 42
# END
# ^ cas_unique = 14
# cas — write only if cas_unique still matches
cas counter 0 0 2 14
43
# STORED (token 14 still current)
# Another client modified counter between our gets and cas:
cas counter 0 0 2 14
44
# EXISTS (token changed — someone else wrote first)
# Race-free increment pattern
gets counter # 42, token=14
# ... compute new value ...
cas counter 0 0 2 14
43
# if EXISTS, retry: gets again, recompute, cas again
# Python (pymemcache)
from pymemcache.client.base import Client
c = Client(("localhost", 11211))
result = c.gets("counter") # (value, cas)
ok = c.cas("counter", b"43", result[1], expire=0)
if not ok:
pass # retryExplanation
cas (Compare-And-Swap) implements optimistic concurrency: gets fetches the value plus a cas_unique token; cas writes only if the token still matches, otherwise returns EXISTS. This avoids lost updates when two clients read-modify-write the same key. The standard retry pattern: gets → compute → cas → on EXISTS, loop. cas_unique is a server-side counter incremented on each write. Note cas does NOT bump exptime automatically — pass a new exptime if you want to extend ttl. For pure integer counters prefer incr/decr which are already atomic.
More Memcached Snippets
set / get — Basic Key-Value
Store and retrieve values by key with expiration and flags.
add / replace / append / prepend
Conditional writes and in-place string concatenation.
stats — Server Metrics & Slabs
Inspect memory, hit rate, evictions and per-slab allocation.
flush_all — Invalidate Everything
Logically invalidate all keys instantly (lazy deletion).
Expiration, Eviction & TTL Strategy
Choose TTLs wisely and understand how Memcached evicts under pressure.
Text vs Binary Protocol & Consistent Hashing
Pick the right protocol and shard across servers without reshuffling.