DynamoDB deep dive: access patterns, financial authority, and recovery
Kinesis explained how records reach a consumer; this chapter asks what that consumer may safely commit and how the data will be queried. Start with the access-pattern inventory, follow each pattern into keys and indexes, then examine transactions, exact money, publication, capacity, and recovery. AP means access pattern, IDX names a key/index route, AMP names a write-amplification example, and L names a capacity lane. AP07 is the derived portfolio; AP12 is the authoritative balance/reservation boundary; AP16 is the semantic outbox.
Evidence notation: C identifies a claim in the claim register, A a dated AWS source, F a foundational source, and CS a finding in the repository case study. The source index supplies the full source details. These labels are lookup aids, not facts to memorize.
This chapter designs DynamoDB from explicit questions and invariants, not from an entity diagram or a one-table slogan. Alex DeBrie's method is the primary modeling authority: enumerate access patterns, shape item collections and indexes to answer them, then account for the operational trade-offs. The original Dynamo paper and the DynamoDB USENIX paper explain the distributed systems lineage; current AWS documentation controls mutable API behavior. The local SSE notes are prompts only and are corrected where they overreach.
The case used below is an intended repair target for the repository, not a claim that its current tables already implement this design. Canonical defects remain in the repository evidence map.
Access-pattern inventory: contract before schema
Section titled “Access-pattern inventory: contract before schema”Inference: Every proposed key below must answer one of these stable IDs. P95 rates are
design inputs for a workload test, not AWS guarantees. Size includes names,
types, keys, and projected attributes—not just the JSON payload. Key conditions
select the narrow set; filters may only reduce the returned set after read work
has occurred (C81; A111, F21,F22,F33–F35, retrieved 2026-08-22).
| AP | Operation | Key predicates | Sort, filter, order | Consistency / freshness | Cardinality and item size | Peak rate | Owner | Invariant | Failure response |
|---|---|---|---|---|---|---|---|---|---|
| AP01 | get order | tenant+orderId | exact/no filter | strong command;eventual history | 1x1.2KiB | 2000 read/s | Orders | tenant+version | retry/reconcile by ID |
| AP02 | list account orders | tenant+account+time | descending/no filter | eventual<=2s | 100x0.45KiB/page | 1200 query/s | Orders | deterministic order;not snapshot | continue LEK/surface lag |
| AP03 | list status orders | tenant+account+status+time | descending/sparse | eventual<=5s | active subset 0.35KiB | 400 query/s | Orders | terminal membership removed | verify base before action |
| AP04 | read order trades | tenant+orderId | ascending/no filter | strong for remaining qty | 1-20x0.9KiB | 1500 query/s | Execution | fills<=accepted qty | stop/reconcile |
| AP05 | list account trades | tenant+account+time | descending/no filter | eventual<=2s | 100x0.5KiB/page | 1000 query/s | Execution | fill resolves to source | paginate/repair |
| AP06 | list symbol trades | tenant+symbol+time | descending/no filter | eventual<=5s | 100x0.4KiB/page;1page/request | 2000 query/s;top share 8% | Execution | not sequencer | formula selects shard/merge cursor |
| AP07 | read portfolio view | tenant+account+optional symbol | lexical/no filter | eventual<=2s;rebuildable | 10-5000x0.8KiB | 3000 read/s | Portfolio projection | sourceVersion+gap visible | never authorize;rebuild |
| AP08 | claim request | tenant+client key | exact/no filter | strong immediate | 1x0.7KiB | 2000 write/s | Orders API | fingerprint one result | complete/in-progress/mismatch |
| AP09 | claim event inbox | consumer+eventId+shardVersion | exact/no filter | strong transactional | 2x<=1KiB (0.35KiB receipt+protected state) | 5000 write/s | Consumer | one effect/event | no-op/read/repair |
| AP10 | append ledger txn | tenant+account+month+bucket | ascending append | transactional | 2-20x0.6KiB;max2m/month;250k/bucket | 1500 tx/s | Ledger | balanced immutable | reject/reconcile |
| AP11 | read ledger | tenant+account+month+buckets | merge ascending/no filter | strong investigation | max2m/month;8x<=150000KiB | 300 query/s | Ledger | complete history | paginate bucket cursor/control totals |
| AP12 | authorize cash/securities balance+reservation | tenant+account+asset(currency-or-symbol) | exact/version | strong transactional | 1x0.8KiB | 2000 tx/s | Ledger/Risk command | available policy+version | conflict retry;never projection |
| AP13 | projection checkpoint | projection+source key+shardVersion | exact/version | strong | 1x0.3KiB | 5000 write/s | Projection | next once/gap visible | park/replay/rebuild |
| AP14 | create/read/list reconciliation batches | tenant+date;optional batchId | BATCH#batchId exact/prefix | strong transitions | 1-20KiB/batch | 20 batch/s | Finance Ops | manifest+window | fail/restart idempotently |
| AP15 | list due reconciliation discrepancies | tenant+status+shard;due<=cutoff | dueAt#batchId#id range | eventual discover;strong base resolve | 0-millionsx0.5KiB | 200 query/s | Finance Ops | owned resolution | paginate/escalate/conditional resolve |
| AP16 | create/claim/complete/retry outbox | eventId base;service+shard;due<=cutoff | base exact;READY GSI due order | eventual discover;strong conditional transitions | 1x1.6KiB+0.45KiB READY index | create5000/s;claim5100/s;complete5000/s;retry100/s;move20/s | Producer | state+event atomic;one owner | lease/retry/reconcile |
| AP17 | client order uniqueness | tenant+clientOrderId | exact/no filter | transactional condition | 1x0.2KiB | 2000 write/s | Orders | one ID mapping | return/reject mismatch |
| AP18 | idempotency repair queue | tenant+shard+due | due order/sparse | eventual discover;strong takeover | rare 0.3KiB | 100 query/s | Orders Ops | one repair lease | inspect/complete/escalate |
- AP
- AP01
- Operation
- get order
- Key predicates
- tenant+orderId
- Sort, filter, order
- exact/no filter
- Consistency / freshness
- strong command;eventual history
- Cardinality and item size
- 1x1.2KiB
- Peak rate
- 2000 read/s
- Owner
- Orders
- Invariant
- tenant+version
- Failure response
- retry/reconcile by ID
- AP
- AP02
- Operation
- list account orders
- Key predicates
- tenant+account+time
- Sort, filter, order
- descending/no filter
- Consistency / freshness
- eventual<=2s
- Cardinality and item size
- 100x0.45KiB/page
- Peak rate
- 1200 query/s
- Owner
- Orders
- Invariant
- deterministic order;not snapshot
- Failure response
- continue LEK/surface lag
- AP
- AP03
- Operation
- list status orders
- Key predicates
- tenant+account+status+time
- Sort, filter, order
- descending/sparse
- Consistency / freshness
- eventual<=5s
- Cardinality and item size
- active subset 0.35KiB
- Peak rate
- 400 query/s
- Owner
- Orders
- Invariant
- terminal membership removed
- Failure response
- verify base before action
- AP
- AP04
- Operation
- read order trades
- Key predicates
- tenant+orderId
- Sort, filter, order
- ascending/no filter
- Consistency / freshness
- strong for remaining qty
- Cardinality and item size
- 1-20x0.9KiB
- Peak rate
- 1500 query/s
- Owner
- Execution
- Invariant
- fills<=accepted qty
- Failure response
- stop/reconcile
- AP
- AP05
- Operation
- list account trades
- Key predicates
- tenant+account+time
- Sort, filter, order
- descending/no filter
- Consistency / freshness
- eventual<=2s
- Cardinality and item size
- 100x0.5KiB/page
- Peak rate
- 1000 query/s
- Owner
- Execution
- Invariant
- fill resolves to source
- Failure response
- paginate/repair
- AP
- AP06
- Operation
- list symbol trades
- Key predicates
- tenant+symbol+time
- Sort, filter, order
- descending/no filter
- Consistency / freshness
- eventual<=5s
- Cardinality and item size
- 100x0.4KiB/page;1page/request
- Peak rate
- 2000 query/s;top share 8%
- Owner
- Execution
- Invariant
- not sequencer
- Failure response
- formula selects shard/merge cursor
- AP
- AP07
- Operation
- read portfolio view
- Key predicates
- tenant+account+optional symbol
- Sort, filter, order
- lexical/no filter
- Consistency / freshness
- eventual<=2s;rebuildable
- Cardinality and item size
- 10-5000x0.8KiB
- Peak rate
- 3000 read/s
- Owner
- Portfolio projection
- Invariant
- sourceVersion+gap visible
- Failure response
- never authorize;rebuild
- AP
- AP08
- Operation
- claim request
- Key predicates
- tenant+client key
- Sort, filter, order
- exact/no filter
- Consistency / freshness
- strong immediate
- Cardinality and item size
- 1x0.7KiB
- Peak rate
- 2000 write/s
- Owner
- Orders API
- Invariant
- fingerprint one result
- Failure response
- complete/in-progress/mismatch
- AP
- AP09
- Operation
- claim event inbox
- Key predicates
- consumer+eventId+shardVersion
- Sort, filter, order
- exact/no filter
- Consistency / freshness
- strong transactional
- Cardinality and item size
- 2x<=1KiB (0.35KiB receipt+protected state)
- Peak rate
- 5000 write/s
- Owner
- Consumer
- Invariant
- one effect/event
- Failure response
- no-op/read/repair
- AP
- AP10
- Operation
- append ledger txn
- Key predicates
- tenant+account+month+bucket
- Sort, filter, order
- ascending append
- Consistency / freshness
- transactional
- Cardinality and item size
- 2-20x0.6KiB;max2m/month;250k/bucket
- Peak rate
- 1500 tx/s
- Owner
- Ledger
- Invariant
- balanced immutable
- Failure response
- reject/reconcile
- AP
- AP11
- Operation
- read ledger
- Key predicates
- tenant+account+month+buckets
- Sort, filter, order
- merge ascending/no filter
- Consistency / freshness
- strong investigation
- Cardinality and item size
- max2m/month;8x<=150000KiB
- Peak rate
- 300 query/s
- Owner
- Ledger
- Invariant
- complete history
- Failure response
- paginate bucket cursor/control totals
- AP
- AP12
- Operation
- authorize cash/securities balance+reservation
- Key predicates
- tenant+account+asset(currency-or-symbol)
- Sort, filter, order
- exact/version
- Consistency / freshness
- strong transactional
- Cardinality and item size
- 1x0.8KiB
- Peak rate
- 2000 tx/s
- Owner
- Ledger/Risk command
- Invariant
- available policy+version
- Failure response
- conflict retry;never projection
- AP
- AP13
- Operation
- projection checkpoint
- Key predicates
- projection+source key+shardVersion
- Sort, filter, order
- exact/version
- Consistency / freshness
- strong
- Cardinality and item size
- 1x0.3KiB
- Peak rate
- 5000 write/s
- Owner
- Projection
- Invariant
- next once/gap visible
- Failure response
- park/replay/rebuild
- AP
- AP14
- Operation
- create/read/list reconciliation batches
- Key predicates
- tenant+date;optional batchId
- Sort, filter, order
- BATCH#batchId exact/prefix
- Consistency / freshness
- strong transitions
- Cardinality and item size
- 1-20KiB/batch
- Peak rate
- 20 batch/s
- Owner
- Finance Ops
- Invariant
- manifest+window
- Failure response
- fail/restart idempotently
- AP
- AP15
- Operation
- list due reconciliation discrepancies
- Key predicates
- tenant+status+shard;due<=cutoff
- Sort, filter, order
- dueAt#batchId#id range
- Consistency / freshness
- eventual discover;strong base resolve
- Cardinality and item size
- 0-millionsx0.5KiB
- Peak rate
- 200 query/s
- Owner
- Finance Ops
- Invariant
- owned resolution
- Failure response
- paginate/escalate/conditional resolve
- AP
- AP16
- Operation
- create/claim/complete/retry outbox
- Key predicates
- eventId base;service+shard;due<=cutoff
- Sort, filter, order
- base exact;READY GSI due order
- Consistency / freshness
- eventual discover;strong conditional transitions
- Cardinality and item size
- 1x1.6KiB+0.45KiB READY index
- Peak rate
- create5000/s;claim5100/s;complete5000/s;retry100/s;move20/s
- Owner
- Producer
- Invariant
- state+event atomic;one owner
- Failure response
- lease/retry/reconcile
- AP
- AP17
- Operation
- client order uniqueness
- Key predicates
- tenant+clientOrderId
- Sort, filter, order
- exact/no filter
- Consistency / freshness
- transactional condition
- Cardinality and item size
- 1x0.2KiB
- Peak rate
- 2000 write/s
- Owner
- Orders
- Invariant
- one ID mapping
- Failure response
- return/reject mismatch
- AP
- AP18
- Operation
- idempotency repair queue
- Key predicates
- tenant+shard+due
- Sort, filter, order
- due order/sparse
- Consistency / freshness
- eventual discover;strong takeover
- Cardinality and item size
- rare 0.3KiB
- Peak rate
- 100 query/s
- Owner
- Orders Ops
- Invariant
- one repair lease
- Failure response
- inspect/complete/escalate
The inventory deliberately separates command-current reads from eventual listing projections. A GSI cannot satisfy a strong-read requirement; an AP that authorizes a financial action therefore returns to the base item or ledger authority (C82; A19,A100, retrieved 2026-08-22).
Inference: AP07 is only a stale-tolerant portfolio projection. Even a strongly consistent read of that derived table would make only the stored copy current; it would not make the copy authoritative. Cash, securities quantities, and reservations used by risk or order admission are AP12 state owned by the Ledger/Risk command boundary; AP07 carries source versions/gaps and rebuilds from authority (C46,C91; A19,A32–A35, retrieved 2026-08-22; F08,F17,F21).
Key and index design with AP traceability
Section titled “Key and index design with AP traceability”The inventory states the question; the key design must answer it without silently changing freshness or ownership. Follow the get-order and list-order patterns first: the authoritative item and the eventual history index can share data while serving different decisions. Then carry the same distinction through every proposed index and its write cost.
Inference: The bounded-context table is the working default here because it
aligns service ownership and recovery while retaining one-request item
collections inside a context (C94; F21,F22). It is not one table per entity:
Orders, Execution, Portfolio, Ledger, Reconciliation, and consumer-owned Inbox
tables each overload their base PK/SK only within an owned vocabulary.
| Path | Kind | Table | PK | SK | Role | Read consequence | AP IDs |
|---|---|---|---|---|---|---|---|
| IDX01 | BASE | Orders | TEN#t#ORDER#id | META | aggregate root | strong/eventual | AP01 |
| IDX02 | GSI1 | Orders | TEN#t#ACCT#a | ORD#at#id | projected summary | eventual | AP02 |
| IDX03 | GSI2 | Orders | TEN#t#ACCT#a#STATUS#s | ORD#at#id | sparse moved membership | eventual | AP03 |
| IDX04 | BASE | Execution | TEN#t#ORDER#id | TRADE#at#id | item collection | strong/eventual | AP04 |
| IDX05 | GSI1 | Execution | TEN#t#ACCT#a | TRADE#at#id | projected summary | eventual | AP05 |
| IDX06 | GSI2 | Execution | TEN#t#SYM#symbol | TRADE#at#id | unsharded at 800RRU/s top-key assumption | eventual | AP06 |
| IDX07 | BASE | Portfolio | TEN#t#ACCT#a | POS#symbol | rebuildable view collection | eventual only | AP07 |
| IDX08 | BASE | Idempotency | TEN#t#REQ#key | REQUEST | state/result | strong | AP08 |
| IDX09 | BASE | Inbox | CONSUMER#name#V#v#SHARD#h(eventId)%13 | EVENT#id | deterministic 13-shard dedupe receipt | strong transactional | AP09 |
| IDX10 | BASE | Ledger | TEN#t#ACCT#a#MONTH#yyyy-mm#BKT#nn | POST#at#txn#line | sequence-range sub-bucket | strong/eventual | AP10,AP11 |
| IDX11 | BASE | Ledger | TEN#t#ACCT#a | AUTH#CASH#currency or AUTH#SEC#symbol | cash/securities authority | strong | AP12 |
| IDX12 | BASE | Projection | PROJ#name#V#v#SHARD#h(sourceKey)%7 | SOURCE#key | deterministic 7-shard checkpoint/gap | strong | AP13 |
| IDX13 | BASE | Reconciliation | TEN#t#RECON#date | BATCH#batchId | batch list/exact | strong | AP14 |
| IDX14 | BASE | Reconciliation | TEN#t#RECON#batchId | BREAK#id | discrepancy authority | strong | AP15 |
| IDX15 | GSI1 | Reconciliation | TEN#t#BREAK#status#shard | DUE#at#batch#id | sparse cross-batch due queue | eventual | AP15 |
| IDX16 | BASE | Context | OUTBOX#eventId | EVENT | semantic envelope | strong | AP16 |
| IDX17 | GSI3 | Context | SERVICE#svc#READY#shard | DUE#at#eventId | sparse 13-shard READY due queue | eventual | AP16 |
| IDX18 | BASE | Orders | TEN#t#CLIENTORDER#id | UNIQUE | sentinel | transactional | AP17 |
| IDX19 | GSI1 | Idempotency | TEN#t#REPAIR#shard | DUE#at#key | sparse repair | eventual+strong takeover | AP18 |
- Path
- IDX01
- Kind
- BASE
- Table
- Orders
- PK
- TEN#t#ORDER#id
- SK
- META
- Role
- aggregate root
- Read consequence
- strong/eventual
- AP IDs
- AP01
- Path
- IDX02
- Kind
- GSI1
- Table
- Orders
- PK
- TEN#t#ACCT#a
- SK
- ORD#at#id
- Role
- projected summary
- Read consequence
- eventual
- AP IDs
- AP02
- Path
- IDX03
- Kind
- GSI2
- Table
- Orders
- PK
- TEN#t#ACCT#a#STATUS#s
- SK
- ORD#at#id
- Role
- sparse moved membership
- Read consequence
- eventual
- AP IDs
- AP03
- Path
- IDX04
- Kind
- BASE
- Table
- Execution
- PK
- TEN#t#ORDER#id
- SK
- TRADE#at#id
- Role
- item collection
- Read consequence
- strong/eventual
- AP IDs
- AP04
- Path
- IDX05
- Kind
- GSI1
- Table
- Execution
- PK
- TEN#t#ACCT#a
- SK
- TRADE#at#id
- Role
- projected summary
- Read consequence
- eventual
- AP IDs
- AP05
- Path
- IDX06
- Kind
- GSI2
- Table
- Execution
- PK
- TEN#t#SYM#symbol
- SK
- TRADE#at#id
- Role
- unsharded at 800RRU/s top-key assumption
- Read consequence
- eventual
- AP IDs
- AP06
- Path
- IDX07
- Kind
- BASE
- Table
- Portfolio
- PK
- TEN#t#ACCT#a
- SK
- POS#symbol
- Role
- rebuildable view collection
- Read consequence
- eventual only
- AP IDs
- AP07
- Path
- IDX08
- Kind
- BASE
- Table
- Idempotency
- PK
- TEN#t#REQ#key
- SK
- REQUEST
- Role
- state/result
- Read consequence
- strong
- AP IDs
- AP08
- Path
- IDX09
- Kind
- BASE
- Table
- Inbox
- PK
- CONSUMER#name#V#v#SHARD#h(eventId)%13
- SK
- EVENT#id
- Role
- deterministic 13-shard dedupe receipt
- Read consequence
- strong transactional
- AP IDs
- AP09
- Path
- IDX10
- Kind
- BASE
- Table
- Ledger
- PK
- TEN#t#ACCT#a#MONTH#yyyy-mm#BKT#nn
- SK
- POST#at#txn#line
- Role
- sequence-range sub-bucket
- Read consequence
- strong/eventual
- AP IDs
- AP10,AP11
- Path
- IDX11
- Kind
- BASE
- Table
- Ledger
- PK
- TEN#t#ACCT#a
- SK
- AUTH#CASH#currency or AUTH#SEC#symbol
- Role
- cash/securities authority
- Read consequence
- strong
- AP IDs
- AP12
- Path
- IDX12
- Kind
- BASE
- Table
- Projection
- PK
- PROJ#name#V#v#SHARD#h(sourceKey)%7
- SK
- SOURCE#key
- Role
- deterministic 7-shard checkpoint/gap
- Read consequence
- strong
- AP IDs
- AP13
- Path
- IDX13
- Kind
- BASE
- Table
- Reconciliation
- PK
- TEN#t#RECON#date
- SK
- BATCH#batchId
- Role
- batch list/exact
- Read consequence
- strong
- AP IDs
- AP14
- Path
- IDX14
- Kind
- BASE
- Table
- Reconciliation
- PK
- TEN#t#RECON#batchId
- SK
- BREAK#id
- Role
- discrepancy authority
- Read consequence
- strong
- AP IDs
- AP15
- Path
- IDX15
- Kind
- GSI1
- Table
- Reconciliation
- PK
- TEN#t#BREAK#status#shard
- SK
- DUE#at#batch#id
- Role
- sparse cross-batch due queue
- Read consequence
- eventual
- AP IDs
- AP15
- Path
- IDX16
- Kind
- BASE
- Table
- Context
- PK
- OUTBOX#eventId
- SK
- EVENT
- Role
- semantic envelope
- Read consequence
- strong
- AP IDs
- AP16
- Path
- IDX17
- Kind
- GSI3
- Table
- Context
- PK
- SERVICE#svc#READY#shard
- SK
- DUE#at#eventId
- Role
- sparse 13-shard READY due queue
- Read consequence
- eventual
- AP IDs
- AP16
- Path
- IDX18
- Kind
- BASE
- Table
- Orders
- PK
- TEN#t#CLIENTORDER#id
- SK
- UNIQUE
- Role
- sentinel
- Read consequence
- transactional
- AP IDs
- AP17
- Path
- IDX19
- Kind
- GSI1
- Table
- Idempotency
- PK
- TEN#t#REPAIR#shard
- SK
- DUE#at#key
- Role
- sparse repair
- Read consequence
- eventual+strong takeover
- AP IDs
- AP18
Inference: No LSI is proposed. The order/fill and account/position item collections are bounded or period-bucketed where they can grow. An LSI would freeze an alternate sort key at table creation and impose the current 10 GB item-collection limit; a GSI is operationally independent but eventually consistent and can throttle base writes when underprovisioned or hot (C86; A104, retrieved 2026-08-22).
The adjacency-list technique is justified only for true one-to-many reads: AP04 order→fills and AP07 account→portfolio-view positions. Symbol and account histories use GSIs because duplicating all reverse edges as base items would increase transaction size and ownership ambiguity. All tenant-bearing partition keys place tenant identity first for policy review but keep the naturally high-cardinality order/account/symbol identifier; a low-cardinality status is never the sole partition key.
Machine-readable AP, path, and amplification contract
Section titled “Machine-readable AP, path, and amplification contract”The model details retain the exact source records for checking calculations. The reader tables show the important chain: an access pattern selects a route, a logical operation creates base/index work, and that work lands on a physical lane. Read amplification totals together with lane feasibility; a distributed receipt index does not prove that the protected account item can sustain the same load.
The verifier treats this block as the canonical model and cross-checks every
field in the three rendered tables. base and index are already-rounded write
units per logical operation; only transaction-targeted base-item writes use base-multiplier=2.
Asynchronous GSI entries always use index-multiplier=1. Storage consequences
are called out even when the operation is read-only.
Model details · task6 model
AP|AP01|get order|tenant+orderId|exact/no filter|strong command;eventual history|1x1.2KiB|2000 read/s|Orders|tenant+version|retry/reconcile by IDAP|AP02|list account orders|tenant+account+time|descending/no filter|eventual<=2s|100x0.45KiB/page|1200 query/s|Orders|deterministic order;not snapshot|continue LEK/surface lagAP|AP03|list status orders|tenant+account+status+time|descending/sparse|eventual<=5s|active subset 0.35KiB|400 query/s|Orders|terminal membership removed|verify base before actionAP|AP04|read order trades|tenant+orderId|ascending/no filter|strong for remaining qty|1-20x0.9KiB|1500 query/s|Execution|fills<=accepted qty|stop/reconcileAP|AP05|list account trades|tenant+account+time|descending/no filter|eventual<=2s|100x0.5KiB/page|1000 query/s|Execution|fill resolves to source|paginate/repairAP|AP06|list symbol trades|tenant+symbol+time|descending/no filter|eventual<=5s|100x0.4KiB/page;1page/request|2000 query/s;top share 8%|Execution|not sequencer|formula selects shard/merge cursorAP|AP07|read portfolio view|tenant+account+optional symbol|lexical/no filter|eventual<=2s;rebuildable|10-5000x0.8KiB|3000 read/s|Portfolio projection|sourceVersion+gap visible|never authorize;rebuildAP|AP08|claim request|tenant+client key|exact/no filter|strong immediate|1x0.7KiB|2000 write/s|Orders API|fingerprint one result|complete/in-progress/mismatchAP|AP09|claim event inbox|consumer+eventId+shardVersion|exact/no filter|strong transactional|2x<=1KiB (0.35KiB receipt+protected state)|5000 write/s|Consumer|one effect/event|no-op/read/repairAP|AP10|append ledger txn|tenant+account+month+bucket|ascending append|transactional|2-20x0.6KiB;max2m/month;250k/bucket|1500 tx/s|Ledger|balanced immutable|reject/reconcileAP|AP11|read ledger|tenant+account+month+buckets|merge ascending/no filter|strong investigation|max2m/month;8x<=150000KiB|300 query/s|Ledger|complete history|paginate bucket cursor/control totalsAP|AP12|authorize cash/securities balance+reservation|tenant+account+asset(currency-or-symbol)|exact/version|strong transactional|1x0.8KiB|2000 tx/s|Ledger/Risk command|available policy+version|conflict retry;never projectionAP|AP13|projection checkpoint|projection+source key+shardVersion|exact/version|strong|1x0.3KiB|5000 write/s|Projection|next once/gap visible|park/replay/rebuildAP|AP14|create/read/list reconciliation batches|tenant+date;optional batchId|BATCH#batchId exact/prefix|strong transitions|1-20KiB/batch|20 batch/s|Finance Ops|manifest+window|fail/restart idempotentlyAP|AP15|list due reconciliation discrepancies|tenant+status+shard;due<=cutoff|dueAt#batchId#id range|eventual discover;strong base resolve|0-millionsx0.5KiB|200 query/s|Finance Ops|owned resolution|paginate/escalate/conditional resolveAP|AP16|create/claim/complete/retry outbox|eventId base;service+shard;due<=cutoff|base exact;READY GSI due order|eventual discover;strong conditional transitions|1x1.6KiB+0.45KiB READY index|create5000/s;claim5100/s;complete5000/s;retry100/s;move20/s|Producer|state+event atomic;one owner|lease/retry/reconcileAP|AP17|client order uniqueness|tenant+clientOrderId|exact/no filter|transactional condition|1x0.2KiB|2000 write/s|Orders|one ID mapping|return/reject mismatchAP|AP18|idempotency repair queue|tenant+shard+due|due order/sparse|eventual discover;strong takeover|rare 0.3KiB|100 query/s|Orders Ops|one repair lease|inspect/complete/escalateINDEX|IDX01|BASE|Orders|TEN#t#ORDER#id|META|aggregate root|strong/eventual|AP01INDEX|IDX02|GSI1|Orders|TEN#t#ACCT#a|ORD#at#id|projected summary|eventual|AP02INDEX|IDX03|GSI2|Orders|TEN#t#ACCT#a#STATUS#s|ORD#at#id|sparse moved membership|eventual|AP03INDEX|IDX04|BASE|Execution|TEN#t#ORDER#id|TRADE#at#id|item collection|strong/eventual|AP04INDEX|IDX05|GSI1|Execution|TEN#t#ACCT#a|TRADE#at#id|projected summary|eventual|AP05INDEX|IDX06|GSI2|Execution|TEN#t#SYM#symbol|TRADE#at#id|unsharded at 800RRU/s top-key assumption|eventual|AP06INDEX|IDX07|BASE|Portfolio|TEN#t#ACCT#a|POS#symbol|rebuildable view collection|eventual only|AP07INDEX|IDX08|BASE|Idempotency|TEN#t#REQ#key|REQUEST|state/result|strong|AP08INDEX|IDX09|BASE|Inbox|CONSUMER#name#V#v#SHARD#h(eventId)%13|EVENT#id|deterministic 13-shard dedupe receipt|strong transactional|AP09INDEX|IDX10|BASE|Ledger|TEN#t#ACCT#a#MONTH#yyyy-mm#BKT#nn|POST#at#txn#line|sequence-range sub-bucket|strong/eventual|AP10,AP11INDEX|IDX11|BASE|Ledger|TEN#t#ACCT#a|AUTH#CASH#currency or AUTH#SEC#symbol|cash/securities authority|strong|AP12INDEX|IDX12|BASE|Projection|PROJ#name#V#v#SHARD#h(sourceKey)%7|SOURCE#key|deterministic 7-shard checkpoint/gap|strong|AP13INDEX|IDX13|BASE|Reconciliation|TEN#t#RECON#date|BATCH#batchId|batch list/exact|strong|AP14INDEX|IDX14|BASE|Reconciliation|TEN#t#RECON#batchId|BREAK#id|discrepancy authority|strong|AP15INDEX|IDX15|GSI1|Reconciliation|TEN#t#BREAK#status#shard|DUE#at#batch#id|sparse cross-batch due queue|eventual|AP15INDEX|IDX16|BASE|Context|OUTBOX#eventId|EVENT|semantic envelope|strong|AP16INDEX|IDX17|GSI3|Context|SERVICE#svc#READY#shard|DUE#at#eventId|sparse 13-shard READY due queue|eventual|AP16INDEX|IDX18|BASE|Orders|TEN#t#CLIENTORDER#id|UNIQUE|sentinel|transactional|AP17INDEX|IDX19|GSI1|Idempotency|TEN#t#REPAIR#shard|DUE#at#key|sparse repair|eventual+strong takeover|AP18MAP|AP01|IDX01MAP|AP02|IDX02MAP|AP03|IDX03MAP|AP04|IDX04MAP|AP05|IDX05MAP|AP06|IDX06MAP|AP07|IDX07MAP|AP08|IDX08MAP|AP09|IDX09MAP|AP10|IDX10MAP|AP11|IDX10MAP|AP12|IDX11MAP|AP13|IDX12MAP|AP14|IDX13MAP|AP15|IDX14,IDX15MAP|AP16|IDX16,IDX17MAP|AP17|IDX18MAP|AP18|IDX19LANE|L01|AP01|IDX01|2000 read/s|READ|2000|1|NA|NA|2400|NA|LOAD_TEST_REQUIRED|max-order share is not measuredLANE|L02|AP02|IDX02|1200 query/s|READ|1200|6|NA|NA|2400|NA|LOAD_TEST_REQUIRED|max-account share is not measuredLANE|L03|AP03|IDX03|400 query/s|READ|400|0.5|NA|NA|2400|NA|LOAD_TEST_REQUIRED|evaluated page and max account-status share are not measuredLANE|L04|AP04|IDX04|1500 query/s|READ|1500|5|NA|NA|2400|NA|LOAD_TEST_REQUIRED|max-order share and fill-count mix are not measuredLANE|L05|AP05|IDX05|1000 query/s|READ|1000|6.5|NA|NA|2400|NA|LOAD_TEST_REQUIRED|max-account share is not measuredLANE|L06|AP06|IDX06|2000 query/s;top share 8%|READ|2000|5|0.08|1|2400|800.0|FEASIBLE_PLANNING|explicit top-symbol share and one-page assumptionLANE|L07|AP07|IDX07|3000 read/s|READ|3000|0.5|NA|NA|2400|NA|LOAD_TEST_REQUIRED|optional-symbol versus whole-account page mix is not measuredLANE|L08|AP08|IDX08|2000 write/s|WRITE|2000|2|NA|NA|800|NA|LOAD_TEST_REQUIRED|max-client-key lane and lifecycle mix are not measuredLANE|L09A|AP09|IDX09|5000 write/s|WRITE|5000|2|1|13|800|769.23|FEASIBLE_PLANNING|fixed consumer scope hashes eventId over versioned shardsLANE|L09B|AP09|PROTECTED_STATE_AP_REQUIRED|5000 write/s|WRITE|5000|2|NA|NA|800|NA|UNPROVEN|consumer must bind protected state to its own registered AP laneLANE|L10|AP10|IDX10|1500 tx/s|WRITE|1500|6|NA|NA|800|NA|LOAD_TEST_REQUIRED|AMP07 three-item scenario; max-account-month share and posting-count mix are not measuredLANE|L11|AP11|IDX10|300 query/s|READ|300|1|NA|NA|2400|NA|LOAD_TEST_REQUIRED|max-account share and evaluated page bytes are not measuredLANE|L12|AP12|IDX11|2000 tx/s|WRITE|2000|2|NA|NA|800|NA|LOAD_TEST_REQUIRED|max-account-asset share is not measuredLANE|L13|AP13|IDX12|5000 write/s|WRITE|5000|1|1|7|800|714.29|FEASIBLE_PLANNING|fixed projection scope hashes sourceKey over versioned shardsLANE|L14|AP14|IDX13|20 batch/s|WRITE|20|20|NA|NA|800|NA|LOAD_TEST_REQUIRED|read-write mix and hottest tenant-date share are not measuredLANE|L15A|AP15|IDX14|200 query/s|READ|200|0.5|NA|NA|2400|NA|LOAD_TEST_REQUIRED|base-resolution and page-byte mix are not measuredLANE|L15B|AP15|IDX15|200 query/s|READ|200|0.5|NA|NA|2400|NA|LOAD_TEST_REQUIRED|status-shard count and hottest due-queue share are not measuredLANE|L16A|AP16|IDX16|create5000/s;claim5100/s;complete5000/s;retry100/s;move20/s|WRITE|40440|1|NA|NA|800|NA|LOAD_TEST_REQUIRED|base work spans event keys but max physical-key placement is not measuredLANE|L16B|AP16|IDX17|create5000/s;claim5100/s;complete5000/s;retry100/s;move20/s|WRITE|10240|1|1|13|800|787.69|FEASIBLE_PLANNING|full READY lifecycle hashes eventId over thirteen shardsLANE|L17|AP17|IDX18|2000 write/s|WRITE|2000|2|NA|NA|800|NA|LOAD_TEST_REQUIRED|max-tenant-client-order share is not measuredLANE|L18|AP18|IDX19|100 query/s|READ|100|0.5|NA|NA|2400|NA|LOAD_TEST_REQUIRED|repair shard count and hottest due-queue share are not measuredAMP|AMP01|AP01,AP02|order create|2|1|1|1|3|base+account GSIAMP|AMP02|AP03|order status key move|2|1|2|1|4|old delete+new put;lagAMP|AMP03|AP04,AP05,AP06|trade+two GSIs|1|1|2|1|3|three representationsAMP|AMP04|AP07|portfolio view update|1|1|0|1|1|derived storageAMP|AMP05|AP08,AP17|request+sentinel transaction|2|2|0|1|4|two targeted base itemsAMP|AMP06|AP09|inbox receipt+protected state|2|2|0|1|4|atomic receipt+effectAMP|AMP07|AP10,AP12|two postings+authority transaction|3|2|0|1|6|immutable ledger growthAMP|AMP08|AP11|ledger read only|0|1|0|1|0|bucket pagination/storageAMP|AMP09|AP13|checkpoint update|1|1|0|1|1|version stateAMP|AMP10|AP14|batch metadata|1|1|0|1|1|manifest storageAMP|AMP11|AP15|discrepancy+due GSI|1|1|1|1|2|base authority+eventual queueAMP|AMP12|AP16|outbox create+READY insert|2|2|1|1|5|transactional base+async insertAMP|AMP13|AP18|failed state+repair GSI|1|1|1|1|2|sparse until repairedAMP|AMP14|AP01,AP02,AP03,AP08,AP16,AP17|accepted_order_v1 complete route|6|2|3|1|15|4 base targets+3 async GSI entriesAMP|AMP15|AP16|READY claim+index removal|2|1|1|1|3|ordinary base update+async deleteAMP|AMP16|AP16|IN_FLIGHT completion|2|1|0|1|2|ordinary base update;no index entryAMP|AMP17|AP16|IN_FLIGHT retry+READY insert|2|1|1|1|3|ordinary base update+async insertAMP|AMP18|AP16|READY due/shard reschedule|2|1|2|1|4|ordinary base update+index delete+put| Amplification | AP IDs | Scenario | Rounded base units | Base multiplier | Rounded GSI units | GSI multiplier | Total units | Consequence |
|---|---|---|---|---|---|---|---|---|
| AMP01 | AP01,AP02 | order create | 2 | 1 | 1 | 1 | 3 | base+account GSI |
| AMP02 | AP03 | order status key move | 2 | 1 | 2 | 1 | 4 | old delete+new put;lag |
| AMP03 | AP04,AP05,AP06 | trade+two GSIs | 1 | 1 | 2 | 1 | 3 | three representations |
| AMP04 | AP07 | portfolio view update | 1 | 1 | 0 | 1 | 1 | derived storage |
| AMP05 | AP08,AP17 | request+sentinel transaction | 2 | 2 | 0 | 1 | 4 | two targeted base items |
| AMP06 | AP09 | inbox receipt+protected state | 2 | 2 | 0 | 1 | 4 | atomic receipt+effect |
| AMP07 | AP10,AP12 | two postings+authority transaction | 3 | 2 | 0 | 1 | 6 | immutable ledger growth |
| AMP08 | AP11 | ledger read only | 0 | 1 | 0 | 1 | 0 | bucket pagination/storage |
| AMP09 | AP13 | checkpoint update | 1 | 1 | 0 | 1 | 1 | version state |
| AMP10 | AP14 | batch metadata | 1 | 1 | 0 | 1 | 1 | manifest storage |
| AMP11 | AP15 | discrepancy+due GSI | 1 | 1 | 1 | 1 | 2 | base authority+eventual queue |
| AMP12 | AP16 | outbox create+READY insert | 2 | 2 | 1 | 1 | 5 | transactional base+async insert |
| AMP13 | AP18 | failed state+repair GSI | 1 | 1 | 1 | 1 | 2 | sparse until repaired |
| AMP14 | AP01,AP02,AP03,AP08,AP16,AP17 | accepted_order_v1 complete route | 6 | 2 | 3 | 1 | 15 | 4 base targets+3 async GSI entries |
| AMP15 | AP16 | READY claim+index removal | 2 | 1 | 1 | 1 | 3 | ordinary base update+async delete |
| AMP16 | AP16 | IN_FLIGHT completion | 2 | 1 | 0 | 1 | 2 | ordinary base update;no index entry |
| AMP17 | AP16 | IN_FLIGHT retry+READY insert | 2 | 1 | 1 | 1 | 3 | ordinary base update+async insert |
| AMP18 | AP16 | READY due/shard reschedule | 2 | 1 | 2 | 1 | 4 | ordinary base update+index delete+put |
- Amplification
- AMP01
- AP IDs
- AP01,AP02
- Scenario
- order create
- Rounded base units
- 2
- Base multiplier
- 1
- Rounded GSI units
- 1
- GSI multiplier
- 1
- Total units
- 3
- Consequence
- base+account GSI
- Amplification
- AMP02
- AP IDs
- AP03
- Scenario
- order status key move
- Rounded base units
- 2
- Base multiplier
- 1
- Rounded GSI units
- 2
- GSI multiplier
- 1
- Total units
- 4
- Consequence
- old delete+new put;lag
- Amplification
- AMP03
- AP IDs
- AP04,AP05,AP06
- Scenario
- trade+two GSIs
- Rounded base units
- 1
- Base multiplier
- 1
- Rounded GSI units
- 2
- GSI multiplier
- 1
- Total units
- 3
- Consequence
- three representations
- Amplification
- AMP04
- AP IDs
- AP07
- Scenario
- portfolio view update
- Rounded base units
- 1
- Base multiplier
- 1
- Rounded GSI units
- 0
- GSI multiplier
- 1
- Total units
- 1
- Consequence
- derived storage
- Amplification
- AMP05
- AP IDs
- AP08,AP17
- Scenario
- request+sentinel transaction
- Rounded base units
- 2
- Base multiplier
- 2
- Rounded GSI units
- 0
- GSI multiplier
- 1
- Total units
- 4
- Consequence
- two targeted base items
- Amplification
- AMP06
- AP IDs
- AP09
- Scenario
- inbox receipt+protected state
- Rounded base units
- 2
- Base multiplier
- 2
- Rounded GSI units
- 0
- GSI multiplier
- 1
- Total units
- 4
- Consequence
- atomic receipt+effect
- Amplification
- AMP07
- AP IDs
- AP10,AP12
- Scenario
- two postings+authority transaction
- Rounded base units
- 3
- Base multiplier
- 2
- Rounded GSI units
- 0
- GSI multiplier
- 1
- Total units
- 6
- Consequence
- immutable ledger growth
- Amplification
- AMP08
- AP IDs
- AP11
- Scenario
- ledger read only
- Rounded base units
- 0
- Base multiplier
- 1
- Rounded GSI units
- 0
- GSI multiplier
- 1
- Total units
- 0
- Consequence
- bucket pagination/storage
- Amplification
- AMP09
- AP IDs
- AP13
- Scenario
- checkpoint update
- Rounded base units
- 1
- Base multiplier
- 1
- Rounded GSI units
- 0
- GSI multiplier
- 1
- Total units
- 1
- Consequence
- version state
- Amplification
- AMP10
- AP IDs
- AP14
- Scenario
- batch metadata
- Rounded base units
- 1
- Base multiplier
- 1
- Rounded GSI units
- 0
- GSI multiplier
- 1
- Total units
- 1
- Consequence
- manifest storage
- Amplification
- AMP11
- AP IDs
- AP15
- Scenario
- discrepancy+due GSI
- Rounded base units
- 1
- Base multiplier
- 1
- Rounded GSI units
- 1
- GSI multiplier
- 1
- Total units
- 2
- Consequence
- base authority+eventual queue
- Amplification
- AMP12
- AP IDs
- AP16
- Scenario
- outbox create+READY insert
- Rounded base units
- 2
- Base multiplier
- 2
- Rounded GSI units
- 1
- GSI multiplier
- 1
- Total units
- 5
- Consequence
- transactional base+async insert
- Amplification
- AMP13
- AP IDs
- AP18
- Scenario
- failed state+repair GSI
- Rounded base units
- 1
- Base multiplier
- 1
- Rounded GSI units
- 1
- GSI multiplier
- 1
- Total units
- 2
- Consequence
- sparse until repaired
- Amplification
- AMP14
- AP IDs
- AP01,AP02,AP03,AP08,AP16,AP17
- Scenario
- accepted_order_v1 complete route
- Rounded base units
- 6
- Base multiplier
- 2
- Rounded GSI units
- 3
- GSI multiplier
- 1
- Total units
- 15
- Consequence
- 4 base targets+3 async GSI entries
- Amplification
- AMP15
- AP IDs
- AP16
- Scenario
- READY claim+index removal
- Rounded base units
- 2
- Base multiplier
- 1
- Rounded GSI units
- 1
- GSI multiplier
- 1
- Total units
- 3
- Consequence
- ordinary base update+async delete
- Amplification
- AMP16
- AP IDs
- AP16
- Scenario
- IN_FLIGHT completion
- Rounded base units
- 2
- Base multiplier
- 1
- Rounded GSI units
- 0
- GSI multiplier
- 1
- Total units
- 2
- Consequence
- ordinary base update;no index entry
- Amplification
- AMP17
- AP IDs
- AP16
- Scenario
- IN_FLIGHT retry+READY insert
- Rounded base units
- 2
- Base multiplier
- 1
- Rounded GSI units
- 1
- GSI multiplier
- 1
- Total units
- 3
- Consequence
- ordinary base update+async insert
- Amplification
- AMP18
- AP IDs
- AP16
- Scenario
- READY due/shard reschedule
- Rounded base units
- 2
- Base multiplier
- 1
- Rounded GSI units
- 2
- GSI multiplier
- 1
- Total units
- 4
- Consequence
- ordinary base update+index delete+put
The lane contract below is deliberately conservative. It covers every AP and
every mapped base/index route. A numeric FEASIBLE_PLANNING row has an
independently recomputed rate * rounded-units * max-key-share / shards result;
an unmeasured distribution remains LOAD_TEST_REQUIRED or UNPROVEN rather
than borrowing table-average or adaptive-capacity headroom. NA therefore
means “the interview design still needs a key histogram/load test,” not zero.
| Lane | AP | Route | AP peak-rate contract | Unit kind | Rate/s | Rounded units/op | Max-key share | Shards | Target units/s | Load/shard | State | Distribution evidence |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| L01 | AP01 | IDX01 | 2000 read/s | READ | 2000 | 1 | NA | NA | 2400 | NA | LOAD_TEST_REQUIRED | max-order share is not measured |
| L02 | AP02 | IDX02 | 1200 query/s | READ | 1200 | 6 | NA | NA | 2400 | NA | LOAD_TEST_REQUIRED | max-account share is not measured |
| L03 | AP03 | IDX03 | 400 query/s | READ | 400 | 0.5 | NA | NA | 2400 | NA | LOAD_TEST_REQUIRED | evaluated page and max account-status share are not measured |
| L04 | AP04 | IDX04 | 1500 query/s | READ | 1500 | 5 | NA | NA | 2400 | NA | LOAD_TEST_REQUIRED | max-order share and fill-count mix are not measured |
| L05 | AP05 | IDX05 | 1000 query/s | READ | 1000 | 6.5 | NA | NA | 2400 | NA | LOAD_TEST_REQUIRED | max-account share is not measured |
| L06 | AP06 | IDX06 | 2000 query/s;top share 8% | READ | 2000 | 5 | 0.08 | 1 | 2400 | 800.0 | FEASIBLE_PLANNING | explicit top-symbol share and one-page assumption |
| L07 | AP07 | IDX07 | 3000 read/s | READ | 3000 | 0.5 | NA | NA | 2400 | NA | LOAD_TEST_REQUIRED | optional-symbol versus whole-account page mix is not measured |
| L08 | AP08 | IDX08 | 2000 write/s | WRITE | 2000 | 2 | NA | NA | 800 | NA | LOAD_TEST_REQUIRED | max-client-key lane and lifecycle mix are not measured |
| L09A | AP09 | IDX09 | 5000 write/s | WRITE | 5000 | 2 | 1 | 13 | 800 | 769.23 | FEASIBLE_PLANNING | fixed consumer scope hashes eventId over versioned shards |
| L09B | AP09 | PROTECTED_STATE_AP_REQUIRED | 5000 write/s | WRITE | 5000 | 2 | NA | NA | 800 | NA | UNPROVEN | consumer must bind protected state to its own registered AP lane |
| L10 | AP10 | IDX10 | 1500 tx/s | WRITE | 1500 | 6 | NA | NA | 800 | NA | LOAD_TEST_REQUIRED | AMP07 three-item scenario; max-account-month share and posting-count mix are not measured |
| L11 | AP11 | IDX10 | 300 query/s | READ | 300 | 1 | NA | NA | 2400 | NA | LOAD_TEST_REQUIRED | max-account share and evaluated page bytes are not measured |
| L12 | AP12 | IDX11 | 2000 tx/s | WRITE | 2000 | 2 | NA | NA | 800 | NA | LOAD_TEST_REQUIRED | max-account-asset share is not measured |
| L13 | AP13 | IDX12 | 5000 write/s | WRITE | 5000 | 1 | 1 | 7 | 800 | 714.29 | FEASIBLE_PLANNING | fixed projection scope hashes sourceKey over versioned shards |
| L14 | AP14 | IDX13 | 20 batch/s | WRITE | 20 | 20 | NA | NA | 800 | NA | LOAD_TEST_REQUIRED | read-write mix and hottest tenant-date share are not measured |
| L15A | AP15 | IDX14 | 200 query/s | READ | 200 | 0.5 | NA | NA | 2400 | NA | LOAD_TEST_REQUIRED | base-resolution and page-byte mix are not measured |
| L15B | AP15 | IDX15 | 200 query/s | READ | 200 | 0.5 | NA | NA | 2400 | NA | LOAD_TEST_REQUIRED | status-shard count and hottest due-queue share are not measured |
| L16A | AP16 | IDX16 | create5000/s;claim5100/s;complete5000/s;retry100/s;move20/s | WRITE | 40440 | 1 | NA | NA | 800 | NA | LOAD_TEST_REQUIRED | base work spans event keys but max physical-key placement is not measured |
| L16B | AP16 | IDX17 | create5000/s;claim5100/s;complete5000/s;retry100/s;move20/s | WRITE | 10240 | 1 | 1 | 13 | 800 | 787.69 | FEASIBLE_PLANNING | full READY lifecycle hashes eventId over thirteen shards |
| L17 | AP17 | IDX18 | 2000 write/s | WRITE | 2000 | 2 | NA | NA | 800 | NA | LOAD_TEST_REQUIRED | max-tenant-client-order share is not measured |
| L18 | AP18 | IDX19 | 100 query/s | READ | 100 | 0.5 | NA | NA | 2400 | NA | LOAD_TEST_REQUIRED | repair shard count and hottest due-queue share are not measured |
- Lane
- L01
- AP
- AP01
- Route
- IDX01
- AP peak-rate contract
- 2000 read/s
- Unit kind
- READ
- Rate/s
- 2000
- Rounded units/op
- 1
- Max-key share
- NA
- Shards
- NA
- Target units/s
- 2400
- Load/shard
- NA
- State
- LOAD_TEST_REQUIRED
- Distribution evidence
- max-order share is not measured
- Lane
- L02
- AP
- AP02
- Route
- IDX02
- AP peak-rate contract
- 1200 query/s
- Unit kind
- READ
- Rate/s
- 1200
- Rounded units/op
- 6
- Max-key share
- NA
- Shards
- NA
- Target units/s
- 2400
- Load/shard
- NA
- State
- LOAD_TEST_REQUIRED
- Distribution evidence
- max-account share is not measured
- Lane
- L03
- AP
- AP03
- Route
- IDX03
- AP peak-rate contract
- 400 query/s
- Unit kind
- READ
- Rate/s
- 400
- Rounded units/op
- 0.5
- Max-key share
- NA
- Shards
- NA
- Target units/s
- 2400
- Load/shard
- NA
- State
- LOAD_TEST_REQUIRED
- Distribution evidence
- evaluated page and max account-status share are not measured
- Lane
- L04
- AP
- AP04
- Route
- IDX04
- AP peak-rate contract
- 1500 query/s
- Unit kind
- READ
- Rate/s
- 1500
- Rounded units/op
- 5
- Max-key share
- NA
- Shards
- NA
- Target units/s
- 2400
- Load/shard
- NA
- State
- LOAD_TEST_REQUIRED
- Distribution evidence
- max-order share and fill-count mix are not measured
- Lane
- L05
- AP
- AP05
- Route
- IDX05
- AP peak-rate contract
- 1000 query/s
- Unit kind
- READ
- Rate/s
- 1000
- Rounded units/op
- 6.5
- Max-key share
- NA
- Shards
- NA
- Target units/s
- 2400
- Load/shard
- NA
- State
- LOAD_TEST_REQUIRED
- Distribution evidence
- max-account share is not measured
- Lane
- L06
- AP
- AP06
- Route
- IDX06
- AP peak-rate contract
- 2000 query/s;top share 8%
- Unit kind
- READ
- Rate/s
- 2000
- Rounded units/op
- 5
- Max-key share
- 0.08
- Shards
- 1
- Target units/s
- 2400
- Load/shard
- 800.0
- State
- FEASIBLE_PLANNING
- Distribution evidence
- explicit top-symbol share and one-page assumption
- Lane
- L07
- AP
- AP07
- Route
- IDX07
- AP peak-rate contract
- 3000 read/s
- Unit kind
- READ
- Rate/s
- 3000
- Rounded units/op
- 0.5
- Max-key share
- NA
- Shards
- NA
- Target units/s
- 2400
- Load/shard
- NA
- State
- LOAD_TEST_REQUIRED
- Distribution evidence
- optional-symbol versus whole-account page mix is not measured
- Lane
- L08
- AP
- AP08
- Route
- IDX08
- AP peak-rate contract
- 2000 write/s
- Unit kind
- WRITE
- Rate/s
- 2000
- Rounded units/op
- 2
- Max-key share
- NA
- Shards
- NA
- Target units/s
- 800
- Load/shard
- NA
- State
- LOAD_TEST_REQUIRED
- Distribution evidence
- max-client-key lane and lifecycle mix are not measured
- Lane
- L09A
- AP
- AP09
- Route
- IDX09
- AP peak-rate contract
- 5000 write/s
- Unit kind
- WRITE
- Rate/s
- 5000
- Rounded units/op
- 2
- Max-key share
- 1
- Shards
- 13
- Target units/s
- 800
- Load/shard
- 769.23
- State
- FEASIBLE_PLANNING
- Distribution evidence
- fixed consumer scope hashes eventId over versioned shards
- Lane
- L09B
- AP
- AP09
- Route
- PROTECTED_STATE_AP_REQUIRED
- AP peak-rate contract
- 5000 write/s
- Unit kind
- WRITE
- Rate/s
- 5000
- Rounded units/op
- 2
- Max-key share
- NA
- Shards
- NA
- Target units/s
- 800
- Load/shard
- NA
- State
- UNPROVEN
- Distribution evidence
- consumer must bind protected state to its own registered AP lane
- Lane
- L10
- AP
- AP10
- Route
- IDX10
- AP peak-rate contract
- 1500 tx/s
- Unit kind
- WRITE
- Rate/s
- 1500
- Rounded units/op
- 6
- Max-key share
- NA
- Shards
- NA
- Target units/s
- 800
- Load/shard
- NA
- State
- LOAD_TEST_REQUIRED
- Distribution evidence
- AMP07 three-item scenario; max-account-month share and posting-count mix are not measured
- Lane
- L11
- AP
- AP11
- Route
- IDX10
- AP peak-rate contract
- 300 query/s
- Unit kind
- READ
- Rate/s
- 300
- Rounded units/op
- 1
- Max-key share
- NA
- Shards
- NA
- Target units/s
- 2400
- Load/shard
- NA
- State
- LOAD_TEST_REQUIRED
- Distribution evidence
- max-account share and evaluated page bytes are not measured
- Lane
- L12
- AP
- AP12
- Route
- IDX11
- AP peak-rate contract
- 2000 tx/s
- Unit kind
- WRITE
- Rate/s
- 2000
- Rounded units/op
- 2
- Max-key share
- NA
- Shards
- NA
- Target units/s
- 800
- Load/shard
- NA
- State
- LOAD_TEST_REQUIRED
- Distribution evidence
- max-account-asset share is not measured
- Lane
- L13
- AP
- AP13
- Route
- IDX12
- AP peak-rate contract
- 5000 write/s
- Unit kind
- WRITE
- Rate/s
- 5000
- Rounded units/op
- 1
- Max-key share
- 1
- Shards
- 7
- Target units/s
- 800
- Load/shard
- 714.29
- State
- FEASIBLE_PLANNING
- Distribution evidence
- fixed projection scope hashes sourceKey over versioned shards
- Lane
- L14
- AP
- AP14
- Route
- IDX13
- AP peak-rate contract
- 20 batch/s
- Unit kind
- WRITE
- Rate/s
- 20
- Rounded units/op
- 20
- Max-key share
- NA
- Shards
- NA
- Target units/s
- 800
- Load/shard
- NA
- State
- LOAD_TEST_REQUIRED
- Distribution evidence
- read-write mix and hottest tenant-date share are not measured
- Lane
- L15A
- AP
- AP15
- Route
- IDX14
- AP peak-rate contract
- 200 query/s
- Unit kind
- READ
- Rate/s
- 200
- Rounded units/op
- 0.5
- Max-key share
- NA
- Shards
- NA
- Target units/s
- 2400
- Load/shard
- NA
- State
- LOAD_TEST_REQUIRED
- Distribution evidence
- base-resolution and page-byte mix are not measured
- Lane
- L15B
- AP
- AP15
- Route
- IDX15
- AP peak-rate contract
- 200 query/s
- Unit kind
- READ
- Rate/s
- 200
- Rounded units/op
- 0.5
- Max-key share
- NA
- Shards
- NA
- Target units/s
- 2400
- Load/shard
- NA
- State
- LOAD_TEST_REQUIRED
- Distribution evidence
- status-shard count and hottest due-queue share are not measured
- Lane
- L16A
- AP
- AP16
- Route
- IDX16
- AP peak-rate contract
- create5000/s;claim5100/s;complete5000/s;retry100/s;move20/s
- Unit kind
- WRITE
- Rate/s
- 40440
- Rounded units/op
- 1
- Max-key share
- NA
- Shards
- NA
- Target units/s
- 800
- Load/shard
- NA
- State
- LOAD_TEST_REQUIRED
- Distribution evidence
- base work spans event keys but max physical-key placement is not measured
- Lane
- L16B
- AP
- AP16
- Route
- IDX17
- AP peak-rate contract
- create5000/s;claim5100/s;complete5000/s;retry100/s;move20/s
- Unit kind
- WRITE
- Rate/s
- 10240
- Rounded units/op
- 1
- Max-key share
- 1
- Shards
- 13
- Target units/s
- 800
- Load/shard
- 787.69
- State
- FEASIBLE_PLANNING
- Distribution evidence
- full READY lifecycle hashes eventId over thirteen shards
- Lane
- L17
- AP
- AP17
- Route
- IDX18
- AP peak-rate contract
- 2000 write/s
- Unit kind
- WRITE
- Rate/s
- 2000
- Rounded units/op
- 2
- Max-key share
- NA
- Shards
- NA
- Target units/s
- 800
- Load/shard
- NA
- State
- LOAD_TEST_REQUIRED
- Distribution evidence
- max-tenant-client-order share is not measured
- Lane
- L18
- AP
- AP18
- Route
- IDX19
- AP peak-rate contract
- 100 query/s
- Unit kind
- READ
- Rate/s
- 100
- Rounded units/op
- 0.5
- Max-key share
- NA
- Shards
- NA
- Target units/s
- 2400
- Load/shard
- NA
- State
- LOAD_TEST_REQUIRED
- Distribution evidence
- repair shard count and hottest due-queue share are not measured
Table-boundary decision: three defensible shapes
Section titled “Table-boundary decision: three defensible shapes”Inference: Single-table design's strongest benefit is not “fewer tables.” It is answering a heterogeneous, related access pattern in one request. The cost is that shared key/index vocabulary becomes an API among teams, and an unforeseen query may require reshaping or asynchronous projection. Start with APs and ownership, not doctrine (C81; A111, F21,F22,F33–F35, retrieved 2026-08-22).
| Dimension | One mega-table | Single table per bounded context | Multiple entity tables |
|---|---|---|---|
| Request shape | Excellent for cross-entity item collections with one owner | One-request aggregates within Orders, Execution, or Ledger | Batch/transaction or application composition across entities |
| Deployment coupling | Shared index/key changes coordinate every writer | Context team coordinates only its vocabulary | Lowest schema coupling; more orchestration |
| Transaction scope | Same-table is convenient but not uniquely capable | Cross-context transaction is available inside the current same-account, same-Region boundary | Same current cross-table boundary; more table names and IAM resources |
| Ownership / IAM | Broad table permissions and shared stream are hard to isolate | Clear owner, narrow IAM, dedicated stream/alarms | Clearest entity IAM; ownership can become too granular |
| Blast radius / scaling | One hot index, restore, or bad deploy affects all contexts | Context-local capacity, hot keys, restore, and alarms | Smallest table blast radius; more fleet overhead |
| Backup / restore | Restoring one context means restoring a new copy of everything and extracting | Restore context table and rebuild only its projections | Fine-grained restores; cross-table recovery needs a manifest/cutover |
| Observability | Table averages hide context/AP attribution unless every request is tagged | AP metrics align to one service and indexes | Clear table metrics but many dashboards |
| Streams | One mixed change feed requires type filtering and shared evolution | Context-owned CDC/outbox relay | Multiple event-source mappings and checkpoints |
| Cognitive complexity | Highest global key/index grammar | Moderate, cohesive grammar per domain | Simple schemas; complex cross-table workflows |
| Best fit | One team, stable related APs, high value from mixed item collection | Several domain owners with rich aggregates | Independent entities, distinct lifecycle/security/scale, relational composition elsewhere |
- Dimension
- Request shape
- One mega-table
- Excellent for cross-entity item collections with one owner
- Single table per bounded context
- One-request aggregates within Orders, Execution, or Ledger
- Multiple entity tables
- Batch/transaction or application composition across entities
- Dimension
- Deployment coupling
- One mega-table
- Shared index/key changes coordinate every writer
- Single table per bounded context
- Context team coordinates only its vocabulary
- Multiple entity tables
- Lowest schema coupling; more orchestration
- Dimension
- Transaction scope
- One mega-table
- Same-table is convenient but not uniquely capable
- Single table per bounded context
- Cross-context transaction is available inside the current same-account, same-Region boundary
- Multiple entity tables
- Same current cross-table boundary; more table names and IAM resources
- Dimension
- Ownership / IAM
- One mega-table
- Broad table permissions and shared stream are hard to isolate
- Single table per bounded context
- Clear owner, narrow IAM, dedicated stream/alarms
- Multiple entity tables
- Clearest entity IAM; ownership can become too granular
- Dimension
- Blast radius / scaling
- One mega-table
- One hot index, restore, or bad deploy affects all contexts
- Single table per bounded context
- Context-local capacity, hot keys, restore, and alarms
- Multiple entity tables
- Smallest table blast radius; more fleet overhead
- Dimension
- Backup / restore
- One mega-table
- Restoring one context means restoring a new copy of everything and extracting
- Single table per bounded context
- Restore context table and rebuild only its projections
- Multiple entity tables
- Fine-grained restores; cross-table recovery needs a manifest/cutover
- Dimension
- Observability
- One mega-table
- Table averages hide context/AP attribution unless every request is tagged
- Single table per bounded context
- AP metrics align to one service and indexes
- Multiple entity tables
- Clear table metrics but many dashboards
- Dimension
- Streams
- One mega-table
- One mixed change feed requires type filtering and shared evolution
- Single table per bounded context
- Context-owned CDC/outbox relay
- Multiple entity tables
- Multiple event-source mappings and checkpoints
- Dimension
- Cognitive complexity
- One mega-table
- Highest global key/index grammar
- Single table per bounded context
- Moderate, cohesive grammar per domain
- Multiple entity tables
- Simple schemas; complex cross-table workflows
- Dimension
- Best fit
- One mega-table
- One team, stable related APs, high value from mixed item collection
- Single table per bounded context
- Several domain owners with rich aggregates
- Multiple entity tables
- Independent entities, distinct lifecycle/security/scale, relational composition elsewhere
TransactWriteItems and TransactGetItems currently accept up to 100 distinct
items and 4 MB across one or more tables in the same account and Region; a
write transaction cannot target the same item twice. Indexes themselves are
not transaction targets. This means “transactions require one DynamoDB table”
is false, although cross-Region/cross-account coordination remains outside this
boundary (C83; A20,A101, retrieved 2026-08-22).
Inference: The bounded-context table is the selected shape for this case, but keep a decision record. It minimizes shared deployment/IAM/Stream/restore blast radius while preserving AP04 and AP07 item collections; use a cross-table transaction only when a truly synchronous invariant spans owned tables and its 100-item/4 MB ceiling is acceptable (C94; F21,F22).
Concurrency, transactions, uniqueness, and durable idempotency
Section titled “Concurrency, transactions, uniqueness, and durable idempotency”Conditions and versions
Section titled “Conditions and versions”Inference: Use attribute_not_exists(PK) for deterministic creation and a condition such
as version = :expected AND state = :allowed for compare-and-set transitions.
Return the new version as part of the command result. Optimistic locking stops
a stale writer; it does not recognize that two different messages represent
the same business event. An inbox receipt supplies that identity boundary
(C93; A101,A110, retrieved 2026-08-22).
Inference: For AP17, transactionally condition-create
TEN#t#CLIENTORDER#clientOrderId / UNIQUE with its mapped orderId and create
the order. A concurrent claimant loses the condition and then reads the
sentinel: same fingerprint returns the existing order, different fingerprint
is a conflict. A pre-read followed by an unconditional write has a race (C93;
A101,A110, retrieved 2026-08-22).
Transactions consume capacity even when canceled, and their changes propagate
to GSIs, Streams, backups, and exports gradually. ClientRequestToken gives
identical TransactWriteItems calls a ten-minute idempotency window; altered
parameters cause a mismatch. That API feature is useful for a short retry but
is not the permanent record of an accepted order (C83; A20,A101, retrieved 2026-08-22).
AP08 durable request state machine
Section titled “AP08 durable request state machine”Inference: Store the following record, not merely a cached 201 response
(C90; A20,A101, retrieved 2026-08-22; F11):
PK = TEN#<tenant>#REQ#<clientKey>, SK = REQUESTfingerprint = SHA-256(canonical command fields + tenant + operation + schema version)state = IN_PROGRESS | COMPLETED | REPAIR_REQUIREDattemptOwner, leaseUntil, createdAt, updatedAtresult = {orderId, acceptedVersion, responseCode, responseDigest}effect = {orderId, transactionId, outboxEventId}expiresAt = cleanup time only- Canonicalize the command and hash it. Conditionally create
IN_PROGRESSwith a short lease; never use the TTL timestamp as the lease decision. - A same-key/different-fingerprint request is
409 Conflict. It must not inherit another command's result. - A concurrent same-fingerprint duplicate reads strongly:
COMPLETEDreturns the durable result; a liveIN_PROGRESSreturns retry guidance; an expired lease can be conditionally taken over by one owner. - In one transaction, validate the lease/fingerprint, write order and
uniqueness sentinel, write the semantic outbox item, and set
COMPLETEDwith the durable response. If table boundaries make one transaction unsuitable, make the authoritative effect deterministically discoverable and move toREPAIR_REQUIRED; never pretend a partial dual write completed. - The repair worker strongly rereads the record and protected effect. It completes from evidence, safely reattempts a deterministic absent effect, or escalates an ambiguous external effect. TTL may later remove a record only after the business replay/audit horizon.
Inference: AP09 applies the same principle at each consumer: target the
receipt and the consumer's protected state in one TransactWriteItems call.
The receipt key is
CONSUMER#name#V#v#SHARD#h(businessEventId)%13 / EVENT#businessEventId;
both sub-1-KiB base items therefore cost 2 * 2 = 4 WRU/event in this planning
case. The receipt lane alone costs two WRU/event, or 10,000 WRU/s at 5,000
events/s; ceil(10000/(1000*0.80))=13 gives 769.23 WRU/s/shard. The protected
state does not magically share that receipt distribution: its table/key must
name another AP-specific lane, histogram, and capacity proof. Store source
aggregate/version and effect receipt. Transport message IDs are diagnostics,
not the durable business identity (C90,C87; A20,A22,A101,A105, retrieved
2026-08-22; F11,F24,F32,F33).
Do not change N in place. Here h is a contract, not a runtime hash: use the
unsigned first 64 bits of SHA-256 over the canonical UTF-8 business key, and
store hashVersion with shardMapVersion. A shard-map version selects the hash for each new
business event; retries retain the original version. During cutover, route
lookups by recorded version (or check the bounded old/new versions), stop old
admission at a declared watermark, drain and reconcile both maps, and retain
old receipts through the deduplication horizon. The cost is version metadata,
dual-version reads during cutover, and operational reconciliation; the benefit
is a deterministic capacity argument rather than a hope that opaque
split-for-heat/adaptive behavior will hold the 80% target.
Money, ledger authority, projections, and reconciliation
Section titled “Money, ledger authority, projections, and reconciliation”The application currently moves JavaScript number values through order,
trade, and portfolio paths. Authoritative financial amounts must not use
binary floating point. Choose one representation per field:
- fixed minor units as an integer plus ISO currency and explicit scale; or
- DynamoDB
Numberserialized/deserialized with an exact decimal library, never through a binary-float intermediate.
Define an explicit rounding policy: rounding mode, rounding point, precision, fee/tax allocation, currency conversion rate identity, and residual handling in the contract. “Two decimal places” is not enough for instruments, quantities, FX, or currencies with different scales (C47; A41, F08,F17, retrieved 2026-08-22).
Inference: A ledger transaction uses one deterministic txnId; immutable
posting rows carry account, currency, signed exact amount, effective/recorded
times, source business ID, and posting line. Validate that debits and credits
balance by currency before a transaction writes all postings and conditionally
updates the versioned AP12 AUTH#CASH#currency or AUTH#SEC#symbol
authority/reservations. DynamoDB supplies
conditional/transactional storage; the application supplies chart-of-accounts,
balancing, authorization, immutability, rounding, and reversal semantics (C91;
F08,F17,F21).
Never update a posting. Correct an error with a linked reversing/correcting transaction. A current balance is a compact authority only when its version and control total are updated with postings; a portfolio, P&L, OpenSearch document, or cache remains derived. Reservation state distinguishes posted, reserved, and available amounts so two commands cannot spend one balance.
Inference: AP13 projection records enforce source version n = current+1.
n <= current is a duplicate/stale no-op; n > current+1 records a gap and
parks the update. Reconciliation compares source order/fill IDs, ledger posting
IDs, balances, and projection versions for a declared window, emits AP15
discrepancies, and requires evidence before a conditional resolution. This is
the correctness backstop; DynamoDB alone does not supply accounting semantics
(C91; F08,F17,F21).
Inference: The checkpoint PK is
PROJ#name#V#v#SHARD#h(sourceKey)%7 / SOURCE#sourceKey. At 5,000 ordinary
sub-1-KiB conditional writes/s, N=ceil(5000/(1000*0.80))=7, or 714.29
WRU/s/shard. Hashing the stable sourceKey preserves next-version ordering for
that source; it deliberately does not promise one total order across unrelated
sources. Whole-projection scans/listing now fan out seven keyed queries and
merge source watermarks. Reshard with the same versioned map, admission
watermark, drain, gap/control-total reconciliation, and conditional cutover
used for AP09; retries must not silently switch versions (C87,C95;
A22,A100,A105, retrieved 2026-08-22; F24,F32,F33).
DynamoDB Streams and semantic outbox events
Section titled “DynamoDB Streams and semantic outbox events”The financial transaction has established what is true locally. The next boundary is telling other services about that committed result. Raw item changes may be enough for some consumers; when consumers need one stable business fact from a multi-item transaction, the outbox supplies that explicit envelope. Follow its full lifecycle, because claim, retry, completion, and index movement all add work.
Inference: Treat Streams as short-lived CDC. Current retention is 24 hours;
ordering covers mutations to each individual item primary key, not every item
in a partition-key collection or a business transaction. View choices are
KEYS_ONLY, NEW_IMAGE, OLD_IMAGE, and NEW_AND_OLD_IMAGES; choose the
smallest view that still supports repair; NEW_AND_OLD_IMAGES supplies old and new images.
Lambda delivery is at-least-once and may
process a record repeatedly (C84; A21,A102, retrieved 2026-08-22).
Transaction item changes can arrive at different times and interleave with
other changes. A consumer therefore must not infer one business event by
grouping nearby order/sentinel/idempotency records. NEW_AND_OLD_IMAGES helps
derive transitions but increases record size and still does not supply a
semantic envelope (C83; A101, retrieved 2026-08-22).
Inference: AP16 writes one explicit outbox event item in the same local
transaction as the accepted state. It contains stable eventId, aggregate ID
and version, event type/schema version, occurred time, trace/causation IDs, and
the consumer contract payload. Its exact state machine is:
ABSENT -> READY: the transaction creates the base item withreadyPk,readySk=DUE#dueAt#eventId, attempt zero, and no lease; the sparse GSI gets one insert.READY -> IN_FLIGHT: a conditional claim checks state/version and an absent or expired lease, sets owner/lease/attempt, and removes both READY key attributes; the GSI gets one delete.IN_FLIGHT -> COMPLETED: only the lease owner conditionally stores the durable broker acknowledgement and completion time; READY attributes are already absent, so the GSI has no action.IN_FLIGHT -> READY: a failed publish or expired-lease repair conditionally clears owner/lease, records the failure, chooses a newdueAt, and restores READY attributes; the GSI gets one insert.READY -> READY: a deliberate due/shard reschedule conditionally changes an indexed key, so GSI maintenance is one old-key delete plus one new-key put.
Inference: Every stale/repeated transition condition-fails and reads the durable state; an ambiguous broker acknowledgement can therefore repeat publication, and consumers still use AP09. This repairs the dual-write gap without claiming end-to-end exactly once. The current GSI accounting for a sub-1-KiB entry is one put when indexed attributes appear, one delete when they disappear, and delete+put when an indexed key changes (C84,C95; A21,A102,A104, retrieved 2026-08-22).
Checkpointing within the 24-hour window supports ordinary retry, not indefinite rebuild. A projection that falls behind retention needs a PITR-backed export or another versioned full source, followed by catch-up and a measured cutover. Keep unpublished outbox items longer than the maximum outage/replay policy; the Stream is not the durable event archive.
Capacity, skew, and auditable amplification
Section titled “Capacity, skew, and auditable amplification”The full formulas and mutation-tested inputs are in the
shared cost model.
Current rounding is API-specific: standard writes round each item to 1 KiB;
standard strong reads round evaluated bytes to 4 KiB, eventual reads use half,
and each transaction-targeted base-item write uses two underlying write operations.
Indexes are not transaction targets; asynchronous GSI maintenance adds ordinary
index write units after commit. Query consumption is
based on evaluated bytes before filtering; BatchGetItem rounds each item
separately (C82,C83; A100,A101,A104, retrieved 2026-08-22).
| Result ID | Result | Consequence |
|---|---|---|
| standard_write_units | 2 | 1.2KiB crosses two 1KiB buckets |
| base_plus_index_units | 3 | base2+ordinary GSI1 |
| moved_index_units | 4 | base2+old delete1+new put1 |
| strong_read_units | 3 | 10KiB/4KiB rounded |
| eventual_read_units | 1.5 | half standard strong |
| transactional_read_units | 6 | two underlying reads |
| query_eventual_units | 3 | 24,000B evaluated before filter |
| batch_eventual_units | 1.5 | each item rounds separately |
| accepted_order_v1_base_txn_units | 12 | four targeted base items |
| accepted_order_v1_gsi_units | 3 | two order GSIs+READY GSI ordinary cost |
| accepted_order_v1_total_units | 15 | 12 base transaction+3 async GSI |
| ap06_page_kib | 40 | one 100x0.4KiB page/request |
| ap06_eventual_rru_per_page | 5 | half of ten 4KiB chunks |
| ap06_aggregate_rru_s | 10000 | 2000 requests/s x5 |
| ap06_top_symbol_rru_s | 800 | planning top share 8% |
| ap06_shards | 1 | ceil(800/(3000x0.80)) |
| ap09_atomic_path_wru_per_event | 4 | two transaction-targeted <=1KiB base items x2 |
| ap09_receipt_wru_per_event | 2 | receipt item alone uses transaction multiplier |
| ap09_receipt_aggregate_wru_s | 10000 | 5000 receipt writes/s x2 |
| ap09_receipt_shards | 13 | ceil(10000/(1000x0.80)) |
| ap09_receipt_per_shard_wru_s | 769.23 | 10000/13 |
| ap09_receipt_headroom_percent | 3.85 | below 800 WCU/s target |
| ap13_checkpoint_wru_per_event | 1 | ordinary conditional <=1KiB write |
| ap13_checkpoint_aggregate_wru_s | 5000 | 5000 checkpoint writes/s x1 |
| ap13_checkpoint_shards | 7 | ceil(5000/(1000x0.80)) |
| ap13_checkpoint_per_shard_wru_s | 714.29 | 5000/7 |
| ap13_checkpoint_headroom_percent | 10.71 | below 800 WCU/s target |
| ap16_create_base_wru_s | 20000 | 5000xceil(1.6KiB)x2 transaction ops |
| ap16_claim_base_wru_s | 10200 | 5100xceil(1.6KiB) ordinary update |
| ap16_complete_base_wru_s | 10000 | 5000xceil(1.6KiB) ordinary update |
| ap16_retry_base_wru_s | 200 | 100xceil(1.6KiB) ordinary update |
| ap16_reschedule_base_wru_s | 40 | 20xceil(1.6KiB) ordinary update |
| ap16_base_total_wru_s | 40440 | create+claim+complete+retry+reschedule |
| ap16_ready_create_insert_wru_s | 5000 | 5000 READY inserts x1 |
| ap16_ready_claim_delete_wru_s | 5100 | 5100 READY removals x1 |
| ap16_ready_retry_insert_wru_s | 100 | 100 retry READY inserts x1 |
| ap16_ready_reschedule_move_wru_s | 40 | 20 READY key moves x(delete+put) |
| ap16_no_retry_move_floor_index_wru_s | 10000 | 5000 create inserts+5000 claim deletes |
| ap16_ready_index_wru_s | 10240 | all sparse-index lifecycle actions |
| ap16_ready_shards | 13 | ceil(10240/(1000x0.80)) |
| ap16_per_shard_wru_s | 787.69 | 10240/13 |
| ap16_headroom_percent | 1.54 | below 800 WCU/s target |
| ap16_total_lifecycle_wru_s | 50680 | base40440+READY index10240 |
| ledger_month_kib | 1200000 | 2m postings x0.6KiB |
| ledger_sub_buckets | 8 | count and byte ceilings agree |
| ledger_bucket_max_mib | 146.48 | 150000KiB/1024 |
- Result ID
- standard_write_units
- Result
- 2
- Consequence
- 1.2KiB crosses two 1KiB buckets
- Result ID
- base_plus_index_units
- Result
- 3
- Consequence
- base2+ordinary GSI1
- Result ID
- moved_index_units
- Result
- 4
- Consequence
- base2+old delete1+new put1
- Result ID
- strong_read_units
- Result
- 3
- Consequence
- 10KiB/4KiB rounded
- Result ID
- eventual_read_units
- Result
- 1.5
- Consequence
- half standard strong
- Result ID
- transactional_read_units
- Result
- 6
- Consequence
- two underlying reads
- Result ID
- query_eventual_units
- Result
- 3
- Consequence
- 24,000B evaluated before filter
- Result ID
- batch_eventual_units
- Result
- 1.5
- Consequence
- each item rounds separately
- Result ID
- accepted_order_v1_base_txn_units
- Result
- 12
- Consequence
- four targeted base items
- Result ID
- accepted_order_v1_gsi_units
- Result
- 3
- Consequence
- two order GSIs+READY GSI ordinary cost
- Result ID
- accepted_order_v1_total_units
- Result
- 15
- Consequence
- 12 base transaction+3 async GSI
- Result ID
- ap06_page_kib
- Result
- 40
- Consequence
- one 100x0.4KiB page/request
- Result ID
- ap06_eventual_rru_per_page
- Result
- 5
- Consequence
- half of ten 4KiB chunks
- Result ID
- ap06_aggregate_rru_s
- Result
- 10000
- Consequence
- 2000 requests/s x5
- Result ID
- ap06_top_symbol_rru_s
- Result
- 800
- Consequence
- planning top share 8%
- Result ID
- ap06_shards
- Result
- 1
- Consequence
- ceil(800/(3000x0.80))
- Result ID
- ap09_atomic_path_wru_per_event
- Result
- 4
- Consequence
- two transaction-targeted <=1KiB base items x2
- Result ID
- ap09_receipt_wru_per_event
- Result
- 2
- Consequence
- receipt item alone uses transaction multiplier
- Result ID
- ap09_receipt_aggregate_wru_s
- Result
- 10000
- Consequence
- 5000 receipt writes/s x2
- Result ID
- ap09_receipt_shards
- Result
- 13
- Consequence
- ceil(10000/(1000x0.80))
- Result ID
- ap09_receipt_per_shard_wru_s
- Result
- 769.23
- Consequence
- 10000/13
- Result ID
- ap09_receipt_headroom_percent
- Result
- 3.85
- Consequence
- below 800 WCU/s target
- Result ID
- ap13_checkpoint_wru_per_event
- Result
- 1
- Consequence
- ordinary conditional <=1KiB write
- Result ID
- ap13_checkpoint_aggregate_wru_s
- Result
- 5000
- Consequence
- 5000 checkpoint writes/s x1
- Result ID
- ap13_checkpoint_shards
- Result
- 7
- Consequence
- ceil(5000/(1000x0.80))
- Result ID
- ap13_checkpoint_per_shard_wru_s
- Result
- 714.29
- Consequence
- 5000/7
- Result ID
- ap13_checkpoint_headroom_percent
- Result
- 10.71
- Consequence
- below 800 WCU/s target
- Result ID
- ap16_create_base_wru_s
- Result
- 20000
- Consequence
- 5000xceil(1.6KiB)x2 transaction ops
- Result ID
- ap16_claim_base_wru_s
- Result
- 10200
- Consequence
- 5100xceil(1.6KiB) ordinary update
- Result ID
- ap16_complete_base_wru_s
- Result
- 10000
- Consequence
- 5000xceil(1.6KiB) ordinary update
- Result ID
- ap16_retry_base_wru_s
- Result
- 200
- Consequence
- 100xceil(1.6KiB) ordinary update
- Result ID
- ap16_reschedule_base_wru_s
- Result
- 40
- Consequence
- 20xceil(1.6KiB) ordinary update
- Result ID
- ap16_base_total_wru_s
- Result
- 40440
- Consequence
- create+claim+complete+retry+reschedule
- Result ID
- ap16_ready_create_insert_wru_s
- Result
- 5000
- Consequence
- 5000 READY inserts x1
- Result ID
- ap16_ready_claim_delete_wru_s
- Result
- 5100
- Consequence
- 5100 READY removals x1
- Result ID
- ap16_ready_retry_insert_wru_s
- Result
- 100
- Consequence
- 100 retry READY inserts x1
- Result ID
- ap16_ready_reschedule_move_wru_s
- Result
- 40
- Consequence
- 20 READY key moves x(delete+put)
- Result ID
- ap16_no_retry_move_floor_index_wru_s
- Result
- 10000
- Consequence
- 5000 create inserts+5000 claim deletes
- Result ID
- ap16_ready_index_wru_s
- Result
- 10240
- Consequence
- all sparse-index lifecycle actions
- Result ID
- ap16_ready_shards
- Result
- 13
- Consequence
- ceil(10240/(1000x0.80))
- Result ID
- ap16_per_shard_wru_s
- Result
- 787.69
- Consequence
- 10240/13
- Result ID
- ap16_headroom_percent
- Result
- 1.54
- Consequence
- below 800 WCU/s target
- Result ID
- ap16_total_lifecycle_wru_s
- Result
- 50680
- Consequence
- base40440+READY index10240
- Result ID
- ledger_month_kib
- Result
- 1200000
- Consequence
- 2m postings x0.6KiB
- Result ID
- ledger_sub_buckets
- Result
- 8
- Consequence
- count and byte ceilings agree
- Result ID
- ledger_bucket_max_mib
- Result
- 146.48
- Consequence
- 150000KiB/1024
Inference: The named accepted_order_v1 route includes the order,
idempotency result, outbox event, and AP17 sentinel as four base transaction
targets. Rounded base units are 2+1+2+1=6; two operations/item make 12. The
order account/status GSIs and AP16 READY GSI add 1+1+1=3 ordinary units after
commit, totaling 15. Canceled transactions can still consume capacity, so
conditional-conflict load belongs in the peak model (C83,C95; A100,A101,A104,
retrieved 2026-08-22).
Mode and skew decisions
Section titled “Mode and skew decisions”Inference: Current on-demand tables start warm at 12,000 read units/s and 4,000 write units/s. An individual physical partition remains bounded at 3,000 read units/s and 1,000 write units/s. These are dated service dimensions, not a promise that one partition key receives the whole table's warm throughput (C87; A22,A105, retrieved 2026-08-22).
| Choice | Use when | Boundary to test |
|---|---|---|
| On-demand | uncertain/spiky traffic and willingness to pay its request shape | prior peak/warm throughput, sudden step, hot key, account/table quotas |
| Provisioned | predictable rate, reserved headroom, explicit cost/control | forecast error, target utilization, GSI capacity, scale-out delay |
| Autoscaling | gradual provisioned changes | CloudWatch/control-loop delay; not admission control |
| Warm throughput | known launch/failover rate above current warm value | pre-warm lead time and distribution; cannot cure one hot key |
| Burst/adaptive capacity | transient uneven demand with spare capacity | finite credits/partition mechanics; do not encode as guaranteed hot-key budget |
- Choice
- On-demand
- Use when
- uncertain/spiky traffic and willingness to pay its request shape
- Boundary to test
- prior peak/warm throughput, sudden step, hot key, account/table quotas
- Choice
- Provisioned
- Use when
- predictable rate, reserved headroom, explicit cost/control
- Boundary to test
- forecast error, target utilization, GSI capacity, scale-out delay
- Choice
- Autoscaling
- Use when
- gradual provisioned changes
- Boundary to test
- CloudWatch/control-loop delay; not admission control
- Choice
- Warm throughput
- Use when
- known launch/failover rate above current warm value
- Boundary to test
- pre-warm lead time and distribution; cannot cure one hot key
- Choice
- Burst/adaptive capacity
- Use when
- transient uneven demand with spare capacity
- Boundary to test
- finite credits/partition mechanics; do not encode as guaranteed hot-key budget
Inference: The lane table above is the decision surface: twenty-one physical-route rows
cover AP01–AP18. Four rows have sufficient planning inputs for numeric
feasibility (AP06, AP09 receipt, AP13 checkpoint, and AP16 READY); every other
route remains visibly LOAD_TEST_REQUIRED or UNPROVEN. A table can split an
item collection when current mechanics permit, but placement and timing are
service-managed. With no LSI proposed here, that behavior may help observed
traffic; it is still not the deterministic proof for an explicit 80% lane
target. Warm, burst, and adaptive capacity likewise do not replace the
per-route histogram and load test (C87; A22,A105, retrieved 2026-08-22;
F24,F32,F33).
Inference: Instrument ConsumedReadCapacityUnits,
ConsumedWriteCapacityUnits, throttled requests/reasons, latency, conditional
failures, transaction conflicts, GSI lag, item size, and contributor/key skew by
AP. Table averages cannot prove AP06's hottest symbol or AP12's hottest account
is healthy (C87; A22,A105, retrieved 2026-08-22).
Inference: AP06's explicit planning case is one 100-item page/request at
0.4 KiB/item. Five eventual read units/query times 2,000 queries/s is 10,000
units/s aggregate; an 8% top symbol is 800 units/s. With a 2,400-unit/s target,
ceil(800/2400)=1, so IDX06 stays unsharded. If measured top-symbol demand
exceeds the target, write sharding changes
PK=SYM#X into PK=SYM#X#SHARD#h(eventId)%N. That distributes writes but AP06
must fan out N Queries, merge-sort, deduplicate, paginate a compound cursor,
and surrender one-partition total order. Record the shard version in items and
perform an ordered cutover. Prefer a naturally high-cardinality account/order
key when it already meets rate and order requirements (C87; A22,A105,
retrieved 2026-08-22; F24,F32,F33).
Inference: AP16 hashes eventId over thirteen READY shards for a balanced
steady planning lifecycle: 5,000 creates/s enter READY; 5,100 claims/s remove
5,000 new plus 100 retried items; 5,000 items complete; 100 fail or expire back
to READY; and 20 already-READY items/s move due/shard keys. At 0.45 KiB/index
entry, the no-retry/no-move floor is 5,000 inserts + 5,000 deletes = 10,000
index units/s. Retry circulation adds 100 inserts and 100 claim-deletes;
rescheduling adds 20 deletes + 20 puts, totaling 10,240. Thus
N=ceil(10240/(1000*0.80))=13, 787.69 units/s/shard, and 1.54% headroom below
the 800-unit target. Base work remains separate: create 20,000, claim 10,200,
complete 10,000, retry 200, and reschedule 40 units/s, for 40,440 base and
50,680 base+index units/s. dueAt is monotonic only inside each shard; poll all
thirteen equality keys, merge by (dueAt,eventId), and carry one LEK per shard
in the cursor. Recompute N before any measured rate/mix step (C87,C95;
A100,A104,A105, retrieved 2026-08-22).
Inference: AP10/AP11 impose a hard 2,000,000-posting/account/month admission limit. At 0.6 KiB, that is 1,200,000 KiB. A deterministic posting-sequence bucket rolls at 250,000 postings or 150,000 KiB, whichever comes first, so the example uses eight buckets of at most 146.48 MiB. AP11 merge-paginates them with one LEK/bucket; crossing the monthly cap rejects/escalates instead of silently growing the key (C87,C95; A100,A104,A105, retrieved 2026-08-22).
Lifecycle, recovery, and global operation
Section titled “Lifecycle, recovery, and global operation”A usable key design must also survive pagination, expiry, rebuild, and regional failure. These operations have different meanings: a continuation key advances a read, TTL cleans up old data, an export supplies a recovery dataset, and replication changes the regional consistency contract. None can stand in for a complete, reconciled business snapshot.
Pagination, Query, Scan, and expiry
Section titled “Pagination, Query, Scan, and expiry”Inference: A Query requires partition-key equality and may narrow the sort key. Its
filter runs after evaluation. Continue while LastEvaluatedKey is present;
empty returned items plus a continuation key is possible after filtering. A
Scan reads broad table/index data and also paginates. Neither ProjectionExpression
nor Select=COUNT turns a broad read into a cheap keyed read (C81,C96; A111,
retrieved 2026-08-22; F34).
Inference: Online APIs use AP keys, never a table Scan. Bulk reconciliation uses a PITR export with an immutable manifest; an emergency paginated Scan has bounded parallelism, a captured checkpoint/window, throttling protection, and restart state. This directly avoids the repository's single-page/in-memory snapshot failure (C96; A106,A111, retrieved 2026-08-22).
Inference: TTL expiry is cleanup only and is asynchronous, typically within a few days. An
expired item can remain readable and billable until deletion; use leaseUntil
and a condition against current time for takeover/authorization, not item
absence. TTL deletions enter the originating Region's Stream as service deletes;
MREC replicas consume replicated writes and cannot identify the replicated
delete the same way. MRSC does not support TTL (C85; A23,A103,A107, retrieved 2026-08-22).
Backup, export, restore, and projection rebuild
Section titled “Backup, export, restore, and projection rebuild”Inference: PITR currently retains a configurable 1–35 days at per-second granularity and restores to a new table, with the latest restorable time approximately five minutes behind. Export to S3 is asynchronous, uses the PITR data plane, and does not consume RCUs or affect the table's performance. Full and incremental exports are available; an incremental range is a compacted final-state view and one transaction can be split across adjacent exports (C88; A106, retrieved 2026-08-22).
Inference: A recovery runbook therefore: (1) declares the source timestamp and business freeze/cutover policy; (2) restores or exports to a new named dataset; (3) validates counts, control totals, schema and projection version; (4) rebuilds a new projection namespace; (5) catches up changes with stable event/version IDs; (6) proves zero gaps/duplicates against reconciliation; and (7) atomically changes the reader alias/config. Never overwrite the old projection before proof. Tags, IAM, alarms, Streams, TTL, autoscaling, and application configuration require explicit restore checks (C88,C96; A102,A106, retrieved 2026-08-22).
Global Tables: make the consistency mode explicit
Section titled “Global Tables: make the consistency mode explicit”| Boundary | MREC | MRSC |
|---|---|---|
| Default / availability | Current default; replicas in supported DynamoDB Regions (A107, retrieved 2026-08-22) | Introduced 2025; supported Region sets only (A107, retrieved 2026-08-22) |
| Topology | Multiple replicas (A107, retrieved 2026-08-22) | Exactly three Regions: three replicas or two replicas + witness (A107, retrieved 2026-08-22) |
| Replication/read | Asynchronous; monitor ReplicationLatency (A107, retrieved 2026-08-22) | Synchronous quorum; cross-Region strong reads, zero RPO; higher latency (A107, retrieved 2026-08-22) |
| Transactions | Atomic only in source Region; replicas can temporarily observe a partial transaction (A107, retrieved 2026-08-22) | Transaction APIs unsupported (A107, retrieved 2026-08-22) |
| TTL / LSI | TTL supported with replicated-delete cost (A107, retrieved 2026-08-22) | TTL and LSI unsupported (A107, retrieved 2026-08-22) |
| Streams | Replication uses Streams; per-item order and replica records can differ (A107, retrieved 2026-08-22) | Not enabled by default; if enabled replica records/order are identical (A107, retrieved 2026-08-22) |
| Change mode | Cannot change consistency mode after creation (A107, retrieved 2026-08-22) | Cannot change consistency mode after creation (A107, retrieved 2026-08-22) |
- Boundary
- Default / availability
- MREC
- Current default; replicas in supported DynamoDB Regions (A107, retrieved 2026-08-22)
- MRSC
- Introduced 2025; supported Region sets only (A107, retrieved 2026-08-22)
- Boundary
- Topology
- MREC
- Multiple replicas (A107, retrieved 2026-08-22)
- MRSC
- Exactly three Regions: three replicas or two replicas + witness (A107, retrieved 2026-08-22)
- Boundary
- Replication/read
- MREC
- Asynchronous; monitor
ReplicationLatency(A107, retrieved 2026-08-22) - MRSC
- Synchronous quorum; cross-Region strong reads, zero RPO; higher latency (A107, retrieved 2026-08-22)
- Boundary
- Transactions
- MREC
- Atomic only in source Region; replicas can temporarily observe a partial transaction (A107, retrieved 2026-08-22)
- MRSC
- Transaction APIs unsupported (A107, retrieved 2026-08-22)
- Boundary
- TTL / LSI
- MREC
- TTL supported with replicated-delete cost (A107, retrieved 2026-08-22)
- MRSC
- TTL and LSI unsupported (A107, retrieved 2026-08-22)
- Boundary
- Streams
- MREC
- Replication uses Streams; per-item order and replica records can differ (A107, retrieved 2026-08-22)
- MRSC
- Not enabled by default; if enabled replica records/order are identical (A107, retrieved 2026-08-22)
- Boundary
- Change mode
- MREC
- Cannot change consistency mode after creation (A107, retrieved 2026-08-22)
- MRSC
- Cannot change consistency mode after creation (A107, retrieved 2026-08-22)
Inference: For authoritative balances, multi-active MREC writes can race and last-writer convergence is not an accounting conflict policy. Prefer a home Region/single-writer ownership with idempotent failover and reconciliation, or use MRSC only after accepting its topology, latency, feature, transaction, and external-effect boundaries. MRSC zero RPO for table data does not make a broker, bank API, exchange acknowledgement, or customer notification atomic. Detect conflicts/errors, preserve request/event identity, and reconcile every external effect (C89; A24,A107, retrieved 2026-08-22).
DAX, ElastiCache, Aurora, and OpenSearch by access pattern
Section titled “DAX, ElastiCache, Aurora, and OpenSearch by access pattern”Inference: These are complements or alternatives chosen by a concrete AP; none changes which system owns a monetary invariant (C92; A32–A35,A108,A109,A112, retrieved 2026-08-22).
| Candidate and AP | Query / transaction shape | Consistency and invalidation | Operational load | Source-of-truth boundary |
|---|---|---|---|---|
| DAX for repeated AP01 history reads | DynamoDB-compatible item reads; not arbitrary search | Eventually consistent reads cache; strong and transactional reads pass through. Cached Query/Scan results are not invalidated by item writes, so accept TTL staleness explicitly. (A108, retrieved 2026-08-22) | Cluster sizing, subnet/security, hit/miss/eviction and fallback | Never AP12 authority or AP04 transition decision |
| ElastiCache for computed session/market reference data | Application-defined keys, structures, atomic cache operations | Define cache-aside/read-through, TTL, invalidation message loss, stampede, and source fallback. (A34,A109, retrieved 2026-08-22) | Nodes/serverless capacity, failover, memory/eviction, client behavior | Cache disposable; DynamoDB/ledger or market source remains authoritative |
| Aurora PostgreSQL for ledger/reporting with evolving relations | PostgreSQL-compatible SQL and ACID transactions; Data API exposes begin/commit/rollback operations (A112, retrieved 2026-08-22) | Isolation/endpoint mode must be selected and tested; local write forwarding supports documented isolation levels but not SERIALIZABLE; replica freshness is separate (A35,A112, retrieved 2026-08-22) | Schema/index tuning, connections, failover, engine maintenance | Inference: Candidate ledger authority only if its accounting invariants and operating model are explicitly implemented (C92; A112, retrieved 2026-08-22) |
| OpenSearch for AP05/AP06/AP15 discovery | Full-text, relevance, aggregations, flexible filters | Async index with refresh/ingestion lag, duplicates and mapping evolution; rebuildable. (A32, retrieved 2026-08-22) | Domain/shard sizing, mappings, ingestion DLQ, rollover, snapshot | Search is a locator/projection; strong-read authority before action |
- Candidate and AP
- DAX for repeated AP01 history reads
- Query / transaction shape
- DynamoDB-compatible item reads; not arbitrary search
- Consistency and invalidation
- Eventually consistent reads cache; strong and transactional reads pass through. Cached Query/Scan results are not invalidated by item writes, so accept TTL staleness explicitly. (A108, retrieved 2026-08-22)
- Operational load
- Cluster sizing, subnet/security, hit/miss/eviction and fallback
- Source-of-truth boundary
- Never AP12 authority or AP04 transition decision
- Candidate and AP
- ElastiCache for computed session/market reference data
- Query / transaction shape
- Application-defined keys, structures, atomic cache operations
- Consistency and invalidation
- Define cache-aside/read-through, TTL, invalidation message loss, stampede, and source fallback. (A34,A109, retrieved 2026-08-22)
- Operational load
- Nodes/serverless capacity, failover, memory/eviction, client behavior
- Source-of-truth boundary
- Cache disposable; DynamoDB/ledger or market source remains authoritative
- Candidate and AP
- Aurora PostgreSQL for ledger/reporting with evolving relations
- Query / transaction shape
- PostgreSQL-compatible SQL and ACID transactions; Data API exposes begin/commit/rollback operations (A112, retrieved 2026-08-22)
- Consistency and invalidation
- Isolation/endpoint mode must be selected and tested; local write forwarding supports documented isolation levels but not
SERIALIZABLE; replica freshness is separate (A35,A112, retrieved 2026-08-22) - Operational load
- Schema/index tuning, connections, failover, engine maintenance
- Source-of-truth boundary
- Inference: Candidate ledger authority only if its accounting invariants and operating model are explicitly implemented (C92; A112, retrieved 2026-08-22)
- Candidate and AP
- OpenSearch for AP05/AP06/AP15 discovery
- Query / transaction shape
- Full-text, relevance, aggregations, flexible filters
- Consistency and invalidation
- Async index with refresh/ingestion lag, duplicates and mapping evolution; rebuildable. (A32, retrieved 2026-08-22)
- Operational load
- Domain/shard sizing, mappings, ingestion DLQ, rollover, snapshot
- Source-of-truth boundary
- Search is a locator/projection; strong-read authority before action
DAX is a poor response to the repository's trades-reader: the query is a GSI
history path, freshness matters, and cache invalidation is not established.
Measure reuse and acceptable staleness before paying cluster cost. ElastiCache
offers more flexible structures but more application-owned coherence. Aurora
is preferable when APs are genuinely relational/ad hoc and transaction
constraints dominate key-value scale. OpenSearch is preferable for search and
aggregations that would otherwise create proliferating GSIs—but only as a
rebuildable projection.
Repository repair map
Section titled “Repository repair map”This is a repair design against the canonical evidence, not a second audit. All locators and exact observations remain under CS01–CS12 in the repository evidence map.
| ID | DynamoDB-relevant repair | Proof / residual boundary |
|---|---|---|
| CS01 | Commit order, fingerprinted AP08 result, AP17 sentinel, and AP16 outbox item in one transaction. | Prove no accepted order lacks outbox; relay/consumer still repeat. |
| CS02 | Replace cached 201 with durable IN_PROGRESS/COMPLETED result, fingerprint mismatch rejection, lease, and repair state. | TTL is cleanup; ambiguous external effects still require evidence. |
| CS03 | Persist relay attempt and broker response per outbox ID; inspect every PutEvents entry and reconcile target effects. | Broker acknowledgement is not downstream completion. |
| CS04 | Atomically write fill, conditionally advance order version/remaining quantity, and write semantic trade outbox item. | Cross-boundary ledger/clearing effects need inbox/outbox/reconciliation. |
| CS05 | Retry discovers deterministic fill/outbox records and resumes publication; duplicate guard returns an effect receipt. | Never delete repair evidence merely because publish later succeeds. |
| CS06 | AP09 inbox event ID plus AP13 source version accompany the conditional AP07 portfolio projection update. | Version stops stale order; inbox stops duplicate identity; only AP12 authority may authorize cash/securities/risk. |
| CS07 | Accept only next aggregate version, expose gaps, park later events, and rebuild from full source. | EventBridge provides routing, not per-account causal order. |
| CS08 | Keep EventBridge target-DLQ policy and failed-DLQ-send metrics as separate transport controls. | DynamoDB repair records do not grant SQS policy or replace DLQ runbooks. |
| CS09 | Replace one-page Scan with PITR export, manifest/control totals, versioned rebuild, catch-up, and cutover. | Export is async and not an atomic business transaction snapshot. |
| CS10 | Store fixed minor units or exact decimals with currency, scale, and explicit rounding. | Validate serialization end to end; no binary-float intermediate. |
| CS11 | Add immutable balanced postings, versioned balances/reservations, AP14/AP15 reconciliation, and projections. | DynamoDB primitives do not invent accounting semantics. |
| CS12 | Keep matching/sequencing on an evidenced runtime; use DynamoDB for durable orders, results, ledger, and projections. | Durability does not establish deterministic microsecond matching. |
- ID
- CS01
- DynamoDB-relevant repair
- Commit order, fingerprinted AP08 result, AP17 sentinel, and AP16 outbox item in one transaction.
- Proof / residual boundary
- Prove no accepted order lacks outbox; relay/consumer still repeat.
- ID
- CS02
- DynamoDB-relevant repair
- Replace cached
201with durableIN_PROGRESS/COMPLETEDresult, fingerprint mismatch rejection, lease, and repair state. - Proof / residual boundary
- TTL is cleanup; ambiguous external effects still require evidence.
- ID
- CS03
- DynamoDB-relevant repair
- Persist relay attempt and broker response per outbox ID; inspect every
PutEventsentry and reconcile target effects. - Proof / residual boundary
- Broker acknowledgement is not downstream completion.
- ID
- CS04
- DynamoDB-relevant repair
- Atomically write fill, conditionally advance order version/remaining quantity, and write semantic trade outbox item.
- Proof / residual boundary
- Cross-boundary ledger/clearing effects need inbox/outbox/reconciliation.
- ID
- CS05
- DynamoDB-relevant repair
- Retry discovers deterministic fill/outbox records and resumes publication; duplicate guard returns an effect receipt.
- Proof / residual boundary
- Never delete repair evidence merely because publish later succeeds.
- ID
- CS06
- DynamoDB-relevant repair
- AP09 inbox event ID plus AP13 source version accompany the conditional AP07 portfolio projection update.
- Proof / residual boundary
- Version stops stale order; inbox stops duplicate identity; only AP12 authority may authorize cash/securities/risk.
- ID
- CS07
- DynamoDB-relevant repair
- Accept only next aggregate version, expose gaps, park later events, and rebuild from full source.
- Proof / residual boundary
- EventBridge provides routing, not per-account causal order.
- ID
- CS08
- DynamoDB-relevant repair
- Keep EventBridge target-DLQ policy and failed-DLQ-send metrics as separate transport controls.
- Proof / residual boundary
- DynamoDB repair records do not grant SQS policy or replace DLQ runbooks.
- ID
- CS09
- DynamoDB-relevant repair
- Replace one-page Scan with PITR export, manifest/control totals, versioned rebuild, catch-up, and cutover.
- Proof / residual boundary
- Export is async and not an atomic business transaction snapshot.
- ID
- CS10
- DynamoDB-relevant repair
- Store fixed minor units or exact decimals with currency, scale, and explicit rounding.
- Proof / residual boundary
- Validate serialization end to end; no binary-float intermediate.
- ID
- CS11
- DynamoDB-relevant repair
- Add immutable balanced postings, versioned balances/reservations, AP14/AP15 reconciliation, and projections.
- Proof / residual boundary
- DynamoDB primitives do not invent accounting semantics.
- ID
- CS12
- DynamoDB-relevant repair
- Keep matching/sequencing on an evidenced runtime; use DynamoDB for durable orders, results, ledger, and projections.
- Proof / residual boundary
- Durability does not establish deterministic microsecond matching.
Poor fits and myth corrections
Section titled “Poor fits and myth corrections”Poor fits
Section titled “Poor fits”- A latency-critical central limit order book requiring deterministic global priority and one sequenced matching loop. DynamoDB can persist surrounding state; its partitioned request model is not the matching algorithm.
- Unbounded ad-hoc joins, constantly changing predicates, and exploratory analytics. Export to S3/Athena or use Aurora/OpenSearch according to the AP.
- Long-retention event sourcing from DynamoDB Streams. Retention is 24 hours; store an authoritative event sequence explicitly if that is the model.
- Cross-Region multi-item financial transactions with arbitrary external effects. Current MREC/MRSC boundaries do not supply that atomicity.
- One hot monotonically addressed key whose required write rate exceeds one partition and whose total order cannot be relaxed. Sharding changes the order contract; capacity mode does not repeal it.
Myth and correction table
Section titled “Myth and correction table”| Local-note myth or tempting shorthand | Correction |
|---|---|
| “Use a single table for DynamoDB.” | Inference: Start with APs. One table helps when a related heterogeneous collection answers them in one request; ownership/new-query/analytics trade-offs can justify other boundaries (C81; A111, F21,F22,F33–F35, retrieved 2026-08-22). |
| “Transactions lock items and are about 2–5 ms / 25 tx/s per item.” | Do not invent lock/latency/per-item throughput guarantees. Use the documented 100-item, 4 MB, same-account/Region scope and load-test the real shape (C83; A20,A101, retrieved 2026-08-22). |
“ClientRequestToken gives business idempotency.” | It is a ten-minute identical-call window. AP08 persists fingerprint, state, lease, effect and result (C83; A20,A101, retrieved 2026-08-22). |
| “Strong reads cost 2×.” | Standard strong is one 4 KiB unit; eventual is half; transactional strong is twice standard (C82; A19,A100, retrieved 2026-08-22). |
| “A GSI can give current status if I request strong consistency.” | GSIs are eventual-only. Return to the base table/LSI for a strong decision (C82; A19,A100, retrieved 2026-08-22). |
| “A filter makes a Query cheap.” | Inference: Filtering occurs after evaluated read work. Put selectivity in keys (C81; A111, F34, retrieved 2026-08-22). |
| “Streams delivers every change exactly once and in table order.” | Inference: It is 24-hour CDC with per-item order; Lambda is at least once and repeats (C84; A21,A102, retrieved 2026-08-22). |
| “A transaction appears as one event in Streams.” | Item changes may interleave. Write one semantic outbox item in the transaction (C83; A101, retrieved 2026-08-22). |
| “TTL deletes within 48 hours, so it enforces expiry.” | Inference: Current wording is typically within a few days; conditions enforce expiry/lease, TTL only cleans up (C85; A23,A103, retrieved 2026-08-22). |
| “On-demand fixes hot keys.” | Inference: Warm/prior-peak and physical-partition limits remain; one partition is 3,000 read units/s and 1,000 write units/s (C87; A22,A105, retrieved 2026-08-22). |
| “DAX invalidates all queries on write.” | Inference: Strong/transaction reads pass through; cached Query/Scan results are not invalidated by item writes (C92; A108, retrieved 2026-08-22). |
| “Global Tables are always eventual.” | Inference: MREC is default; MRSC now provides cross-Region strong reads/zero RPO under strict limits (C89; A24,A107, retrieved 2026-08-22). |
| “A mutable balance row is a ledger.” | Inference: A ledger needs exact amounts, immutable balanced postings, authority, reversals, versions and reconciliation (C91; F08,F17,F21). |
- Local-note myth or tempting shorthand
- “Use a single table for DynamoDB.”
- Correction
- Inference: Start with APs. One table helps when a related heterogeneous collection answers them in one request; ownership/new-query/analytics trade-offs can justify other boundaries (C81; A111, F21,F22,F33–F35, retrieved 2026-08-22).
- Local-note myth or tempting shorthand
- “Transactions lock items and are about 2–5 ms / 25 tx/s per item.”
- Correction
- Do not invent lock/latency/per-item throughput guarantees. Use the documented 100-item, 4 MB, same-account/Region scope and load-test the real shape (C83; A20,A101, retrieved 2026-08-22).
- Local-note myth or tempting shorthand
- “
ClientRequestTokengives business idempotency.” - Correction
- It is a ten-minute identical-call window. AP08 persists fingerprint, state, lease, effect and result (C83; A20,A101, retrieved 2026-08-22).
- Local-note myth or tempting shorthand
- “Strong reads cost 2×.”
- Correction
- Standard strong is one 4 KiB unit; eventual is half; transactional strong is twice standard (C82; A19,A100, retrieved 2026-08-22).
- Local-note myth or tempting shorthand
- “A GSI can give current status if I request strong consistency.”
- Correction
- GSIs are eventual-only. Return to the base table/LSI for a strong decision (C82; A19,A100, retrieved 2026-08-22).
- Local-note myth or tempting shorthand
- “A filter makes a Query cheap.”
- Correction
- Inference: Filtering occurs after evaluated read work. Put selectivity in keys (C81; A111, F34, retrieved 2026-08-22).
- Local-note myth or tempting shorthand
- “Streams delivers every change exactly once and in table order.”
- Correction
- Inference: It is 24-hour CDC with per-item order; Lambda is at least once and repeats (C84; A21,A102, retrieved 2026-08-22).
- Local-note myth or tempting shorthand
- “A transaction appears as one event in Streams.”
- Correction
- Item changes may interleave. Write one semantic outbox item in the transaction (C83; A101, retrieved 2026-08-22).
- Local-note myth or tempting shorthand
- “TTL deletes within 48 hours, so it enforces expiry.”
- Correction
- Inference: Current wording is typically within a few days; conditions enforce expiry/lease, TTL only cleans up (C85; A23,A103, retrieved 2026-08-22).
- Local-note myth or tempting shorthand
- “On-demand fixes hot keys.”
- Correction
- Inference: Warm/prior-peak and physical-partition limits remain; one partition is 3,000 read units/s and 1,000 write units/s (C87; A22,A105, retrieved 2026-08-22).
- Local-note myth or tempting shorthand
- “DAX invalidates all queries on write.”
- Correction
- Inference: Strong/transaction reads pass through; cached Query/Scan results are not invalidated by item writes (C92; A108, retrieved 2026-08-22).
- Local-note myth or tempting shorthand
- “Global Tables are always eventual.”
- Correction
- Inference: MREC is default; MRSC now provides cross-Region strong reads/zero RPO under strict limits (C89; A24,A107, retrieved 2026-08-22).
- Local-note myth or tempting shorthand
- “A mutable balance row is a ledger.”
- Correction
- Inference: A ledger needs exact amounts, immutable balanced postings, authority, reversals, versions and reconciliation (C91; F08,F17,F21).
Senior decision table
Section titled “Senior decision table”| Decision | Choose | Reject / escalate when | Evidence before production |
|---|---|---|---|
| Table boundary | Bounded-context tables here | Cross-context AP misses latency/transaction budget | AP trace, IAM/restore/stream owner, load test |
| Base key | Natural high-cardinality tenant + order/account | Hot-key percentile breaches partition boundary | key histogram and per-AP consumed capacity |
| GSI | Only IDX02/03/05/06/14/15/17 | AP needs strong read or amplification lacks budget | bytes, lag, throttle and rebuild test |
| LSI | None here | Strong alternate order within bounded <10 GB collection is proven | growth proof and creation-time decision |
| Idempotency | Fingerprinted durable state/result + inbox | External effect cannot be observed/reconciled | concurrency/timeout/lease/repair game day |
| Transaction | One invariant, <=100 items/4 MB, same account/Region | MRSC/cross-Region/account/external API required | conflict load, capacity, cancellation evidence |
| Money/ledger | Exact amounts + immutable balanced postings | Rounding/reversal/authority undefined | invariant tests and reconciliation |
| Streams | CDC/outbox within 24-hour recovery | Long replay/event sourcing/transaction envelope required | repeat/gap/outage exercise |
| Capacity | On-demand uncertain; provisioned stable measured load | one hot key or untested step growth | peak/skew/item/index/unit model |
| Global | Regional/home-Region MREC; MRSC for stated need | feature/latency/topology limits fail | failover/conflict/reconciliation game day |
| Cache/search | Only stale-tolerant derived AP | used to authorize financial command | invalidation/lag/fallback/rebuild proof |
| Recovery | PITR/export → new version → validate → catch up → cut over | no manifest/control totals/rollback | timed restore and reconciliation |
- Decision
- Table boundary
- Choose
- Bounded-context tables here
- Reject / escalate when
- Cross-context AP misses latency/transaction budget
- Evidence before production
- AP trace, IAM/restore/stream owner, load test
- Decision
- Base key
- Choose
- Natural high-cardinality tenant + order/account
- Reject / escalate when
- Hot-key percentile breaches partition boundary
- Evidence before production
- key histogram and per-AP consumed capacity
- Decision
- GSI
- Choose
- Only IDX02/03/05/06/14/15/17
- Reject / escalate when
- AP needs strong read or amplification lacks budget
- Evidence before production
- bytes, lag, throttle and rebuild test
- Decision
- LSI
- Choose
- None here
- Reject / escalate when
- Strong alternate order within bounded <10 GB collection is proven
- Evidence before production
- growth proof and creation-time decision
- Decision
- Idempotency
- Choose
- Fingerprinted durable state/result + inbox
- Reject / escalate when
- External effect cannot be observed/reconciled
- Evidence before production
- concurrency/timeout/lease/repair game day
- Decision
- Transaction
- Choose
- One invariant, <=100 items/4 MB, same account/Region
- Reject / escalate when
- MRSC/cross-Region/account/external API required
- Evidence before production
- conflict load, capacity, cancellation evidence
- Decision
- Money/ledger
- Choose
- Exact amounts + immutable balanced postings
- Reject / escalate when
- Rounding/reversal/authority undefined
- Evidence before production
- invariant tests and reconciliation
- Decision
- Streams
- Choose
- CDC/outbox within 24-hour recovery
- Reject / escalate when
- Long replay/event sourcing/transaction envelope required
- Evidence before production
- repeat/gap/outage exercise
- Decision
- Capacity
- Choose
- On-demand uncertain; provisioned stable measured load
- Reject / escalate when
- one hot key or untested step growth
- Evidence before production
- peak/skew/item/index/unit model
- Decision
- Global
- Choose
- Regional/home-Region MREC; MRSC for stated need
- Reject / escalate when
- feature/latency/topology limits fail
- Evidence before production
- failover/conflict/reconciliation game day
- Decision
- Cache/search
- Choose
- Only stale-tolerant derived AP
- Reject / escalate when
- used to authorize financial command
- Evidence before production
- invalidation/lag/fallback/rebuild proof
- Decision
- Recovery
- Choose
- PITR/export → new version → validate → catch up → cut over
- Reject / escalate when
- no manifest/control totals/rollback
- Evidence before production
- timed restore and reconciliation
Interview follow-ups
Section titled “Interview follow-ups”1. Why enumerate APs before drawing keys?
Section titled “1. Why enumerate APs before drawing keys?”Rubric: Name operation, predicates, order, consistency, size/rate, owner, invariant and failure response; every key/index must trace back.
2. When is single-table design valuable?
Section titled “2. When is single-table design valuable?”Rubric: One request over heterogeneous related items; then discuss stable APs, ownership, analytics, new-query friction and recovery coupling.
3. Why bounded-context tables here?
Section titled “3. Why bounded-context tables here?”Rubric: Align ownership/blast radius while preserving local item collections; acknowledge cross-table transactions and trade-offs.
4. Can a GSI satisfy a strongly current balance read?
Section titled “4. Can a GSI satisfy a strongly current balance read?”Rubric: No; GSI is eventual-only. Use base/LSI strong read or transaction, and name lag/fallback behavior.
5. What is the current transaction boundary?
Section titled “5. What is the current transaction boundary?”Rubric: Up to 100 distinct items/4 MB, one or more tables, same account and Region; no two write actions on one item; not indexes/external effects.
6. Why is ClientRequestToken insufficient?
Section titled “6. Why is ClientRequestToken insufficient?”Rubric: Ten-minute API window versus durable fingerprinted business record/result, concurrent duplicates, leases, cleanup and repair.
7. Design idempotency through a timeout.
Section titled “7. Design idempotency through a timeout.”Rubric: Fingerprint, conditional IN_PROGRESS, owner/lease, protected
effect + COMPLETED, durable result, evidence-based takeover.
8. Does optimistic locking deduplicate events?
Section titled “8. Does optimistic locking deduplicate events?”Rubric: No; version enforces order. Inbox identity deduplicates. Explain duplicate, stale, next, and gap cases.
9. How do you enforce a unique client order ID?
Section titled “9. How do you enforce a unique client order ID?”Rubric: Sentinel plus entity in one conditioned transaction; on collision read mapping and compare fingerprint, never check-then-put.
10. How do you represent money?
Section titled “10. How do you represent money?”Rubric: Fixed minor units or exact Decimal/Number, currency/scale, rounding, precision, conversion and residual policy; no binary float.
11. What makes the ledger authoritative?
Section titled “11. What makes the ledger authoritative?”Rubric: Immutable balanced postings, deterministic IDs, versioned balances/reservations, reversals, exact amounts and reconciliation.
12. What order does DynamoDB Streams provide?
Section titled “12. What order does DynamoDB Streams provide?”Rubric: Per individual item primary key, 24-hour retention; Lambda at least once. Not collection/global/business-transaction order.
13. Why an outbox item if Streams exists?
Section titled “13. Why an outbox item if Streams exists?”Rubric: Transaction items can interleave; outbox supplies one semantic envelope atomically with state. Relay and consumers still deduplicate.
14. Recompute acceptance write cost.
Section titled “14. Recompute acceptance write cost.”Rubric: Round four base targets, then 2*(2+1+2+1)=12; add three
ordinary asynchronous GSI writes for 15. Never double index entries.
15. Why can a selective filter be expensive?
Section titled “15. Why can a selective filter be expensive?”Rubric: Read work precedes filter. Move selectivity into keys and continue
LastEvaluatedKey even after an empty filtered page.
16. Does on-demand solve a hot account?
Section titled “16. Does on-demand solve a hot account?”Rubric: No. Separate warm/prior-peak behavior from the physical-partition 3,000 read-unit/1,000 write-unit boundary; measure skew.
17. Compare MREC and MRSC for balances.
Section titled “17. Compare MREC and MRSC for balances.”Rubric: MREC default/async/conflicts/source-Region transaction; MRSC three-Region quorum/strong/zero RPO/higher latency/no TTL-LSI-tx; external effects remain separate.
18. How do you recover a projection after 30 hours?
Section titled “18. How do you recover a projection after 30 hours?”Rubric: Streams expired. Use PITR/export manifest and versioned namespace, catch-up with IDs/versions, prove gaps/control totals, then cut over.
Sources used in this chapter
Section titled “Sources used in this chapter”- Alex DeBrie: The DynamoDB Book (F21), single-table design (F22), DynamoDB paper (F33), filters (F34), and one-to-many (F35).
- Foundations: original Dynamo paper (F32) and DynamoDB USENIX paper (F24).
- Current AWS docs, all retrieved 2026-08-22: read consistency (A19), transactions (A101), capacity (A100), indexes (A104), warm throughput (A105), Streams (A102), TTL (A103), backup/export (A106), Global Tables (A107), and Query/pagination (A111).
- Adjacent services, retrieved 2026-08-22: DAX (A108), ElastiCache integration (A109), Aurora (A35), and OpenSearch (A32).
Takeaway and next step
Section titled “Takeaway and next step”You should be able to trace an access pattern to its base or index route, explain why a projection cannot authorize money, and account for the accepted-order transaction without doubling asynchronous GSI work. Retain the distinction between a receipt's distribution and its protected state. Next, use these local guarantees to reason about CQRS, event sourcing, outbox, and sagas.
Reading layout adapted from SSE reading notes by Mohammed Balila, MIT. Source manifest · Attribution