Skip to content
Domain 4Task 4.5

Batch Processing Strategies

Learn this interactively

What You Need to Know

The Message Batches API takes many requests in one submission and returns the results later. It is a cost optimisation tool with hard constraints. A synchronous call sends one request and waits for its answer. In a blocking workflow, someone or something waits for the result. A latency-tolerant workflow uses its results later.

This lesson uses one made-up example throughout: the development team at a telecoms company. Its pre-merge check reviews each pull request while a developer waits. That work is blocking. An overnight job writes a technical debt report on the codebase, and the team reads it next morning. That work is latency-tolerant.

Message Batches API: The Facts

  • 50% cost savings compared to synchronous API calls
  • Up to 24-hour processing window: results may arrive in minutes or take up to 24 hours
  • No guaranteed latency SLA: an SLA (service level agreement) is a promise to deliver within a stated time. You cannot rely on results arriving within any specific timeframe
  • No multi-turn tool calling within a single batch request: the model cannot execute tools mid-request and use the results to continue processing
  • custom_id fields for correlating request/response pairs: each request in a batch gets a unique identifier used to match it with its response

The Matching Rule

Use the synchronous API for blocking workflows and the batch API for latency-tolerant ones. A batch has no latency guarantee and can take 24 hours. So anyone who waits for a batch could wait up to 24 hours. An overnight job loses nothing when it waits, and it costs half as much.

Blocking workflows include:

  • Pre-merge checks in CI/CD
  • Real-time code review feedback
  • Any workflow where developers are blocked pending completion

Latency-tolerant workflows include:

  • Overnight technical debt reports
  • Weekly code audit summaries
  • Nightly test generation runs
  • Batch document extraction

The telecoms team keeps its pre-merge check synchronous, because a developer is waiting. It batches the technical debt report.

The first call below is synchronous. The second call is a batch.

typescript
// Synchronous — developer is waiting for this
const preMergeReview = await client.messages.create({
  model: "claude-sonnet-5-5",
  max_tokens: 4096,
  messages: [{ role: "user", content: prDiffContent }]
});

// Batch — results consumed tomorrow morning
const batchRequest = await client.messages.batches.create({
  requests: technicalDebtDocuments.map((doc, i) => ({
    custom_id: `debt-report-${i}`,
    params: {
      model: "claude-sonnet-5-5",
      max_tokens: 4096,
      messages: [{ role: "user", content: doc }]
    }
  }))
});

Multi-Turn Tool Calling Limitation

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

  • Define tools and have the model call them mid-request
  • Process tool results and continue the conversation within the same batch item
  • Run agentic loops (the model calls a tool, reads the result and continues) within a single batch request

A workflow that needs to execute a tool during processing must use the synchronous API for that step. If the telecoms team's overnight job queried its issue tracker in the middle of a file, that step would run synchronously.

SLA Calculation

Plan batch schedules for the full 24 hours. The 24 hours is a maximum window, not a delivery guarantee. A batch that does not finish inside that window returns as expired. Plan the schedule for that worst case, and treat an expired batch as work to resubmit.

Suppose the telecoms team also batches the extraction of data from customer contracts. Contracts arrive all day, and the team promises each one a result within 30 hours. Work backwards:

  • 30 hours total SLA minus the 24-hour worst case = 6 hours of buffer for collecting requests, validating inputs, or absorbing operational delays
  • Submit batches every 4 hours within that buffer window, so that a new batch is always running
  • Submitting every 6 hours leaves no margin at all

A document that arrives just after a submission waits for the next batch. If you submit every 6 hours, it can wait 6 hours and then take 24 hours to process. That uses all 30 hours.

Batch Failure Handling

Not all documents in a batch succeed. The correct way to handle failures has three steps.

1. Identify failures by custom_id. Each request has a unique identifier. Parse the batch results to find which custom_id values failed.

2. Resubmit only failures with modifications. If you resubmit the entire batch, you pay again for documents that already succeeded. Common modifications include:

  • Chunking (splitting into smaller parts) oversized documents that exceeded context limits, such as the telecoms team's longest contracts
  • Simplifying extraction prompts for documents with unusual structures
  • Adding format-specific few-shot examples (input-output pairs included in the prompt) for documents that failed due to structural variety

3. Refine prompts on a sample set before batch processing. This early step maximises the number of documents that succeed on the first submission and reduces the cost of resubmissions.

The handler below retries only failed and expired results. The results arrive as JSONL, a format with one JSON object on each line.

typescript
// Poll until the batch has finished before reading results
let batch = await client.messages.batches.retrieve(batchId);
while (batch.processing_status !== "ended") {
  await new Promise(r => setTimeout(r, 60_000));
  batch = await client.messages.batches.retrieve(batchId);
}

// results() returns a JSONL async iterable, not an array — accumulate it.
// Treat `expired` as a failure too: that is what an overrun batch returns.
const failedIds: string[] = [];
for await (const result of client.messages.batches.results(batchId)) {
  if (result.result.type === "errored" || result.result.type === "expired") {
    failedIds.push(result.custom_id);
  }
}

// Resubmit only failures with modifications
const retryRequests = failedIds.map(id => {
  const originalDoc = documentsById[id];
  return {
    custom_id: `${id}-retry-1`,
    params: {
      model: "claude-sonnet-5-5",
      max_tokens: 8192,  // increased for oversized docs
      messages: [{
        role: "user",
        content: chunkIfNeeded(originalDoc)
      }]
    }
  };
});

Prompt Optimisation Before Batch Submission

