Observation (production OCA broker, 2026-07-22)
JetStream account state: 8,838 consumers, including 6,556 on the tic_status stream alone. Creation-date histogram of tic_status consumers (from /jsz?consumers=true):
2026-06-24: 5,099 ← burst, created within seconds (~21:45:15)
2026-06-17: 276
2026-06-25: 230
2026-05-20: 138
...
5,099 consumers created in one burst on 2026-06-24 — the day the halina service (serverish 2.0.5 client) was restarted. This looks like a creation retry storm: consumer-create requests being retried in a loop where each attempt actually succeeds server-side (response lost/slow?), each retry registering a fresh ephemeral consumer. Pattern-wise a cousin of #30's "retry forever on 4xx" (fixed), but for the create path + non-idempotent creates.
These consumers show Last Delivery: never and survive for a month+. Note: consumers created by current serverish 2.0.5 carry inactive_threshold: 300s (observed on a live one), so month-old leftovers either predate that default or were created through a path that doesn't set it — worth auditing both.
Impact
- 6.5k consumers on one stream degrade JS API responsiveness for every client of that broker (slow consumer-create/info responses → more client-side timeouts → more retries — self-reinforcing).
- Operationally invisible until someone lists consumers.
Suggested fixes
- Idempotent creates: name ephemeral consumers deterministically per reader instance (client-generated name), so a retried create with the same name is a no-op server-side instead of a new consumer (JetStream treats same-name create as idempotent update).
- Ensure every consumer-creation path sets
inactive_threshold (bounded, e.g. 300 s), so even leaked ones self-destruct.
MsgReader.close() should explicitly delete its ephemeral consumer (best effort) instead of relying on inactivity GC.
- One-off ops cleanup script for existing brokers: delete consumers with
delivered.last == never older than N days (happy to contribute).
Observation (production OCA broker, 2026-07-22)
JetStream account state: 8,838 consumers, including 6,556 on the
tic_statusstream alone. Creation-date histogram oftic_statusconsumers (from/jsz?consumers=true):5,099 consumers created in one burst on 2026-06-24 — the day the
halinaservice (serverish 2.0.5 client) was restarted. This looks like a creation retry storm: consumer-create requests being retried in a loop where each attempt actually succeeds server-side (response lost/slow?), each retry registering a fresh ephemeral consumer. Pattern-wise a cousin of #30's "retry forever on 4xx" (fixed), but for the create path + non-idempotent creates.These consumers show
Last Delivery: neverand survive for a month+. Note: consumers created by current serverish 2.0.5 carryinactive_threshold: 300s(observed on a live one), so month-old leftovers either predate that default or were created through a path that doesn't set it — worth auditing both.Impact
Suggested fixes
inactive_threshold(bounded, e.g. 300 s), so even leaked ones self-destruct.MsgReader.close()should explicitly delete its ephemeral consumer (best effort) instead of relying on inactivity GC.delivered.last == neverolder than N days (happy to contribute).