Batch Processing

The Message Batches API trades latency for roughly 50% cost savings — ideal for latency-tolerant work, wrong for anything a person is actively waiting on.

Lesson 23 of 3077% of the guide
Prefer to learn by doing?

The Message Batches API processes large volumes of requests asynchronously at roughly 50% of the standard cost. In exchange you accept an up to 24-hour processing window with no latency guarantee, and no support for multi-turn tool calling within a single batch request. It is a throughput-and-cost tool, not a speed tool.

Synchronous versus batch

The decision rule is simple: if a human or a blocking workflow is waiting on the result, use the synchronous API. If the work is latency-tolerant, use batch.

Use synchronous whenUse batch when
Pre-merge / CI code checksOvernight report generation
Real-time, user-facing reviewWeekly compliance audits
Anything blocking a pipelineBulk backfills and re-processing
Batch everything vs match the API to the wait
Don't

Moving every workflow to batch for the 50% saving stalls anything a person or pipeline is waiting on — there is no latency SLA and the window can reach 24 hours.

# CI code check submitted to batch:
batch.create(requests=[...])  # PR blocked
# for up to 24h waiting on results
Do

Route by who is waiting: synchronous for blocking, user-facing work; batch only for latency-tolerant bulk jobs.

# Real-time review -> synchronous:
client.messages.create(...)
# Overnight report -> batch:
client.messages.batches.create(...)
Exam trap

A scenario proposing to move all workflows to batch 'for the cost savings' is wrong when any of them block a person or a pipeline. Never assume batch completes quickly — there is no latency SLA.

Correlate results with custom_id

Each request in a batch carries a unique custom_id. Results come back unordered, so the custom_id is how you match a response to its request — and how you identify exactly which items failed for targeted resubmission.

import anthropic
from anthropic.types.messages.batch_create_params import Request

client = anthropic.Anthropic()

batch = client.messages.batches.create(
    requests=[
        Request(
            custom_id=f"doc-{doc_id}",
            params={
                "model": "claude-sonnet-4-5",
                "max_tokens": 1024,
                "messages": [{"role": "user", "content": text}],
            },
        )
        for doc_id, text in documents.items()
    ]
)

# Later, once status == "ended":
for result in client.messages.batches.results(batch.id):
    if result.result.type == "succeeded":
        store(result.custom_id, result.result.message)
    else:
        mark_for_resubmit(result.custom_id, result.result.type)

Handling failures

  1. 1Identify failures by inspecting the custom_id of each errored result.
  2. 2Resubmit only the failures, with modifications — chunk oversized documents, simplify prompts, or add few-shot examples.
  3. 3Refine prompts up front on a 5-10 document sample covering edge cases and format variety before submitting the full batch.

Planning around the SLA

Work backward from your deadline. With a 30-hour SLA and a 24-hour maximum window, you have a 6-hour buffer. Submitting a fresh batch every 4-6 hours keeps one in flight at all times, so a slow batch never blows the deadline.

Batch is for cost, not speed

50% cheaper, up to 24-hour window, no latency SLA, no multi-turn tool calling per request. Use it only when nothing is actively waiting on the result.

How the exam will try to trick you

The distractors below look right under time pressure — learn the tell.

  1. The trap

    Move all workflows to batch to capture the 50% cost saving.

    Correct answer

    Keep blocking, user-facing work synchronous; batch only latency-tolerant jobs.

    Why: Batch has no latency SLA and can take up to 24 hours, so it stalls anything a person or pipeline waits on.

  2. The trap

    Design a time-sensitive workflow assuming batch results arrive quickly.

    Correct answer

    Design around the 24-hour maximum window.

    Why: Results often come faster, but there is no latency guarantee, so speed is unpredictable.

  3. The trap

    Submit a multi-turn tool-calling workflow to the Batches API.

    Correct answer

    Use the synchronous API for anything needing tool execution mid-processing.

    Why: The batch API does not support multi-turn tool calling within a single request.

Key takeaways

  • The Message Batches API gives ~50% cost savings with an up-to-24-hour window and no latency SLA.
  • Use synchronous APIs for anything blocking a person or pipeline; batch only for latency-tolerant work.
  • A unique custom_id correlates unordered results and pinpoints failures for resubmission.
  • Resubmit only failed items with fixes (chunking, simpler prompts, few-shot examples).
  • Refine prompts on a 5-10 document sample before running the full batch.
  • Plan submissions around the 24-hour window: keep a fresh batch in flight to protect the deadline.

Frequently asked questions

When should you use Claude's Message Batches API?+

Use it for high-volume, latency-tolerant work — overnight reports, weekly audits, bulk backfills — where the ~50% cost saving matters and no one is waiting on individual results. Avoid it for real-time or pipeline-blocking tasks, since there is no latency guarantee.

How do you match batch results back to their requests?+

Assign each request a unique custom_id. Batch results return unordered, so you use the custom_id to correlate each response with its input and to identify exactly which requests failed for targeted resubmission.

Practice makes pass

Ready to test what you just learned?

Reading gets you familiar — answering questions gets you certified. Jump into free practice or sit a full timed mock exam, scored 100–1000 just like the real thing.

No sign-up required · Explanation for every answer · Works offline