Skip to content

Limits

fdyno is constrained by three different contracts. They must not be treated as one quota system:

  1. DynamoDB-documented constraints define the client behavior fdyno aims to reproduce.
  2. fdyno validation and workflow boundaries are what the current implementation rejects, splits, filters, or leaves to operators.
  3. FoundationDB limits apply to the encoded physical transaction after base chunks, indexes, stream images, metadata, keys, and conflict ranges are included.

DynamoDB sizes use binary units (1 KiB = 1,024 bytes), although AWS labels them KB and MB. FoundationDB's affected-data, key, and value limits below are exact decimal byte counts from its documentation.

Limit table

Area Current boundary Kind / owner Observable result Mitigation Source
Protocol: request line or headers 16 KiB each at fdyno's application check Hard · fdyno HTTP 431 Request Header Fields Too Large Reduce cookies/custom headers and signed-header set; use a proxy with compatible limits code
Protocol: request body 16 MiB raw and after decompression Hard · fdyno Request rejected before action execution; no mutation Split requests; compression cannot bypass the decompressed cap code · tests
Query / Scan page Approximately 1 MiB of accepted/scanned item data per response page Hard page boundary · fdyno, modeled on DynamoDB LastEvaluatedKey is returned; the page may include the item crossing the internal budget Continue from LastEvaluatedKey; do not assume one snapshot across pages code · AWS
Item 400 KiB, including attribute-name and value sizes under fdyno's DynamoDB sizing logic Hard · fdyno validation / DynamoDB ValidationException; write does not commit Split the logical object across items or externalize large payloads code · tests · AWS
Primary-key value Partition key 2,048 bytes; sort key 1,024 bytes Hard · fdyno validation / DynamoDB ValidationException beyond the bound; selected tests accept 2,048 and reject 2,049 partition-key bytes on write and read Hash or shorten external identifiers while preserving collision handling code · boundary tests · AWS
Nested document or expression value 32 levels; 31 map wrappers plus a leaf at level 32 is accepted, while 32 wrappers plus a leaf at level 33 is rejected Hard · fdyno validation / DynamoDB ValidationException before Put, Delete, Update, or transaction mutation evaluation Flatten the document or split it into related items code · test · AWS
Expression parameter 4,096 bytes in the raw expression string; 4,097 rejected for Update, Condition, Query/Scan Filter, and Projection Hard · fdyno validation / DynamoDB ValidationException with the expression-size diagnostic Shorten attribute paths or split work; alias expansion does not count against the raw expression string code · tests · AWS
BatchGetItem 100 keys total and per table Hard · fdyno validation / DynamoDB ValidationException; no batch read Split key sets and combine results client-side code · tests
BatchWriteItem 25 put/delete requests total and per table Hard · fdyno validation / DynamoDB Invalid request: ValidationException; physically oversized valid request: chunks may commit and failures return in UnprocessedItems Retry only UnprocessedItems; use TransactWriteItems when all-or-nothing is required code · AWS
Batch 16 MiB limit AWS documents 16 MiB for BatchGetItem results and BatchWriteItem requests; fdyno has a generic 16 MiB request-body cap, but no focused test verifies a 16 MiB BatchGetItem result limit Compatibility boundary · mixed Requests over fdyno's body cap fail; large batch-read response behavior should not be assumed identical Keep batches below both count and payload bounds; test large-result behavior AWS · fdyno edge
Transaction actions 100 actions for TransactGetItems, TransactWriteItems, and PartiQL ExecuteTransaction Hard · fdyno validation / DynamoDB ValidationException Split only if application invariants permit; otherwise redesign the transaction boundary code · tests
DynamoDB transaction data AWS documents 4 MiB for TransactWriteItems and TransactGetItems; fdyno currently prechecks 4 MiB across Put item bodies for TransactWriteItems, and no separate 4 MiB TransactGetItems result enforcement was identified Hard TWI precheck + compatibility gap · fdyno Oversized Put total: ValidationException; other aggregate cases remain subject to the physical FoundationDB limits Reduce item/action count; test large updates and transaction reads; leave room for physical amplification code · AWS
FoundationDB transaction 10,000,000 bytes of affected data, including written keys/values/ranges and read/conflict keys/ranges Hard · FoundationDB FDB size error; transactional fdyno paths map size/key/value errors to ValidationException; BatchWriteItem may split only for transaction-too-large Reduce the atomic write/read set; project less; use bounded workflow transactions where atomicity is not required FDB · mapping
FoundationDB transaction lifetime Transactions over five seconds from the first read are unsupported Hard · FoundationDB Usually transaction_too_old / not_committed; fdyno retries until its operation budget or returns an error Keep transaction callbacks short; page maintenance; reduce contention/load FDB
FoundationDB key / value Key: 10,000 bytes; value: 100,000 bytes Hard · FoundationDB FDB key/value-too-large error, normally mapped to ValidationException on data paths fdyno chunks item, index, stream, backup, restore, and receipt payloads; table metadata remains one value FDB · storage inventory
Number At most 38 significant digits; non-zero magnitude from 1E-130 through 9.9999999999999999999999999999999E+125, and the negative mirror Hard · fdyno validation / DynamoDB ValidationException for malformed/whitespace-bearing N strings, or a transaction cancellation reason where that API reports item validation per action; valid leading signs, exponent forms, and zero forms read back canonically Send exact decimal strings and validate before arithmetic code · precision tests · format tests · AWS
Secondary-index count 20 GSIs and 5 LSIs per table Hard · fdyno validation; DynamoDB's 20-GSI value is a default quota, fdyno's is not adjustable ValidationException during create/update Consolidate access patterns or denormalize data code · tests · AWS
INCLUDE projection 20 named non-key attributes per index; 100 occurrences summed across all GSIs/LSIs Hard · fdyno validation / DynamoDB ValidationException Use KEYS_ONLY/ALL where appropriate or reduce duplicate projections code · AWS
LSI item collection DynamoDB documents 10 GiB per partition-key item collection when LSIs exist; no equivalent aggregate fdyno validator was found Compatibility gap / cluster-dependent · fdyno Do not expect an early ItemCollectionSizeLimitExceededException; eventual constraints are FoundationDB capacity/transaction behavior Test large item collections and monitor storage; redesign hot/unbounded partitions AWS · evidence memo
Stream shard topology Default 1; fixed count 1–100 persisted per enabled generation Hard configuration range + generation immutability · fdyno Invalid environment defaults use 1; changing count requires a new empty generation and invalidates old iterators Choose before enablement; consume the persisted shards returned by DescribeStream code · Change streams
GetRecords page 1–1,000 records; default 1,000 Hard · fdyno validation / DynamoDB compatibility Out-of-range limit returns ValidationException Poll repeatedly and checkpoint the last durable sequence number code
Stream record storage Direct FDYNOC01 through 10,000 bytes; larger binary records use at most 1,024 chunks with a versioned manifest; legacy JSON records remain readable Hard · fdyno bounds and FoundationDB transaction size Oversized or corrupt records fail the operation; item, index, and record never commit partially Prefer KEYS_ONLY when transaction amplification matters; test maximum-shaped mutations code · storage inventory
Stream retention Unlimited growth when trimmer is off; when enabled, retention defaults to 24 hours and each pass examines a configurable bounded prefix (default 1,000 records per table/shard) Soft / configuration-dependent · fdyno Storage grows without bound when off; when enabled, a lagging consumer can lose trimmed records without an explicit gap error Set and capacity the trimmer, synchronize clocks, and monitor oldest record vs checkpoint externally startup · implementation
TTL visibility and reclamation Expired items are hidden on selected reads; bounded physical sweep starts by default at 1m and can be disabled with DYNODB_TTL_SWEEP_INTERVAL=off or 0 Soft / API- and configuration-dependent · fdyno GetItem, BatchGetItem, Query, and Scan hide expiry; disabled sweep leaves untouched expired storage; TransactGetItems and reviewed PartiQL reads do not apply the same filter Keep sweep enabled and monitor it; test every read API; never use physical deletion time as a correctness clock startup · TTL code · compatibility
Table backup snapshot No fixed table-size promise; all pages must remain readable at one pinned FoundationDB version Soft workflow boundary · data size/load/cluster dependent ValidationException when the read version ages out; no mixed-version backup is published Use fdyno backup only for bounded table copies; use FoundationDB-native backup for unbounded/DR workflows code · Backup & restore
Backup/restore memory and recovery One decoded and encoded backup page is held at a time; large restores use durable batches and resumable progress Soft workflow boundary · fdyno/host The request can end while recovery continues; a fenced target remains CREATING and unavailable until complete Wait for ACTIVE, validate before cutover, and monitor stale/failed jobs code · runbook
Foreground operation budget 30 seconds by default, configurable; retries and all workflow transactions share the HTTP request budget Soft configuration boundary · fdyno Deadline error; after a commit attempt the message states that outcome may be unknown Set client/server deadlines coherently; use a stable transaction token or reconcile state code · Reliable writes
Throughput, concurrency, table size/count No fdyno request-unit throttle, concurrency gate, or universal throughput/table-size promise Cluster-dependent · operator Saturation appears as latency, memory pressure, FDB errors, deadlines, or unavailability; this is not a reliable DynamoDB throttling signal Load-test the exact topology; add external admission control; monitor FoundationDB capacity and fault tolerance operations · current measurement scope · capacity code

