Skip to main content

Variable: STREAM_BOUNDS

const STREAM_BOUNDS: object

Defined in: packages/messaging/src/streams.ts:81

Each stream's bounds. A stream added to the permission table without a row here does not compile.

AUDIT (D1.10, 09): 1 GiB, 5,000,000 messages and 30 days, against N172's bounded retention. The duplicate window is a day, so an outbox relay that retries across a long outage still publishes once. maxAgeNs is the one bound that can drop a message the chain has not appended (a 30-day audit outage); verify-chain --reconcile finds that case by comparing the outbox with the chain.

GOVERNANCE and TRUST (slice 2): 64 MiB, 100,000 messages and 30 days each. They carry accreditation decisions and published statements, a few per entity per year, so the ceiling is far above any national tree and exists only so neither is unbounded. The day-long duplicate window is AUDIT's, for the same reason: both are fed by an outbox relay that may retry across a long outage. A full stream refuses rather than drops, and the relay keeps the row (see streamConfig).

ISSUANCE and PLACEMENT (slice 3, D3.16): the same 64 MiB, 100,000 messages and 30 days. ISSUANCE carries one message per published version of an identifier and PLACEMENT one per placement written or changed, so both are as sparse as the two above and are bounded for the same reason. Both are fed by outbox relays, hence the day-long duplicate window. PLACEMENT is a work queue (see streamConfig), so its bounds count the answers issuance has not recorded yet; 30 days is how long an answer may wait for credential to come back.

PROVISIONING (slice 3; plan 3a, "Rulings before 3.11b and 3.12", item 2, and ruling 5 of the wave 3 hand-out): 10,000 messages, deliberately low. It is the one stream a principal other than its reader's can fill with messages the reader then acts on: credential publishes identifier.requested and provisioning creates a placement for each. The cap is a cap on the backlog. PROVISIONING is a work queue, so a request leaves the stream when provisioning acknowledges it, and the 10,000 are requests still waiting for a placement, never requests already answered. It is what a flood can leave queued, and provisioning's quota (600 new placements per ten minutes by default) then works through a full stream in under three hours. At the cap the broker refuses the publish (discard: New), issuance's outbox row stays unpublished, and it goes out when there is room, which is as soon as one request is acknowledged. A deployment whose backlog legitimately runs deeper raises this number and nothing else.

The duplicate window outlives the message. The broker remembers a Nats-Msg-Id for the whole window whether or not the message is still stored, so on a work queue a message published again under the id of one already acknowledged and removed is dropped as a duplicate, silently. That is right for an outbox relay retrying one row. Anything meant to be delivered a second time (a re-driven request, a repeated answer) has to be a new message with a new id; nothing here derives or reuses ids.

Type Declaration​

AUDIT​

readonly AUDIT: object

AUDIT.duplicateWindowNs​

readonly duplicateWindowNs: number = DAY_NS

AUDIT.maxAgeNs​

readonly maxAgeNs: number

AUDIT.maxBytes​

readonly maxBytes: number

AUDIT.maxMessages​

readonly maxMessages: 5000000 = 5_000_000

GOVERNANCE​

readonly GOVERNANCE: object

GOVERNANCE.duplicateWindowNs​

readonly duplicateWindowNs: number = DAY_NS

GOVERNANCE.maxAgeNs​

readonly maxAgeNs: number

GOVERNANCE.maxBytes​

readonly maxBytes: number

GOVERNANCE.maxMessages​

readonly maxMessages: 100000 = 100_000

ISSUANCE​

readonly ISSUANCE: object

ISSUANCE.duplicateWindowNs​

readonly duplicateWindowNs: number = DAY_NS

ISSUANCE.maxAgeNs​

readonly maxAgeNs: number

ISSUANCE.maxBytes​

readonly maxBytes: number

ISSUANCE.maxMessages​

readonly maxMessages: 100000 = 100_000

PLACEMENT​

readonly PLACEMENT: object

PLACEMENT.duplicateWindowNs​

readonly duplicateWindowNs: number = DAY_NS

PLACEMENT.maxAgeNs​

readonly maxAgeNs: number

PLACEMENT.maxBytes​

readonly maxBytes: number

PLACEMENT.maxMessages​

readonly maxMessages: 100000 = 100_000

PROVISIONING​

readonly PROVISIONING: object

PROVISIONING.duplicateWindowNs​

readonly duplicateWindowNs: number = DAY_NS

PROVISIONING.maxAgeNs​

readonly maxAgeNs: number

PROVISIONING.maxBytes​

readonly maxBytes: number

PROVISIONING.maxMessages​

readonly maxMessages: 10000 = 10_000

TRUST​

readonly TRUST: object

TRUST.duplicateWindowNs​

readonly duplicateWindowNs: number = DAY_NS

TRUST.maxAgeNs​

readonly maxAgeNs: number

TRUST.maxBytes​

readonly maxBytes: number

TRUST.maxMessages​

readonly maxMessages: 100000 = 100_000