Batch and Flex Cost the Same. Why Both Exist?
Two service tiers, published as separate tables, with numerically identical prices for every text model that offers both. If your first reaction to that is "so one of them must be redundant," you're not alone — and you're also not quite right, because the redundancy is only in the number, not in what the number is attached to.
The discovery that prompts this question
Anyone who's actually gone through OpenAI's pricing tables row by row, rather than skimming for the number they need, eventually notices it: Batch's input, cached-input, and output prices match Flex's, exactly, model after model. It's not an approximation that happens to look close — it's identical, published as two separate tables that could, in principle, have been one table with two names attached. That's an unusual enough choice that it's worth asking why a vendor would bother.
What actually differs, and why it's not a pricing question
The answer, once you go looking, is that Batch and Flex aren't differentiated on cost at all — they're differentiated on delivery guarantee. Batch commits to a fixed completion window, publishes no output-token limit, and draws from its own separate rate-limit pool. Flex doesn't carry that same fixed-window commitment. Same price, different promise about when — and under what resource allocation — your results actually show up.
Why a shared price for different guarantees makes sense
Once you frame it as "same underlying compute, different scheduling promise," the shared price stops looking redundant and starts looking coherent. The actual work OpenAI's infrastructure does to answer a Batch request and a Flex request, at the token level, isn't different — both are lower-priority, asynchronous-friendly processing relative to Standard's synchronous guarantee. What's genuinely different is the operational commitment layered on top: Batch says "definitely within this window," Flex doesn't make that same promise. Pricing the underlying compute identically while offering two different commitment levels around it is a reasonable way to let customers choose the guarantee that fits without OpenAI having to price the guarantee itself as a separate line item.
Why two names instead of one tier with an optional flag
An alternative design would fold this into one tier with a boolean "fixed window: yes/no" flag rather than two named tiers. That's plausible, and it's worth asking why OpenAI didn't do it that way. One reasonable guess: naming them separately makes the choice more visible in documentation, pricing pages, and API parameters than a flag buried inside a single tier's configuration would. Whether or not that's the actual internal reasoning, the practical effect for a developer is the same either way — two names to learn instead of one, in exchange for a clearer mental model of what each name promises.
The confusion this design invites, and how to avoid it
Because the prices match, it's genuinely easy to pick between the two arbitrarily, or to inherit whichever one a colleague happened to choose first, without ever actually deciding based on the one thing that differs. That's a real, if minor, failure mode: a job with a genuine deadline that ends up on Flex by habit rather than Batch by decision is exposed to a risk it didn't need to accept, for literally zero savings, since the price was never the differentiator to begin with.
The decision rule this actually reduces to
Once you strip away the pricing question entirely — because there isn't one — the choice between Batch and Flex reduces to a single question: does this job need the fixed-window guarantee, or does it just need to be cheap and asynchronous without a hard deadline commitment? A nightly report that has to be ready by morning belongs on Batch, specifically for the guarantee. A large, exploratory, delay-tolerant job with no real deadline is a reasonable fit for Flex, and there's no cost argument against it either way.
Why this is worth its own page rather than a footnote
It would be easy to fold this into a general "service tiers" reference and move on, and this site does cover it there too. It earns a dedicated page because the specific confusion — assuming identical price implies interchangeable product — is exactly the kind of mistake a quick glance at a pricing table produces and a closer read corrects. That gap between a quick glance and a closer read is, in miniature, most of what this whole site exists to close.
A test worth applying to any two "identical" options
Whenever two options in a system are priced identically, it's worth treating that as a prompt to look harder rather than a reason to stop looking — a shared price is either a coincidence (rare, in a deliberately designed pricing system) or a signal that the actual differentiation lives somewhere other than cost. Batch and Flex are a clean example specifically because the differentiator, once you look, is easy to state precisely: one guarantee is fixed, the other isn't. Not every "why do these cost the same" question resolves this cleanly, but the habit of asking it is worth having regardless of the specific answer it turns up.
What this reveals about reading pricing documentation generally
The instinct to stop reading once you've found the number you needed is a reasonable one for most everyday purchasing decisions, where price genuinely is the whole story. It's a worse habit for infrastructure decisions specifically, because infrastructure pricing tables are often structured to communicate operational tradeoffs, not just cost — a service tier's name, its footnotes, and its relationship to sibling tiers frequently carry information a bare number doesn't. Batch and Flex sharing a price is exactly the kind of detail that only becomes informative once you've read past the number to the structure surrounding it.
The takeaway for anyone choosing between the two today
If you've been defaulting to one of these two tiers out of habit rather than a considered choice, this is worth revisiting once: does the job actually need a fixed completion guarantee, or was that guarantee simply unused overhead the whole time? Either answer is fine — the point isn't that one tier is secretly better, it's that the choice should reflect an actual operational need rather than an arbitrary first pick that nobody ever went back and questioned.
Verified 2026-08-09 against CodexHow facts module (src/data/facts/) — see /about/#accuracy.