Protocol and item boundaries

The 16 MiB body limit applies to every fdyno request, not only DynamoDB batch APIs. The body is bounded before signature verification and again after decompression, so a small compressed payload cannot expand without limit. A focused black-box test for the exact fdyno 16 MiB boundary has not been identified; existing manual-request tests cover oversized input and compression behavior.

The 400 KiB item check is logical DynamoDB sizing. fdyno then encodes and, for base storage, divides larger encoded values into 10,000-byte chunks. Chunking avoids FoundationDB's single-value ceiling but does not exempt the operation from the 10,000,000-byte affected-data limit, and it does not apply to every value type. Stream records are a counterexample.

Query and scan pagination is an API boundary, not a consistency lease. The next call starts after LastEvaluatedKey in a new FoundationDB read transaction. See Consistency model.

Batch and transactional boundaries

BatchWriteItem and TransactWriteItems have different failure contracts:

  • TransactWriteItems must fit one FoundationDB transaction. It is never split; an oversized physical transaction is rejected.
  • BatchWriteItem is non-atomic. fdyno first attempts one transaction. On FoundationDB transaction_too_large, it validates the whole request in a rolled- back transaction, estimates conservative chunks under a 4 MiB internal budget, and commits chunks separately. Runtime failures are returned in UnprocessedItems.

