DynamoDB BatchWriteItem in Node.js (AWS SDK v3)
BatchWriteItem puts or deletes up to 25 items in one request. It is not a smaller UpdateItem: every PutRequest replaces the whole stored item, and the v3 types give you nowhere to attach a condition. Batch operations in DynamoDB covers the limits and the partial-failure model; this page is about the v3 call and the one way it loses data quietly.
Code
import {BatchWriteItemCommand, DynamoDBClient} from '@aws-sdk/client-dynamodb';
const client = new DynamoDBClient({region: 'us-east-1'});
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
let requestItems = {
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'}}
}
}
]
};
let attempt = 0;
do {
const response = await client.send(new BatchWriteItemCommand({RequestItems: requestItems}));
// Writes that were throttled come back in UnprocessedItems — resubmit them
// with exponential backoff until the map is empty.
requestItems = response.UnprocessedItems;
if (requestItems && Object.keys(requestItems).length > 0) {
attempt += 1;
await sleep(Math.min(100 * 2 ** attempt, 5000));
}
} while (requestItems && Object.keys(requestItems).length > 0);
console.log('Batch written');Explanation
UnprocessedItems, notUnprocessedKeys— the leftover member. The read side uses the other name, and in JavaScript a typo here compiles, reads asundefined, and turns thedo/whileinto a single-pass call that drops throttled writes on the floor. TypeScript catches it; plain JS does not.- There is nowhere to put a condition. The v3
WriteRequesttype has exactly two optional members,PutRequestandDeleteRequest, and neither acceptsConditionExpressionorReturnValues. This is not the SDK being conservative: the API reference says you cannot specify conditions on individual put and delete requests. If a write needs a guard it does not belong in a batch, it belongs in UpdateItem with a condition or a transaction. - Two
catch-able mistakes, both non-retryable, discriminated onerr.name. Twenty-six entries raisesValidationException/Too many items requested for the BatchWriteItem call. Touching one key twice raisesProvided list of item keys contains duplicates, and that message covers a put+delete pair as well as two puts, which reads oddly the first time you see it. - Whole-batch rejection list — longer than the obvious three. Alongside >25 requests, a >400 KB item and >16 MB total, DynamoDB refuses the batch for a missing table, a key that does not match the schema, a partition key over 2048 bytes, or a sort key over 1024 bytes. One bad entry costs you all 25.
- Batching buys round trips, not capacity. Each entry is billed as an individual
PutItemorDeleteItem, rounded up to 1 KB, and a delete aimed at a nonexistent item still consumes a write unit.
A key-only PutRequest destroys the rest of the item
Ella Fitzgerald / Misty starts out with an AlbumTitle and a Year. Send one PutRequest carrying only the two key attributes:
{PutRequest: {Item: {Artist: {S: 'Ella Fitzgerald'}, SongTitle: {S: 'Misty'}}}}Then read it back with ConsistentRead: true. DynamoDB Local 3.3.0 returns:
{
"Artist": { "S": "Ella Fitzgerald" },
"SongTitle": { "S": "Misty" }
}AlbumTitle and Year are gone. The call succeeded, UnprocessedItems was {}, and nothing in the response mentions the two attributes it dropped. A put is a whole-item replace, so a batch assembled from a partial payload (an API request body, a CSV column subset, a projected Query result that omitted attributes) erases every attribute the payload did not carry.
That is the failure mode to plan around when you use a batch for what feels like an update. The fix is to read the current item first and merge, or to stop batching and use UpdateItem, which touches only the attributes you name.
The other reason a 25-item batch becomes a 12-item batch is size. Writes round up to 1 KB each for billing and the request caps at 16 MB, so an item's real byte count decides both your bill and how many fit. The item size calculator gives you that number per item before you assemble the array.
To load, edit and delete items in bulk without hand-writing the replace semantics, download DynoTable.
Related examples
- DynamoDB batch write in Python — boto3's
batch_writer()does the retry loop for you. - DynamoDB BatchWriteItem with the AWS CLI — the same batch write from the shell.
- DynamoDB TransactWriteItems in Node.js — when the writes must succeed or fail together.
- 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
- 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.