advanced13 min read· Module 6, Lesson 5
📦Batch Processing
Send thousands of requests at 50% discount with async batch processing
Batch Processing
Batch processing lets you send thousands of requests to Claude at a 50% discount from the regular price. The trade-off? Results aren't immediate — they're processed within 24 hours.
When to Use Batch Processing
- Large-scale data analysis — Classifying thousands of reviews
- Document translation — Translating hundreds of files
- Content generation — Creating descriptions for thousands of products
- Data extraction — Extracting information from invoices
- Any task that doesn't need an immediate response
How It Works
- Create a "batch" containing multiple requests
- Send it to Anthropic
- Processing completes within 24 hours (usually much faster)
- Retrieve the results
Creating a Batch in JavaScript
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
async function createBatch() {
const batch = await client.messages.batches.create({
requests: [
{
custom_id: "review-1",
params: {
model: "claude-sonnet-4-20250514",
max_tokens: 256,
messages: [
{ role: "user", content: "Classify this review: 'Great product!' — positive/negative/neutral" }
],
},
},
{
custom_id: "review-2",
params: {
model: "claude-sonnet-4-20250514",
max_tokens: 256,
messages: [
{ role: "user", content: "Classify this review: 'Terrible, do not buy' — positive/negative/neutral" }
],
},
},
],
});
console.log("Batch ID:", batch.id);
console.log("Status:", batch.processing_status);
return batch;
}Creating a Batch in Python
import anthropic
client = anthropic.Anthropic()
batch = client.messages.batches.create(
requests=[
{
"custom_id": "review-1",
"params": {
"model": "claude-sonnet-4-20250514",
"max_tokens": 256,
"messages": [
{"role": "user", "content": "Classify: 'Great product!' -> positive/negative/neutral"}
],
},
},
{
"custom_id": "review-2",
"params": {
"model": "claude-sonnet-4-20250514",
"max_tokens": 256,
"messages": [
{"role": "user", "content": "Classify: 'Terrible, do not buy' -> positive/negative/neutral"}
],
},
},
],
)
print(f"Batch ID: {batch.id}")
print(f"Status: {batch.processing_status}")Checking Batch Status
async function checkBatchStatus(batchId) {
const batch = await client.messages.batches.retrieve(batchId);
console.log("Status:", batch.processing_status);
console.log("Succeeded:", batch.request_counts.succeeded);
console.log("Errored:", batch.request_counts.errored);
console.log("Processing:", batch.request_counts.processing);
return batch;
}Retrieving Results
async function getBatchResults(batchId) {
const results = [];
for await (const result of client.messages.batches.results(batchId)) {
results.push({
id: result.custom_id,
type: result.result.type,
text: result.result.type === "succeeded"
? result.result.message.content[0].text
: null,
error: result.result.type === "errored"
? result.result.error
: null,
});
}
return results;
}Real-World Example: Bulk Classification
async function classifyReviews(reviews) {
const requests = reviews.map((review, i) => ({
custom_id: `review-${i}`,
params: {
model: "claude-haiku-3-5-20241022",
max_tokens: 50,
messages: [{
role: "user",
content: `Classify this review as positive, negative, or neutral. Reply with just the label.\nReview: "${review}"`,
}],
},
}));
const batch = await client.messages.batches.create({ requests });
console.log(`Batch created: ${batch.id} (${requests.length} reviews)`);
// Poll until complete
let status;
do {
await new Promise((r) => setTimeout(r, 10000));
const updated = await client.messages.batches.retrieve(batch.id);
status = updated.processing_status;
console.log(`Status: ${status} | Done: ${updated.request_counts.succeeded}`);
} while (status !== "ended");
// Get results
const results = [];
for await (const result of client.messages.batches.results(batch.id)) {
results.push({
review: reviews[parseInt(result.custom_id.split("-")[1])],
sentiment: result.result.type === "succeeded"
? result.result.message.content[0].text.trim()
: "error",
});
}
return results;
}Cost Comparison
| Scenario | Regular Requests | Batch Processing | Savings |
|---|---|---|---|
| 1,000 classifications (Haiku) | $1.20 | $0.60 | $0.60 |
| 500 summaries (Sonnet) | $15.00 | $7.50 | $7.50 |
| 100 analyses (Opus) | $150.00 | $75.00 | $75.00 |
Batch Processing Limits
- Maximum: 100,000 requests per batch
- Processing time: Up to 24 hours (usually much less)
- No streaming support
- Cannot cancel individual requests after submission
Summary
- Batch processing saves 50% on costs
- Perfect for large-scale tasks that don't need immediate responses
- Use
custom_idto map results back to your requests - Monitor status periodically until completion
Next: We'll learn about prompt caching to save even more money.