The 4 MiB transactional precheck is not a guarantee that a request will fit FoundationDB. Current code totals Put item bodies at that check. Update results, chunk keys, active index projections, binary stream records, metadata, idempotency state, and conflict ranges contribute to the physical transaction and can lower the effective ceiling. Test maximum-shaped requests with the same indexes and stream view as production.

FoundationDB transaction limits

FoundationDB defines transaction size as affected data, not only values written. Written keys, values, and ranges count; read keys/ranges and explicit conflict ranges also count, while values that are only read do not. Its documentation additionally advises redesigning transactions above one megabyte because they can hurt performance, even though the hard maximum is 10,000,000 bytes. Treat that one-megabyte statement as FoundationDB design guidance, not an fdyno validation threshold.

fdyno's 30-second default operation budget does not extend FoundationDB's five-second transaction lifetime. It permits retries and multi-transaction workflows to share a bounded request lifetime. The service maps FoundationDB error codes 2101–2103 (transaction, key, and value too large) to an actionable DynamoDB-shaped ValidationException on mapped data paths.

Numbers and indexes

Numbers are parsed and compared as exact decimal values rather than converted as a whole through float64. Accepted values are normalized, including exponent expansion and removal of insignificant zeroes. The limit still applies after arithmetic: an update that produces excess precision or magnitude fails rather than rounding silently.

