FetchLimiter decides admission per connection. That is correct for what it was built for — enumeration sweeps and runaway single clients — but it means total fetch volume across the fleet has no observer, and a consumer topology change can raise aggregate load without any connection approaching its ceiling.
Surfaced by a consumer seat describing their own topology, and it is sharper than "many processes":
the client is per PLUGIN INSTANCE, and a plugin instance is per (process × project) — a single process serving several projects holds several independent clients and therefore several connections
So the connection count scales with projects open, not with processes, and every one of them carries its own 64/60s budget. A fleet-wide rotation storm spreads across N budgets instead of concentrating in one: aggregate RPC volume rises, no individual connection alarms, and nothing records that it happened.
The data is already resident. FetchLimiter.conns is a HashMap<u64, ConnState> holding every live connection's window, and drop_connection (limiter.rs:146) removes closed ones, so the map is live-only. The decision is per-connection; the state is not. A fleet-aggregate observation is a fold over self.conns, not a new surface.
One correctness detail, or the fold reports a number that is wrong in the alarming direction. prune is called at exactly one site — limiter.rs:121, on the admitting connection only. An idle connection's window is never trimmed until it fetches again, so its fetches vector still holds timestamps older than the window. A naive conns.values().map(|c| c.fetches.len()).sum() counts those, and over-counts by exactly the volume of whichever connections went quiet. The fold has to prune-then-sum:
self.conns.values_mut().for_each(|c| c.prune(now, caps.window));
let fleet = self.conns.values().map(|c| c.fetches.len()).sum::<usize>();
That is the same shape as several defects found this week: the data is right, the aggregation is wrong, and the wrong answer looks plausible.
What I am not proposing: a fleet ceiling that denies. Admission::Anomaly alarms and still serves, which is the right default for a credential path — defensive throttling on a recovery mechanism trades a visible alarm for an invisible degradation. Zero fetch_anomaly rows exist in this deployment all-time, so nothing is pressing.
What is worth having: a fleet-volume figure exposed on the existing no-decrypt health snapshot, so "how much load is this fleet generating" has an answer that is not per-connection. Whether it should also alarm at some multiple of the per-connection ceiling is a separate question and probably wants a real number behind it first.
A second, forward-looking note on the distinct ceiling, raised by the same exchange. DEFAULT_DISTINCT_CEILING is 16 distinct credential_ids per connection per 60s, and it exists to catch enumeration sweeps. But a consumer warming several bound accounts at startup touches several distinct ids in quick succession legitimately:
our STARTUP path is the one that could approach it, not the retry path — a process warming several bound accounts at boot touches several distinct credential_ids in quick succession. We hold two accounts today
This threshold scales with roster size rather than with traffic, which is backwards for a vault whose purpose is multi-account custody. A tenant with 12 fallbacks plus main plus a signing key is at 14 on an ordinary boot, and an enumeration sweep and a legitimate startup warm become indistinguishable at the ceiling. Worth a decision before a roster grows into it rather than after the first false alarm.
FetchLimiterdecides admission per connection. That is correct for what it was built for — enumeration sweeps and runaway single clients — but it means total fetch volume across the fleet has no observer, and a consumer topology change can raise aggregate load without any connection approaching its ceiling.Surfaced by a consumer seat describing their own topology, and it is sharper than "many processes":
So the connection count scales with projects open, not with processes, and every one of them carries its own 64/60s budget. A fleet-wide rotation storm spreads across N budgets instead of concentrating in one: aggregate RPC volume rises, no individual connection alarms, and nothing records that it happened.
The data is already resident.
FetchLimiter.connsis aHashMap<u64, ConnState>holding every live connection's window, anddrop_connection(limiter.rs:146) removes closed ones, so the map is live-only. The decision is per-connection; the state is not. A fleet-aggregate observation is a fold overself.conns, not a new surface.One correctness detail, or the fold reports a number that is wrong in the alarming direction.
pruneis called at exactly one site — limiter.rs:121, on the admitting connection only. An idle connection's window is never trimmed until it fetches again, so itsfetchesvector still holds timestamps older than the window. A naiveconns.values().map(|c| c.fetches.len()).sum()counts those, and over-counts by exactly the volume of whichever connections went quiet. The fold has to prune-then-sum:That is the same shape as several defects found this week: the data is right, the aggregation is wrong, and the wrong answer looks plausible.
What I am not proposing: a fleet ceiling that denies.
Admission::Anomalyalarms and still serves, which is the right default for a credential path — defensive throttling on a recovery mechanism trades a visible alarm for an invisible degradation. Zerofetch_anomalyrows exist in this deployment all-time, so nothing is pressing.What is worth having: a fleet-volume figure exposed on the existing no-decrypt health snapshot, so "how much load is this fleet generating" has an answer that is not per-connection. Whether it should also alarm at some multiple of the per-connection ceiling is a separate question and probably wants a real number behind it first.
A second, forward-looking note on the distinct ceiling, raised by the same exchange.
DEFAULT_DISTINCT_CEILINGis 16 distinctcredential_ids per connection per 60s, and it exists to catch enumeration sweeps. But a consumer warming several bound accounts at startup touches several distinct ids in quick succession legitimately:This threshold scales with roster size rather than with traffic, which is backwards for a vault whose purpose is multi-account custody. A tenant with 12 fallbacks plus main plus a signing key is at 14 on an ordinary boot, and an enumeration sweep and a legitimate startup warm become indistinguishable at the ceiling. Worth a decision before a roster grows into it rather than after the first false alarm.