Status: Accepted by owner direction 2026-10-24 ("remove these artificial, made-up, non-standard limits"). In source; Linux qualification pending.
KeyLoad sets no configured limit on the size or amount of work of one operation.
KeyLoad:DatabaseLimits no longer has MaxDocumentBytes, MaxJsonDepth,
MaxBatchMutations, MaxBatchBytes, MaxScanRecords, MaxResults,
MaxQueryBytes, MaxQueryDepth, MaxQueryTokens, QueryDeadlineSeconds,
MaxQueryReadBytes, MaxSearchTextTokens, MaxProjectionConsumers or
MaxProjectionBatchBytes. The section keeps only the optional
MaxQueueTransferAcceptAttempts and MaxQueueTransferRepairAttempts. Both are
null by default and must be at least 1 when set; they no longer depend on a scan
limit.
Every refusal that existed only because one of those numbers was exceeded is
gone: the BudgetExceeded, ResourceExhausted and Validation errors for
document size, JSON depth, batch mutation count, batch bytes, scanned records,
result count, SQL text bytes, SQL depth and token count, query read bytes,
search text tokens, projection consumer count, projection batch bytes and fixed
deadlines. An operation runs as far as its data, the caller's cancellation, the
caller's explicit expiries and real physical constraints allow.
- Read accounting.
ReadExecutionBudgetstarts with no configured bound. It accounts read bytes and records and stops on caller cancellation and on explicit expiries (the request envelopeExpiresAtand caller-supplied expiries). There is no fixed 30-second deadline. Result bytes are bounded only by the real reply ceilings (GrainRoutingOptions.MaximumReplyBytesand the related grain stream ceilings) and by the optionalQueryExecutionOptions.MaximumResultBytes. - Complete ranges. A read that needs a complete key range pages through the
storage provider's own range page (
ZoneTreeStorageExecutionOptions.MaximumRangeRecords) instead of failing when the range holds more records than one scan. The storage-owned range options (MaximumRangeRecords,MaximumRangeWorkBytesand the read-cut ceilings) are unchanged and still bound one storage range operation. - Recursion. SQL token access, the ScriptDOM slot visitor, the lowering
contexts, AST predicate normalization, SQL parameter JSON and the INSERT
expression walkers call
RuntimeHelpers.TryEnsureSufficientExecutionStack(ExecutionStackGuard) and fail the request withValidationwhen the stack runs short. There is no numeric depth or token limit. JSON parsing uses the System.Text.Json default maximum depth (64); KeyLoad defines no JSON depth of its own. A query's offset plus limit must fit a 32-bit row position; a larger sum is aValidationerror because no row index beyond it exists. - Physical owners. Values that bounded a real resource moved to that
resource's owner:
- projection replay pages are sized by
GrainRoutingOptions.MaximumReplyBytes, with no record count; - multi-lane receive results, event feed hints and event feed pubsub rows are
bounded by
GrainRoutingOptions.MaximumReplyBytes; - Orleans
SiloMessagingOptions.MaxMessageBodySizeequalsGrainRoutingOptions.MaximumCompletedBytes; - the Postgres wire transport deadlines and the TLS and admission handshake use
GrainRoutingOptions.RequestLifetime; - Postgres SQL text is bounded by
PostgresSessionOptions.MaximumFrameBytes(Query messages) andMaximumRetainedBytes(prepared statements); - full-text manifest file reads and writes are bounded by
TextExecutionOptions.MaximumDiskBytes; - full-text read cuts (online pins and captured search reads) are clamped to the ZoneTree storage read-cut ceilings;
- the ANN public read reservation sizes its encoded reply scratch from
GrainRoutingOptions.MaximumReplyBytes; - the group-commit journal frame budget still derives from
ZoneTreeStorageExecutionOptions.MaxFrameBytes.
- projection replay pages are sized by
- Analytics. ZoneTree.Analytics generations size their ingestion queue by the actual row count, do not truncate dimension values, and have no query timeout except the caller's explicit expiry.
- Capability manifest.
QueryCapabilityManifest, returned by the SDK, MCP and HTTP query capabilities, no longer hasMaxRows,MaxCandidates,MaxDepthorMaxCandidateBytes.MaxBytesreportsQueryExecutionOptions.MaximumResultBytes, orint.MaxValuewhen no result ceiling is configured. Explain rows no longer reportScanBudget. - Remote queue transfers. The transfer-retention capacity limit and the
TransferRetentionaccept-failure kind are removed. The accept dependency snapshot no longer recordsTransferStoredRecords,TransferStoredBytes,MaxBatchBytesorMaxScanRecords. Queue storage quota failures, enforced by the queue's ownMaxStoredMessagesandMaxStoredBytespolicy, are unchanged. - Comparisons. The load-test AppHost sets no
KeyLoad__DatabaseLimits__environment values, and the benchmark deployment optionsDocumentKeyLoadMaximumScanRecordsandDocumentKeyLoadMaximumQueryReadBytesare removed.
Caller-supplied bounds stay: a request's own Limit, MaxBytes, graph depth,
vertex and edge caps and expiry are honored exactly, and the server
sets no maximum on them beyond the typed QueryExecutionOptions,
GraphExecutionOptions and messaging options that the owning features declare.
ADR-145 (no request throttling) and the
server-wide request body limit are unchanged.
- Large documents, batches, scans, results and SQL text succeed when the hardware and the physical reply and storage ceilings allow them. A request that would produce a reply above a grain reply ceiling fails at that ceiling, not at an invented operation limit.
- A long operation runs until it completes, the caller cancels it or its explicit expiry passes. A caller that needs a time bound sets an expiry.
- Deep SQL, AST and JSON nesting fails only when the execution stack would
overflow (or, for JSON, beyond the System.Text.Json default depth), with
Validationand no partial effect. - Operators size hardware, storage range pages and reply ceilings for their load; there is no per-operation knob to tune instead.
- The removed
DatabaseLimitsmembers, their configuration keys and their wire fields in the capability manifest, Explain rows and the remote transfer accept dependency are gone; configuration that still sets them is ignored. - A test that asserted a removed refusal is removed with it. Complete unit, process recovery, Aspire cluster and delivered-source Linux qualification of this change remain open.