DynamoDB BatchWriteItem with the AWS CLI
aws dynamodb batch-write-item puts or deletes up to 25 items in one command. From the shell it has two sharp edges the SDKs soften: every value is DynamoDB JSON you have to quote correctly, and the CLI has no mechanism at all for draining UnprocessedItems. The limits and the partial-failure model are in batch operations in DynamoDB.
Code
aws dynamodb batch-write-item \
--request-items '{
"Music": [
{"PutRequest": {"Item": {"Artist": {"S": "Arturo Sandoval"}, "SongTitle": {"S": "Cubano Chant"}, "AlbumTitle": {"S": "Danzon"}, "Year": {"N": "1994"}}}},
{"PutRequest": {"Item": {"Artist": {"S": "Arturo Sandoval"}, "SongTitle": {"S": "A Mis Abuelos"}, "AlbumTitle": {"S": "Danzon"}, "Year": {"N": "1994"}}}},
{"DeleteRequest": {"Key": {"Artist": {"S": "Ella Fitzgerald"}, "SongTitle": {"S": "Misty"}}}}
]
}'Run against DynamoDB Local 3.3.0 that prints, in full:
{
"UnprocessedItems": {}
}Explanation
- An empty leftover map is the only success signal you get. The command prints
UnprocessedItemsand nothing else, so a script that checks only the exit status will call a half-written batch a success. Parse the map;jq -e '.UnprocessedItems | length == 0'is the whole check. - No flag to drain it —
aws dynamodb query helpoffers--starting-token,--max-itemsand--page-size.aws dynamodb batch-write-item helpoffers none of them, becauseUnprocessedItemsis not a pagination cursor. Re-feeding it is a shell loop with asleep, and it is already in--request-itemsshape. --condition-expressionand--return-valuesare not accepted here, and that is the API, not the CLI: conditions cannot be attached to individual put and delete requests. EveryPutRequestreplaces the whole stored item, so a batch built from a partial payload deletes the attributes it left out.- Use
file://, not inline JSON.--request-items file://writes.jsonremoves shell quoting from the list of things that can be wrong, which matters because most of what goes wrong in this command is quoting. - One bad entry, all 25 lost — a missing table, a key that does not match the schema, a >400 KB item, >16 MB total, a partition key over 2048 bytes or a sort key over 1024 bytes each reject the entire batch rather than the offending entry.
What the command prints, including the rejections
Add --return-consumed-capacity TOTAL to the fence above and DynamoDB Local 3.3.0 answers:
{
"UnprocessedItems": {},
"ConsumedCapacity": [
{
"TableName": "Music",
"CapacityUnits": 3.0
}
]
}Three units for two puts and one delete: the batch bought one round trip, not a discount. Each entry is billed as the individual PutItem or DeleteItem it stands for, rounded up to 1 KB.
Run the delete a second time, when Ella Fitzgerald / Misty is already gone, and DynamoDB Local reports 2.0 units for that single DeleteRequest. The BatchWriteItem reference (fetched 2026-07-28) says a delete on a nonexistent item consumes one write capacity unit, and a standalone delete-item against the same local engine does report 1.0. Treat local capacity numbers as directional. The point that survives either way is that a delete which finds nothing is still billed.
Two requests the service refuses outright, on stderr, exit status 254:
aws: [ERROR]: An error occurred (ValidationException) when calling the BatchWriteItem operation: Too many items requested for the BatchWriteItem call
aws: [ERROR]: An error occurred (ValidationException) when calling the BatchWriteItem operation: Provided list of item keys contains duplicatesThe second one is worth staring at. It was produced by a PutRequest and a DeleteRequest on the same key, not by two puts. DynamoDB counts any second operation on one item in one batch as a duplicate, so "delete the old row and write the new one" fails as a single batch even though the two entries look nothing alike.
Assembling those value maps inside single quotes is where the time goes. The DynamoDB Expression Builder produces typed maps and copies out a runnable command, so a failure is at least a real one rather than a stray backslash.
To bulk-load or clear items from CSV or JSON without escaping any of it, download DynoTable.
Related examples
- DynamoDB BatchWriteItem in Node.js — the same batch write with AWS SDK v3.
- DynamoDB batch write in Python — boto3's
batch_writer()does the retry loop for you. - DynamoDB PutItem with the AWS CLI — the single-item write this batches.
- Batch operations in DynamoDB — limits, partial failure, and when batching pays off.
- "Too many items requested for the BatchWriteItem call" — more than 25 put/delete requests in one batch.
- "Provided list of item keys contains duplicates" — two requests touching the same key in one batch.
References
- BatchWriteItem — Amazon DynamoDB API Reference
- batch-write-item — AWS CLI Command Reference
- Error handling with DynamoDB — Amazon DynamoDB Developer Guide
- DynamoDB read and write operations (capacity unit consumption) — Amazon DynamoDB Developer Guide
Last verified 2026-07-28 against the official AWS documentation linked above.