Five reasons, and all of them are Memcached’s.
None of these is something BROKA has not got round to. Each is a property of the protocol, and together they decide what a console can honestly offer — which is why the surface is five screens rather than a dozen.
There is no management API
No HTTP endpoint, no admin port, no configuration protocol. A console speaks the same single TCP socket your applications do — stats, slab surgery, emptying the cache and the live log are all line commands on that one connection.
There is no authorisation model
SASL exists; authorisation does not. No roles, no read-only account, no key-level scope, no command allow-list and no audit trail of its own — every authenticated connection can run flush_all. The permissions, guardrails and trail around a Memcached connection are BROKA’s layer, not the broker’s, and the two are not the same thing. So is data masking, in Commercial: a rule hides the parts of a value it covers from anyone not allowed to read them unmasked.
There is no server-side cluster
Consistent hashing lives entirely in the client. A console holds a list of nodes, asks each one and sums the answers — and cannot know which node holds a given key, because that is the application’s choice of hashing, not the server’s.
There is no server-side key search
No pattern matching, no prefix scan, nothing. The one practical listing walks a live LRU: it cannot be paged, it turns the connection into a stream, and it can miss items that move while it runs.
Reading an item changes it
A plain get advances the LRU, sets the fetched bit and updates the last-access time. Browsing keys therefore alters eviction behaviour and perturbs the very metadata the memory screens report — which is the whole argument against giving a cache a keyspace browser.
The fifth is the one worth reading twice. An observation tool that disturbs the thing it observes cannot be the default way you look at a cache — which is why there is no keyspace browser here, and why the metadata read that does not count as a hit sits beside the one that does.
Two nodes of one connection genuinely differ.
Memcached servers share no state and no view of each other. They are started separately, so what each one can do was decided before it launched — and every capability is a start-up flag with no runtime switch behind it.
That is not a claim about configuration in the abstract. Two nodes on 1.6.45, started the way our own development pair is — one plain, one with -X -W -F — answer the same three commands differently, and each refusal names itself:
| Command | Node A | Node B (-X -W -F) |
|---|---|---|
| lru_crawler metadump all | OK … END | ERROR metadump not allowed |
| watch fetchers | OK | CLIENT_ERROR watch commands not allowed |
| flush_all | OK | CLIENT_ERROR flush_all not allowed |
Three refusals, three different messages — so “this node is not answering” and “this node does not do that” are distinguishable, and the console shows the second as a fact about the node rather than as an error to retry. Nothing short of a restart changes any of them.
Memcached evicts long before it looks full.
This is the question a cache actually raises, and the one a top-level counter cannot answer. It is also the reason this platform is worth a console at all.
Memory is committed a page at a time
Pages go to a slab class, and a page committed to one class is unavailable to every other. It cannot be borrowed back as demand shifts.
Items are rounded up
An item occupies the next chunk size in its class, whatever it asked for. Items that wanted 385 bytes sit in 480-byte chunks — and memory used does not count the difference, so the class fills its pages before that figure reaches the limit.
So the totals lie by omission
A node reporting half its memory used can be evicting constantly. Only the per-class table shows it: the pages each class holds, how many of its chunks are in use, and how much of them is rounding.
The limit is the ceiling the node was given. Claimed is how much it has actually asked the operating system for. A node well under its limit, with every page already committed to the wrong classes, evicts constantly — and only these two side by side make that legible. The memory screen puts them there, then breaks the rest down by class: chunk size, pages, what is occupied, what is rounding, what each class evicted, and what it refused outright because it could not even evict to make room.
Five screens, and the count is the point.
Each answers a question the protocol actually lets a console answer. There is no sixth screen waiting to be built — there is no sixth question Memcached can be asked from one TCP socket.
Overview
Every node’s own account of itself, summed rather than averaged — the hit rate is re-derived from summed hits and misses, because a node serving ten requests must not weigh as much as one serving ten million.
Nodes
The servers this connection addresses, and where a whole node is acted on. Resetting the counters, changing the memory ceiling and flushing the cache are all here, all node-scoped — beside a per-prefix report read only when you ask for it.
Memory and slabs
Where a node’s memory has actually gone, per slab class: chunk size, pages, what is occupied, what is rounding, what each class has evicted and what it refused outright — pages moved between classes, and expired items reclaimed on request by the node’s own crawler.
Keys
One key at a time, with the metadata read that does not count as a hit beside the one that does, and an item marked stale instead of deleted — and a listing you ask for explicitly, with its caveats attached, whose selected keys are deleted or re-armed in one round trip and answered key by key.
Live events
Every get, store and eviction as it happens, written to whoever is listening and to nobody afterwards. A log, not a queue: nothing is retained, acknowledged or replayable.
Four limits, stated where you would look for the feature.
Each is a decision, and each is visible in the product rather than only here.
It will not decode your values
The flags integer stored beside a value is the client library’s private serializer tag, and every library numbers it differently. The bytes are shown as bytes, and any format guess is labelled a guess.
It will not flush every node at once
Flushing is node-scoped, one server at a time, with the result of each visible before the next. A single control that emptied an estate’s cache would leave every node cold simultaneously — which is how a cache outage becomes a database outage.
It will not browse your keyspace
Enumeration walks a live LRU: it costs the node real work, it is approximate, it cannot be paged, and on a node started with -X it is unavailable entirely. So it is an explicit, warned action with its caveats attached to the result.
It will not let you set an expiry by accident
Memcached reads one number for two things: past 2 592 000 seconds a TTL becomes an absolute date, and the store succeeds — so an item can expire in 1970 with nothing reported. Every control takes a relative duration and says which of the two is about to happen.

