DynamoDB BatchGetItem in Python (boto3)
batch_get_item fetches up to 100 items by primary key in a single request (16 MB max). With the boto3 low-level client you pass a RequestItems map of table → keys — and you must loop on UnprocessedKeys, because a batch can legally return only part of what you asked for.
Code
import time
import boto3
client = boto3.client("dynamodb")
request_items = {
"Music": {
"Keys": [
{"Artist": {"S": "Arturo Sandoval"}, "SongTitle": {"S": "Cubano Chant"}},
{"Artist": {"S": "Arturo Sandoval"}, "SongTitle": {"S": "A Mis Abuelos"}},
{"Artist": {"S": "Ella Fitzgerald"}, "SongTitle": {"S": "Misty"}},
]
}
}
items = []
attempt = 0
while request_items:
response = client.batch_get_item(RequestItems=request_items)
items.extend(response["Responses"].get("Music", []))
# A partial result is NOT an error: throttling, a >16 MB response, or an
# internal failure returns the leftovers in UnprocessedKeys. Retry them
# with exponential backoff.
request_items = response["UnprocessedKeys"]
if request_items:
attempt += 1
time.sleep(min(0.1 * 2**attempt, 5))
print(f"Fetched {len(items)} items")Explanation
RequestItems— a map of table name →{"Keys": [...]}; one request can span multiple tables. Every key must be the full primary key (partition + sort for a composite key), in DynamoDB JSON ({"S": ...},{"N": ...}). More than 100 keys, or the same key twice, raises aValidationException.Responses— a map of table name → the items found. Items come back in no particular order, and keys that don't exist simply don't appear — match results to requests by their key attributes.UnprocessedKeys— the retry loop above is not optional. If the response passes 16 MB, throughput runs out, or a partition read passes 1 MB, DynamoDB returns the remainder here inRequestItemsform, ready to feed straight back in (an empty map means done — falsy in Python, which is what ends thewhile). AWS strongly recommends exponential backoff between retries.- Consistency — batch reads are eventually consistent by default; set
"ConsistentRead": Trueper table for strongly consistent reads. - Per table you can also pass
ProjectionExpression(withExpressionAttributeNames) to fetch only some attributes. - Prefer native Python types instead of DynamoDB JSON? The resource API offers
dynamodb.batch_get_item(...)with plain values, but the retry contract is the same —UnprocessedKeysis yours to drain either way.
Do it visually
Prefer not to hand-assemble DynamoDB-JSON key maps? The DynamoDB Expression Builder builds typed key/value maps and copies runnable code, and the item size calculator shows how close a batch gets to the 16 MB ceiling.
To fetch and inspect items across tables in a GUI — no retry loops to write — download DynoTable.
Related examples
- DynamoDB BatchGetItem in Node.js — the same batch read with AWS SDK v3.
- DynamoDB BatchGetItem with the AWS CLI — the same batch read from the shell.
- DynamoDB GetItem in Python — the single-item read this batches.
- Batch operations in DynamoDB — limits, partial failure, and when batching pays off.
- "Too many items requested for the BatchGetItem call" — more than 100 keys in one request.
- "Provided list of item keys contains duplicates" — the same key twice in one batch.
References
- BatchGetItem — Amazon DynamoDB API Reference
- DynamoDB.Client.batch_get_item — Boto3 documentation
- Error handling with DynamoDB — Amazon DynamoDB Developer Guide
Last verified 2026-07-13 against the official AWS documentation linked above.