DynamoDB-Batch-Operationen
Wenn du viele Items auf einmal lesen oder schreiben musst, pro Item ein GetItem
oder PutItem zu feuern heißt ein Network Round Trip pro Item — langsam und
gesprächig. DynamoDBs Batch-APIs falten viele Item-Operationen in einen
einzelnen Request: BatchGetItem für Reads, BatchWriteItem für Writes.
Sie sind ein Throughput-und-Latency-Win, keine Consistency-Garantie — und diese Unterscheidung ist, wo Leute verbrennen. Ein Batch ist keine Transaction.
Was sind DynamoDB-Batch-Operationen?
DynamoDB-Batch-Operationen falten viele Item-Reads oder -Writes in einen einzelnen
Request: BatchGetItem holt bis zu 100 Items, BatchWriteItem puttet oder
löscht bis zu 25, jeweils capped bei 16 MB. Sie sparen Round Trips, nicht Capacity.
Kritisch: ein Batch ist keine Transaction — Items succeeden oder failen
unabhängig, ohne Rollback.
BatchGetItem— bis zu 100 Items (oder 16 MB) über eine oder mehrere Tabellen in einem Call fetchen.BatchWriteItem— bis zu 25 Put/Delete-Operationen (oder 16 MB) in einem Call. Keine Updates — nur Puts und Deletes.- Nicht atomar. Einzelne Items können succeeden, während andere failen. Es gibt kein Rollback.
- Partial Failure ist normal. Gedrosselte Items kommen in
UnprocessedItems/UnprocessedKeyszurück — du musst sie selbst retryen, mit Backoff. - Dieselben Capacity-Kosten wie die einzelnen Calls — Batching spart Round Trips, nicht Capacity Units.
Das Problem: viele Items, ein Round Trip
Angenommen, du betreibst einen Support-Desk. Ein Dashboard muss 50 Tickets per ID laden, um eine Queue zu rendern; ein Overnight-Job archiviert 1.000 resolved Tickets. Das Item für Item zu tun sind 50 (oder 1.000) sequenzielle Round Trips — Latenz stapelt sich und der Job kriecht.
Batching kollabiert das in eine Handvoll Calls. Der 50-Ticket-Read wird ein
einzelnes BatchGetItem; der Archive-Job wird ein Stream von BatchWriteItem-
Calls à 25 Deletes. Weit weniger Round Trips, dieselben Daten bewegt.
Wie die Batch-APIs arbeiten
BatchGetItem nimmt eine Menge Primary Keys (über eine oder mehrere Tabellen)
und gibt die matchenden Items zurück. Du kannst stark konsistente Reads pro Tabelle
anfordern. Was es nicht lesen konnte — meist weil der Request ein Throughput-Limit
streifte — kommt in UnprocessedKeys zurück, statt den ganzen Call zu failen.
BatchWriteItem nimmt eine Liste von PutRequest-/DeleteRequest-Operationen.
Beachtee, was fehlt: es gibt kein Update. Ein Batch-Write ersetzt entweder ein
ganzes Item (Put) oder entfernt es (Delete) — um spezifische Attribute zu ändern,
brauchst du weiterhin UpdateItem. Items, die er nicht schreiben konnte, kommen in
UnprocessedItems zurück.
Ein Batch ist ein Bündel unabhängiger Operationen, die jeweils für sich succeeden oder failen — keine All-or-Nothing-Einheit.
Batches sind keine Transactions
Das ist die Falle. Wenn der Batch deines Archive-Jobs halbwegs ein Throughput- Limit trifft, sind manche Tickets gelöscht und manche nicht — und DynamoDB macht die, die durchgingen, nicht rückgängig. Kein Rollback, keine Isolation, kein „alle 25 oder keines“.
Brauchst du All-or-Nothing-Semantik — „beweg das Ticket nach archived und
decrementiere den Open-Tickets-Counter, oder tu keines“ — das ist
TransactWriteItems, kein Batch. Transactions
kosten mehr (jede Operation wird doppelt abgerechnet) und capen bei 100 Items,
geben dir aber die Atomicity, die Batches bewusst nicht geben.
Unprocessed Items handhaben
Ein korrekter Batch-Caller prüft immer das Unprocessed-Set und retryt es.
DynamoDB gibt UnprocessedItems/UnprocessedKeys zurück, wann immer der Request
als Ganzes akzeptiert wurde, aber manche Items nicht bedient werden konnten —
typischerweise transient Throttling.
Re-submitte nur die unprocessed Items, mit exponential Backoff und Jitter. Einen Batch als Fire-and-Forget zu behandeln droppt Writes still — die Art Bug, die Monate später als fehlende Daten auftaucht.
Batch-Writes in DynoTable
Schätze zuerst, was ein Bulk-Job kostet, mit dem DynamoDB Pricing Calculator — ein Batch verbraucht dieselbe Capacity wie die einzelnen Writes, die er bündelt, nur in weniger Requests.
In DynoTable stagest du Edits lokal und reviewst sie vor dem Commit — Bulk- Änderungen über viele Rows gehen als gruppierte Requests raus statt als ein API- Call je. Bulk-Deletes gehen als batched Writes raus, mit dem Unprocessed-Item- Retry für dich gehandelt.