The index-count limits are fdyno hard validations. This differs from AWS's service- quota model, where the documented 20-GSI value is a default that may be adjustable. fdyno also does not establish DynamoDB's aggregate 10 GiB LSI item-collection limit; its reported item-collection size metrics are not a substitute for enforcing or measuring that AWS storage boundary. AWS also documents a 400 KiB combined limit for a base item plus its corresponding LSI entries. fdyno's current item validator measures the logical item; no equivalent combined LSI-size validation was identified. The encoded index writes still count against FoundationDB's physical transaction limits.

Every index increases the physical transaction size. An ALL projection can duplicate most of an item in each index entry; an INCLUDE projection duplicates selected attributes. Count limits therefore do not imply that a maximum-size item with the maximum number of indexes fits one FoundationDB transaction.

Stream and TTL worker settings

DYNODB_STREAM_SHARDS is the process default for a newly enabled generation. fdyno stores the selected count in table metadata. The range 1–100 is an implementation limit, not a DynamoDB quota. Static shards add consumer parallelism but not commit capacity. Iterators do not expire on the server.

Retention and TTL reclamation are bounded background work rather than instantaneous guarantees. Their configured scan maximum is per pass, so a worker can fall behind when arrivals exceed sustained cleanup. Both rely on host wall clocks. Zero or negative durations are not safely rejected by all startup paths; validate deployment configuration before launching workers.

TTL read behavior is narrower than physical deletion. Selected reads hide an expired item immediately according to host time, then lazy cleanup or the sweeper rechecks expiry in the deleting transaction. A concurrent refresh is therefore not deleted by a stale sweep. Until deletion commits, storage and any API path that does not call the TTL filter can still encounter the row.

Backup and operational boundaries

fdyno table backup has no advertised maximum item count or byte size. Creation and restore use bounded decoded pages and verified chunks, but every source page must still read one pinned FoundationDB version before it ages out. fdyno fails rather than moving to a newer version mid-snapshot. This is a consistency-preserving failure, not a capacity promise.

Backup data is stored in the same FoundationDB database as the source. It shares the cluster's failure domain and does not supply a second disaster-recovery copy. Historical PITR is unsupported: enablement and restore fail explicitly rather than returning current state under a historical label.

There is no universal requests-per-second, concurrent-request, table-count, database-size, availability, RPO, or RTO number for fdyno. Those values depend on FoundationDB topology, storage engine, hardware, data distribution, conflict rate, item, index, and stream sizes, and external admission control. DescribeLimits returns fixed compatibility-shaped values; they are not enforced cluster capacity and are not repeated here.

Evidence sources and gaps

When sources disagree or cover different layers, interpret them in this order:

  • AWS DynamoDB constraints describe DynamoDB, not automatically fdyno.
  • The linked fdyno implementation and black-box tests establish current fdyno validation and behavior.
  • FoundationDB known limitations constrain the encoded transaction regardless of DynamoDB request validity.

These gaps require tests. Do not infer guarantees for them:

  1. No focused black-box test was located for the exact 16 MiB raw/decompressed body boundary.
  2. No systematic matrix measures physical transaction amplification at the exact FoundationDB limits across item size, index projection, and stream view.
  3. Static multi-shard streams lack a normal CI matrix across configured shard counts, and iterator expiration is absent.
  4. Backup snapshot expiry and interrupted restore behavior have no published tested size range.
  5. TTL filtering is not uniform across every read API in the reviewed code.
  6. No published benchmark establishes cluster-independent throughput or tail latency.

For related behavior and limits, continue with Guarantees, Tradeoffs, Transactions, and Deployment & operations.