arrow_back Back to Blog
Cost Optimization

LLM Batch API Pricing: When 50% Discounts Make Sense (and When They Don't)

SimplifAI Team

Both OpenAI and Anthropic offer batch APIs with a 50% price discount compared to their standard APIs. That's not a rounding error — it's half price. Yet most teams are not using them.

Why? Because batch APIs come with a major constraint: you don't get responses immediately. Your requests go into a queue and are processed within 24 hours (OpenAI) or similar windows. For real-time applications, that's a dealbreaker. But for many use cases, it's a non-issue — and the savings are enormous.

The Pricing Numbers

Model Standard Input Batch Input Standard Output Batch Output
GPT-4o $2.50/M $1.25/M $10.00/M $5.00/M
GPT-4o mini $0.15/M $0.075/M $0.60/M $0.30/M
Claude Sonnet 4.6 $3.00/M $1.50/M $15.00/M $7.50/M
Claude Haiku 4.5 $0.80/M $0.40/M $4.00/M $2.00/M

The discount applies to both input and output tokens. If you're currently spending $5,000/month on GPT-4o, switching eligible workloads to the Batch API gets you to $2,500/month with zero changes to your prompts or model selection.

The One Constraint That Changes Everything

Batch API requests are asynchronous. You submit a batch file of requests, and results come back within a completion window (typically up to 24 hours for OpenAI, similar for Anthropic). You cannot use them for:

  • Chat interfaces where users expect immediate responses
  • Real-time classification or routing decisions
  • Streaming outputs
  • Anything user-facing with low latency requirements

That rules out a lot. But it leaves a surprisingly large category of workloads completely unaffected.

Workloads That Are Perfect for Batch APIs

Think about every LLM task your system runs that doesn't have a human waiting for it:

Use Case Real-time needed? Batch viable? Typical monthly savings
Content moderation (historical) No Yes 40-50%
SEO metadata generation No Yes 50%
Embedding generation Sometimes Often yes 50%
Nightly report summarization No Yes 50%
Data enrichment / entity extraction No Yes 50%
Training data generation No Yes 50%
Product description writing No Yes 50%
Sentiment analysis (batch jobs) No Yes 50%
Document classification Depends Often yes 50%

If any of these run in your system — especially nightly jobs, pipeline steps that run offline, or administrative AI tasks — you're leaving money on the table.

How to Use the OpenAI Batch API

The OpenAI Batch API takes a JSONL file where each line is a complete API request with a custom ID. Here's the minimal setup:

# Step 1: Create a JSONL batch file
# batch_requests.jsonl
{"custom_id": "req-001", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "gpt-4o", "messages": [{"role": "user", "content": "Summarize: ..."}], "max_tokens": 200}}
{"custom_id": "req-002", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "gpt-4o", "messages": [{"role": "user", "content": "Classify sentiment: ..."}], "max_tokens": 10}}
# Step 2: Upload the file and create the batch
from openai import OpenAI
client = OpenAI()

with open("batch_requests.jsonl", "rb") as f:
    batch_file = client.files.create(file=f, purpose="batch")

batch = client.batches.create(
    input_file_id=batch_file.id,
    endpoint="/v1/chat/completions",
    completion_window="24h"
)
print(f"Batch ID: {batch.id}")  # Save this!
# Step 3: Poll for completion (or set up a webhook)
import time
while True:
    batch = client.batches.retrieve(batch.id)
    if batch.status == "completed":
        break
    time.sleep(60)

# Step 4: Download results
output = client.files.content(batch.output_file_id)
for line in output.text.splitlines():
    result = json.loads(line)
    print(result["custom_id"], result["response"]["body"])

How to Use the Anthropic Batch API

Anthropic's Message Batches API follows the same pattern. Batch sizes up to 10,000 requests per batch, with a 29-day result retention window:

import anthropic
client = anthropic.Anthropic()

batch = client.messages.batches.create(
    requests=[
        {
            "custom_id": f"doc-{i}",
            "params": {
                "model": "claude-sonnet-4-6",
                "max_tokens": 200,
                "messages": [{"role": "user", "content": f"Summarize: {doc}"}]
            }
        }
        for i, doc in enumerate(documents)
    ]
)

# Poll until done
while batch.processing_status == "in_progress":
    time.sleep(60)
    batch = client.messages.batches.retrieve(batch.id)

# Stream results
for result in client.messages.batches.results(batch.id):
    if result.result.type == "succeeded":
        print(result.custom_id, result.result.message.content[0].text)

When NOT to Use Batch APIs

The 24-hour window is the obvious constraint, but there are subtler cases where batch APIs create problems:

  • When freshness matters. If you're enriching data that changes frequently (stock prices, breaking news), getting results 12 hours later may mean processing stale data.
  • When you need streaming. Batch APIs return complete responses only — no token-by-token streaming.
  • When failure recovery is complex. If one request in a batch fails, you need to track which ones completed and retry only the failures. Add operational complexity before committing.
  • When volume is low. For <1,000 requests/day, the engineering overhead of setting up batch workflows probably isn't worth a $10/month saving. Just use the standard API.
  • When you need immediate confirmation. Even "fire and forget" tasks sometimes need a synchronous acknowledgment before proceeding to the next step.

The Hybrid Architecture

The most pragmatic approach is to route by latency sensitivity:

  • Standard API — anything user-facing, real-time, or latency-sensitive
  • Batch API — background jobs, pipeline steps, data enrichment, report generation, content generation at scale

A typical product might have 70% of its token volume in non-interactive workloads. That means 70% of your usage is eligible for the 50% discount — reducing your effective blended rate by 35%.

If you're spending $10,000/month on LLM APIs and 70% is batch-eligible, you're looking at $3,500/month in savings from infrastructure work that takes a developer a day or two to implement.

Tracking Batch vs Standard Costs Separately

One operational challenge: most provider dashboards don't clearly separate batch API costs from standard API costs. You end up with a single blended number that makes it hard to verify your savings or optimize further.

This is one of the places where a tool like LLMeter helps. LLMeter attributes costs to the specific API key or endpoint that incurred them, so you can see your batch workloads distinctly from your real-time workloads — verify your discount is being applied, spot which batch jobs are consuming the most tokens, and track cost trends over time without logging into multiple provider dashboards.

Quick Decision Framework

For any LLM task in your system, ask these three questions:

  1. Does a human need this response in <5 seconds? If yes → Standard API. If no → continue.
  2. Can the next step in your pipeline wait up to 24 hours? If yes → Batch API. If no → Standard API.
  3. Do you run this task >1,000 times/day? If yes → batch savings are worth the engineering effort. If no → evaluate the tradeoff.

The 50% discount is real, consistent, and available right now on both OpenAI and Anthropic. The only question is which of your workloads can afford to wait.