The most cost-effective batch strategy is to refine prompts before submitting large volumes. The telecoms team's sample would cover each type of customer contract.

  1. Sample set testing: Take 5-10 representative documents covering the range of formats, edge cases, and document types in your batch
  2. Iterate on the sample: Refine your extraction prompts, add few-shot examples, adjust schema design until the sample set achieves high accuracy
  3. Submit the full batch: With refined prompts, your first-pass success rate will be significantly higher
  4. Handle failures: Resubmit only the failed documents with targeted modifications

Every failed document costs a retry, so this workflow cuts total cost. A 90% first-pass success rate on 1,000 documents means only 100 retries. A 60% rate means 400 retries. That is four times the resubmission cost.

Key Concept

Batch only latency-tolerant work. Keep blocking work synchronous. Refine prompts on a sample set first.

In the exam

The matching rule is the single most tested concept in this task statement. In Question 11 of the sample questions, a manager proposes to switch everything to batch to get the saving. The correct answer keeps blocking workflows synchronous and batches only latency-tolerant ones.

The exam tests the tool limitation directly. A batch workflow that calls external tools during processing needs the synchronous API for that step. A scheduling question may work backwards from an SLA to a submission frequency.

Current state

Exam guide v1.0 states the limitation exactly as above, and that statement is the right answer. Current state (checked 6 October 2026): Anthropic's batch processing docs split the limitation by tool type. Server tools run the same server-side agentic loop in a batch request as they do synchronously. These server tools are web search, web fetch, code execution, MCP connectors, advisor and tool search. A batch result can return stop_reason: "pause_turn". You continue that turn in a follow-up request. Client tools, which your own code executes, still cannot complete a loop inside a batch item. The request ends at tool_use. After you retrieve the result, you run the tool. Then you submit a follow-up request. For a tool that your own code executes (an internal lookup, a database query), the guide and the docs agree. On the exam, answer as the guide says.

Exam Traps

Exam Trap

Switching all workflows to batch processing for cost savings

Blocking workflows where developers wait for results (pre-merge checks, real-time reviews) must remain synchronous. The batch API has no guaranteed latency SLA and can take up to 24 hours. Only latency-tolerant workflows should use batch.

Exam Trap

Assuming batch results arrive quickly because they often do

The batch API has no latency SLA. Results often arrive faster than 24 hours, but you cannot design blocking workflows around best-case timing. Design around the 24-hour maximum.

Exam Trap

Using batch for a workflow where your own tool must run mid-request and the request continues from its result

The exam guide says a batch request cannot run a tool and continue. Current docs (October 2026) run server tools in batch, but your own tools end the request at tool_use. Run that step synchronously, or resolve the call before submission or between batches.

Practice Scenario

Your manager proposes switching both your blocking pre-merge code review and your overnight technical debt report to the Message Batches API for 50% cost savings. Your manager wants that saving on any workload that can wait for its results. How should you evaluate this proposal?

Build Exercise

Build Exercise

Design a Batch Processing Strategy

Difficulty
45 minutes

What you'll learn

  • Classify workflows as blocking (synchronous) or latency-tolerant (batch-eligible) based on latency requirements
  • Use the Message Batches API with custom_id fields for request-response correlation
  • Implement failure handling that resubmits only failed documents with targeted modifications
  • Calculate batch submission frequency against SLA constraints accounting for the 24-hour processing window
  • Apply the prompt refinement workflow: sample set testing before full batch submission
  1. List 5 workflows in a hypothetical organisation and categorise each as blocking (synchronous) or latency-tolerant (batch-eligible) with justification

    Why: The matching rule between synchronous and batch API is the most tested concept in this task statement. The exam presents a scenario where a manager proposes switching everything to batch for cost savings, and you must identify which workflows cannot tolerate the 24-hour processing window.

    You should see: A table with 5 workflows, each clearly categorised with justification. Blocking workflows have someone or something waiting for the result. Batch-eligible workflows consume results later with no real-time dependency.

  2. Define a batch submission for 20 documents using the Message Batches API format with unique custom_id fields for each document

    Why: custom_id fields are the mechanism for correlating request-response pairs in batch results. Without unique identifiers, you cannot determine which documents succeeded or failed, making failure handling impossible.

    You should see: A valid batch request object with 20 entries, each containing a unique custom_id, model specification, max_tokens, and a messages array with the document content.

  3. Implement failure handling: parse batch results, identify failures by custom_id, and construct a retry batch containing only failed documents with increased max_tokens

    Why: Resubmitting only failures with targeted modifications is the correct batch failure pattern. Resubmitting the entire batch wastes cost on already-successful documents. The exam tests that you understand custom_id correlation and targeted retry.

    You should see: A failure handler that filters results by error status, extracts the custom_id values of failures, looks up the original documents, and creates a retry batch with modifications like increased max_tokens or chunked content.

  4. Calculate the batch submission frequency needed to guarantee a 30-hour SLA given the 24-hour maximum processing window

    Why: SLA calculation with the 24-hour batch processing window is a direct exam test point. You must work backwards from the SLA deadline to determine when to submit, accounting for the maximum processing time plus a safety margin.

    You should see: A calculation showing: 30-hour SLA minus 24-hour maximum processing window equals 6 hours of buffer. The latest safe submission is 24 hours before the deadline, with batches submitted every 4 hours so a new batch is always running.

  5. Create a 5-document sample set and refine extraction prompts iteratively before submitting the full batch of 20 documents

    Why: Prompt refinement on a sample set before batch submission is the most cost-effective batch processing strategy. A 90% first-pass success rate means 2 retries on 20 documents. A 60% first-pass rate means 8 retries, four times the resubmission cost.

    You should see: A sample set covering the range of document types and edge cases, 2-3 prompt iterations improving accuracy on the sample, and then the full batch submission achieving a high first-pass success rate.

Sources