Fallstricke + nächste Schritte
- Retrye
UnprocessedItems/UnprocessedKeysimmer mit Backoff — sie sind erwartet, nicht exceptional. - Kein Partial-Failure-Rollback. Brauchst du Atomicity? Nutze Transactions.
- Keine Updates in einem Batch-Write —
BatchWriteItemist Put/Delete only; greif zuUpdateItem, um Attribute zu ändern. - Achte auf die Per-Call-Caps — 25 Writes / 100 Reads / 16 MB. Sie zu
überschreiten failt den ganzen Call mit
ValidationException(zu viele Items inBatchGetItem, inBatchWriteItem). Page durch größere Jobs; siehe Pagination.
Willst du Bulk-Reads und -Writes fahren, ohne die Retry-Loop zu scripten? Lade DynoTable herunter und editiere deine Tabellen direkt.
Round-Trip-Mathe
Serielle GetItem-Calls zahlen Latenz pro Hop. BatchGetItem bündelt bis zu
100 Keys oder 16 MB pro Request — welches Limit zuerst trifft.
| Pattern | Keys | Ca. Round Trips @ 50 Keys | Notes |
|---|---|---|---|
Serielles GetItem | 50 | 50 | Einfachster Code; schlechteste Tail-Latenz |
Ein BatchGetItem | 50 | 1 | Dieselbe RCU-Summe wie 50 Gets |
| Zwei Batches | 120 | 2 | Zweiter Batch trägt 20 Keys |
Capacity-Kosten sind unverändert — Batching spart Wall-Clock-Zeit und Client-CPU,
nicht RCU. Für Writes sind 1.000 Deletes à 25 pro Batch 40 BatchWriteItem-Calls
statt 1.000 einzelner Deletes.
Stark konsistente Batch-Reads
BatchGetItem akzeptiert ConsistentRead: true pro Tabelle in der Request-Map.
Strong Reads kosten weiterhin 2× die RCU eventueller Reads für dieselben Items.
Consistent und eventual Tabellen in einem Batch-Call zu mischen ist fine — jeder
Table-Entry trägt sein eigenes Flag.
Große Jobs chunking
Beim Archivieren von 1.000 Items à durchschnittlich 3 KB bleibt ein einzelner Batch- Read unter dem 100-Item-Cap, kann aber 16 MB überschreiten (100 × 3 KB = 300 KB — safe). Archive 50-KB-Items und du triffst das Megabyte-Cap bei etwa 320 Items pro Call, obwohl das Count-Limit 100 ist.
Page Writes mit expliziten Loops:
for each chunk of 25 keys:
BatchWriteItem
retry UnprocessedItems with backoff until emptyDynoTables staged Commit batcht eligible Writes und retryt unprocessed Items automatisch — das Pattern, das du sonst mit jittered Sleep scripten würdest.
Batch vs Transaction Decision
| Need | API | Max Items | Bei Partial Failure |
|---|---|---|---|
| Best-effort Bulk Load | BatchWriteItem | 25 Ops | Unprocessed retryen |
| All-or-nothing Ledger Move | TransactWriteItems | 100 Ops | Ganze Txn rollt zurück |
| Viele bekannte Keys lesen | BatchGetItem | 100 Keys | Unprocessed Keys retryen |
| Read + Write atomar | TransactWriteItems | 25 Transact Ops (documented Limits gelten) | All or none |
Generiere Put/Delete-Payloads aus plainem JSON mit dem DynamoDB JSON Converter, wenn du Batch-Loads aus Fixtures seedest.
Consumed Capacity inspizieren
Batch-Responses können ConsumedCapacity pro Tabelle enthalten, wenn angefordert.
Logge sie während Backfills — eine steigende Throttle-Rate zeigt sich als
wachsende Unprocessed-Sets, bevor Jobs komplett stallieren. Cross-checke
sustained WCU mit dem
Pricing Calculator, wenn Batches nach
Schedule laufen.


