Codex vs Claude Code: 48 Runs on Real Tickets, and the Ticket Decided
I ran Codex and Claude Code on 8 real tickets from a production repo, 48 runs at the same price per token, scored by the hidden tests of the real commits. Both write working code from a clear ticket. They differ on speed, care and the bill, and where both failed, my ticket had gone quiet.
Both agents wrote working code for every ticket that said what it wanted. Where they failed, my ticket had gone quiet.
Pick Claude Code if you sit with the agent and steer. Pick Codex if you hand off the ticket and walk away. Both write working code from a clear ticket: I gave them 8 real tickets from this site’s code, 48 runs in all, and checked every result with tests they never saw.
Claude Code is my daily driver. The 13-app crypto fintech I shipped solo in 70 days ran on it. Codex I know from this test: 24 headless runs on the same tickets, plus its docs and its source. Read the Codex side with that in mind.
Free book · 169 pages · PDF + EPUB
Codex and Claude Code both solved every ticket that spelled out the behavior, and missed where mine didn't. The free book's spec templates help you spell it out.
Get the free bookBoth write working code from a clear ticket
On a ticket that says what it wants, every model I ran wrote code that passed: Sonnet 5.5 and Haiku 5.5 in Claude Code, GPT-6.1 Sol and GPT-6 Luna in Codex, the cheap ones included. For the code itself you are not choosing a model. You are choosing speed, care and a plan.
I rewound this site’s code to just before 8 changes I had shipped, gave each agent the ticket, and graded its code with the tests from my real change, which it never saw. Each tool ran a mid-price model and a cheap one, matched on price per token. The full method is at the end. Seven tickets, both tools, every model, every run: solved. Play with the cut that matters to you:
48 runs, sliced
Each run is one agent, one ticket, one try. Solved means every hidden test from the real commit passed.
Solved · higher is better
- Claude Code22 of 24
- Codex21 of 24
Per task (✓ solved, ✗ not)
| Task size | Claude Code | Codex |
|---|---|---|
| Sign-up keeps the languagesmall | 3 of 3 | 3 of 3 |
| Dedupe for 10 minutessmall | 3 of 3 | 3 of 3 |
| HEAD on the readersmall | 3 of 3 | 3 of 3 |
| Ad click IDsmedium | 3 of 3 | 3 of 3 |
| Year-long cachemedium | 3 of 3 | 3 of 3 |
| Country and UTMsmedium | 3 of 3 | 3 of 3 |
| GTM preview headermedium | 3 of 3 | 3 of 3 |
| Book site from the bucketlarge | 1 of 3 | 0 of 3 |
A public leaderboard, Artificial Analysis’s Coding Agent Index, puts Codex with GPT-6.1 Sol ahead, 60 to 55, at $0.89 against $1.24 a task. Its tasks are harder and written by strangers. Mine are tickets for one real repo, written the way I write them. If your tickets look like mine, trust the tie. If you hand agents problems nobody has specified, trust theirs.
They fail where your ticket goes quiet
Where the ticket says nothing, the agent decides, and its choice is sensible but not yours. Ten of the fourteen failures on my large ticket came from a value I never wrote down.
The large ticket asked for a whole module: serve a book’s static site from a private bucket under /read, with caching, analytics, safe paths and a noindex on every response. I handed over the README section that shipped with the real module, 464 words. Here it is next to two tickets for the same route that passed every run:
Two ways to write the same ticket
| Pins down | Clear ticket, 6 of 6 passed | Large ticket, 1 of 6 | Agents guessed |
|---|---|---|---|
| The header | “the browser should keep it for a year with Cache-Control: public, max-age=31536000, immutable” | “assets/site.css|js one year when the URL has the content hash ?v=” | Their own asset headers, in 5 of 6 runs |
| The body | “A HEAD request must answer with the same status and headers a GET would get (including Content-Type and X-Robots-Tag), with an empty body” | “A missing or forbidden object is a plain 404” | A 404 that says Not found, in 2 of 6 runs |
| Each path | “pagefind/pagefind.js, pagefind/pagefind-worker.js, pagefind/wasm.<lang>.pagefind ... one day, public, max-age=86400” | “/read/<slug>/<lang>/[<page>] serves a book as a website.” | A pagefind/ folder that doesn't serve its index.html, in 3 of 6 runs |
Write your ticket like the clear one. Every value you leave out, the agent picks for you. And end every ticket with the four lines I’d give a colleague:
Work in this repository and follow AGENTS.md. Update or add tests for the
new behavior, and update any docs in the repo that describe it. Before you
finish, run `pnpm verify` and make sure it passes. Do not commit and do not push.
Here are all fourteen failures, one by one:
Why the large ticket failed
| What the test wanted | Claude Code | Codex | Why |
|---|---|---|---|
| A folder like pagefind/ serves its index.html | 1 | 2 | My ticket: never said it |
| Exact asset headers: immutable, nosniff, the wasm and CSS types | 2 | 3 | My ticket: said a year, never the header |
| A missing page answers with an empty body | 0 | 2 | My ticket: said only a plain 404 |
| The page context written as JSON text | 2 | 0 | My test: it looked for exact text, and the code was right |
| Skip my own visits in analytics | 0 | 2 | The agent: the ticket said it |
Ten of the fourteen are mine. Two come from one run and a test that read code as text. Two misses were the agent’s own: Codex dropped a rule the ticket did state, so my own visits would have landed in the analytics. One check in my own test was wrong as well; I fixed it and scored the large ticket against the fixed test, and How I tested has the details.
Neither tool reads minds. Both build what the ticket says, and the gap between “what I wrote” and “what I meant” is where a large ticket fails. I write specs for exactly this reason, and this bench is the cleanest proof I have: on the seven tickets that pinned the behavior down, 42 of 42 runs passed. Those seven were written to cover their tests, so that number is partly by design. The large ticket is the honest one: written by a person in a hurry, with gaps nobody noticed until two agents fell into them.
Rewrite the ticket, don’t rerun it
When an agent fails your ticket, rewrite the ticket before you run it again. In my runs a failure stuck to the ticket, not to luck: seven tickets passed every time, and the large one passed once in six.
The usual advice is to run a flaky agent again and keep the best result. That math assumes each run is a fresh coin flip: at the 90% of my runs that passed, two tries would solve 99% of the time. Slide the hard tickets and watch that promise shrink:
pass@k vs pass^k
The other tickets pass 100% of their runs.
Pooled single-run rate:
At least one run passes (pass@k)
If every run were a coin flip at the pooled rate
On these tickets
Every run passes (pass^k)
On these tickets
The retry did change one verdict: Claude Code’s two mid-price runs on the large ticket split, one pass and one fail, and that pass is the difference between 22 and 21.
Free book · 169 pages · PDF + EPUB
Most failures on my largest ticket, in Codex and Claude Code alike, were decisions the spec never wrote down. The free book's templates put them in writing first.
Claude Code came back twice as fast
In Claude Code a typical ticket came back in under two minutes. In Codex, closer to four. If you wait at the terminal while it works, you will feel that on every ticket. On the cheap models the gap grows to 2.3 minutes against 7.6, long enough to go do something else.
Where the time went
- Median run, GPT-6.1 Sol vs Sonnet 5.5÷ 2.2
- Codex: 3.7 minClaude Code: 1.7 min
- Waiting on the model, mid-price÷ 3.1
- Codex: 2.8 minClaude Code: 0.9 min
- Running commands, mid-priceabout equal
- Codex: 35 sClaude Code: 38 s
- Median run, GPT-6 Luna vs Haiku 5.5÷ 3.2
- Codex: 7.6 minClaude Code: 2.3 min
Both tools log a timestamp on every event, so I split each run into time running commands and time waiting on the model. With the mid-price models the two spent the same time on commands; the whole gap is the model. Codex also goes back to the model more often, about 18 times per ticket against about 14, and each time it goes back, you wait again. On the cheap models Luna spent three times as long on commands too, 163 seconds against 50.
My Codex requests went through a gateway, and Artificial Analysis measures the two within a minute of each other, 12.3 minutes against 13.3 on its tasks, so don’t build your choice on my clock. On my machine, on my tickets, Claude Code answered while I would still have been waiting.
Codex cleans up. Claude Code reports.
Neither tool wandered off the ticket or said done on a red check. The difference shows when something it didn’t break is in the way: Codex fixes it and tells you, Claude Code tells you and leaves it. If you review every diff anyway, Codex’s extra care costs you two minutes a ticket. If you don’t, it is the reason to pick Codex.
Reddit has a list of complaints about these two. Claude Code edits files nobody asked about. It says “done” when it isn’t. Codex stays in scope. I counted.
The complaints, counted over 24 runs each
| Claude Code | Codex | |
|---|---|---|
| Changed code the ticket didn't call for | 0 | 0 |
| Said done while the checks were red | 0 | 0 |
| Added or updated tests | 24 | 24 |
| Updated the docs | 24 | 24 |
| Docs edits blocked in .claude/, nobody to say yes | 8 | 0 |
| Fixed a failing check it didn't cause (of 9) | 5 | 9 |
| Left the repo's checks passing | 20 | 24 |
| Median test lines written, mid-price models | 45 | 98 |
| Median shell commands, mid-price models | 13 | 23 |
Three of my eight starting points already failed the checks before the agent touched anything: a rules file under .claude/ that broke the formatter, in a part of the repo the ticket never mentioned. Codex fixed it in all nine runs and said so, which makes Codex the one that edited a file nobody asked about. Claude Code fixed it in five, always by running the formatter from the shell, and in the other four left it alone on purpose: outside this task, it said, and the checks would fail on a file it hadn’t touched.
That folder cost Claude Code more than the formatter. It asks before it edits anything under .claude/, and in a headless run nobody is there to say yes. In eight runs the docs it wanted to update lived there, and in six of them my real commit had updated that same file. Codex lost none. In a live session that folder costs you one keypress. In a run nobody watches, it costs the edit.
With the mid-price models Codex wrote twice the test lines; with the cheap ones the two tied.
The bill ties until you go cheap
This section is your bill only if you pay per token, with an API key or in CI. On a plan, skip to the next one. Per token, the mid-price models tie at about 43 cents a solved ticket. The trap is Haiku in Claude Code on a long task: past 100K tokens of context it bills five times more, and my one long Haiku run cost $1.01 where Codex on Luna cost $0.10.
The tie has a story. The bills were $6.51 for Claude Code and $6.12 for Codex over 16 mid-price runs each, and Claude Code ties per solved ticket because it solved one more. It was cheaper on five of the seven clear tickets and pricier on the large one.
Underneath sits the cache. An agent resends the whole conversation on every turn. What it sent before is read back from the prompt cache at a twentieth of the input price; the new part has to be stored first, and storing costs more than reading back. In my mid-price runs 93% of input tokens were reads, and reads cost the same on both. Storing doesn’t: Anthropic bills its one-hour cache writes at 2x the input price, OpenAI its 30-minute cache writes at 1.25x. Writes were the biggest line on both bills, $3.49 of Claude Code’s $6.51 and $3.10 of Codex’s $6.12. Claude Code’s runs were shorter, about a third fewer tokens read and written per run, and that is what evened it out.
The Haiku trap is a price line. Haiku 5.5 costs $0.10 per million input tokens up to 100K tokens of context and $0.50 past it, and Claude Code gives Haiku a window of a million tokens, so nothing stops a long task from crossing that line. On the large ticket, 64 of Claude Code’s 69 requests on Haiku carried more than 100K tokens, up to 228K. Codex runs Luna with a 258,400-token window, under the 272K line where OpenAI’s price goes up. That one run is most of why the cheap models read $0.19 per solved ticket for Claude Code and $0.05 for Codex.
Same list price, different bill
A
- Cache reads
- $0.06
- Cache writes
- $0.17
- Output
- $0.07
With the cache
B
- Cache reads
- $0.10
- Cache writes
- $0.18
- Output
- $0.07
With the cache
GPT-6.1 Sol, 30-minute cache costs 15% more than Sonnet 5.5, 1-hour cache.
Where the tokens go, and why most of them are the agent rereading its own past, is the subject of where your agent’s tokens die.
Keep the plan you already pay for
They solve the same tickets, so switching buys you speed or care, not better code. Keep the $20 plan you have, unless you want it to work in other tools: a ChatGPT plan does, a Claude plan doesn’t. On ChatGPT Plus you get far more Luna messages than Sol messages, and on my clear tickets Luna passed every run. It just took 7.6 minutes a ticket.
Plans that include each agent
| Plan | Price | For coding |
|---|---|---|
| Claude Pro | $20/mo | Claude Code included; a 5-hour session limit plus a weekly limit, shared with the Claude apps |
| Claude Max | $100 / $200 | 5x or 20x Pro's usage |
| ChatGPT Free and Go | $0 / $8 | GPT-6 Luna in the Codex desktop app, rolling out; no Codex Cloud |
| ChatGPT Plus | $20/mo | 15 to 160 GPT-6.1 Sol local messages per 5 hours, 350 to 3,000 on Luna |
| ChatGPT Pro | $100 / $200 / $500 | No five-hour limit for now; weekly limits may apply |
That criterion will outlive every number in this article. A Claude plan covers Anthropic’s own products, Claude Code included, and Anthropic forbids third-party tools from offering a Claude login. A ChatGPT plan works in Codex and, since September 29, 2026, in participating third-party tools as well. I walked that road in OpenCode vs Claude Code, and the math of a flat plan against API prices is in is Claude Max worth it. Both pricing pages: claude.com/pricing and OpenAI’s Codex pricing.
Same features, opposite defaults
Every feature you’d look for is in both. What differs is the default: Codex boxes the agent in until you let it out, and Claude Code lets it run until you box it in. Out of the box, Claude Code also runs Opus 5.5, which I didn’t test; Sonnet 5.5 was enough for every clear ticket.
Side by side
| Claude Code | Codex | |
|---|---|---|
| Sandbox by default | Off, turn it on with /sandbox | On: workspace writes only, network off |
| Approvals | Six permission modes; auto is the default in the terminal and VS Code | On request, never or granular, plus an optional auto-review agent |
| Instructions file | CLAUDE.md, or AGENTS.md when there is none | AGENTS.md, layered per directory, up to 32 KiB |
| Subagents, skills, hooks, MCP | All four | All four |
| Cloud agent | Claude Code on the web, Pro and up | Codex Cloud, Plus and up |
| Editors | VS Code, JetBrains | VS Code and its forks |
| Headless | claude -p | codex exec, read-only unless told |
| GitHub | GitHub Actions; Code Review on Team and Enterprise | openai/codex-action |
| Default model | Opus 5.5 at medium effort | Undocumented; the source lists GPT-6.1 Sol first, at low effort |
Neither default ran in my test: I gave both a sandbox and high effort, which is how long the model thinks before each step. Out of the box Codex thinks less, at low effort, and that is not what I measured either.
Steer with Claude Code, hand off to Codex
Both solved the same tickets, so pick the habit you already have.
Pick Claude Code if
- 01You steer while it works and want the answer sooner
- 02You already pay for a Claude plan
- 03You review every diff yourself anyway
- 04You want JetBrains support
Pick Codex if
- 01You hand off the ticket and come back later
- 02You already pay for ChatGPT, or want the plan in other tools
- 03You want the checks run and kept green without asking
- 04You run small models on long tasks
Codex or Claude Code?
Four questions about how you work. The answer comes with the reason and what to watch for.
How do you work with the agent?
The second plan buys a reviewer
If you already pay for one, the second is worth it as a reviewer, not as a better writer. Let Claude Code build while you steer, then have Codex read the diff against the ticket before you merge.
Both read the same AGENTS.md, so one instructions file drives both, and it costs one extra command. I haven’t run this pipeline on a team; it is what my numbers suggest. The harness around the agents, the checks and the review, does more for quality than which agent writes the code.
Two agents, one ticket
Input
A ticket that states the behavior and the interface
- youWrite AGENTS.md once
Both tools read it. No CLAUDE.md, or keep one that points to it.
- Claude CodeBuild the change
The fast loop: you steer while it works.
- CodexReview against the ticket
codex exec starts read-only: it reads the diff against the ticket and reports what is missing.
- Gate:CIRun the full checks outside any sandbox
- Gate:youApprove the diff
Output
A change two agents and the checks agree on
How I tested, for the skeptics
Everything above rests on the details below. If you want to rerun it on your own repo, this is the recipe.
The test
- real tickets
- 8
- from this site's Worker
- runs
- 48
- 24 per tool
- total at API prices
- $14.33
- all 48 runs
- 'done' on a red check
- 0
- in either tool
I took 8 real commits from this site’s Cloudflare Worker (TypeScript: lead capture, downloads, a book reader), from a 25-line fix to a 647-line module. For each one: a fresh git worktree at the commit’s parent, which is a clean copy of the repo as it stood just before the change, a ticket, and the agent alone with it. When the agent stops, the test file from the real commit goes in and runs. Same idea as SWE-bench, on my own code. I checked all 8 first: each hidden test fails on the parent commit and passes on the real fix. Of the 128 hidden tests, 103 already passed before the change; they check that the agent didn’t break what worked. The other 25 are the ticket.
The tickets come in two kinds, on purpose. My agent wrote seven of them from the real commits: the behavior and the interface the test checks, never the code. The eighth, the large one, is the README section that shipped with the real module, as it was written back then, plus the interface the test imports. Every ticket ended with the four lines above.
The 8 tickets
| Ticket | Size | Real diff | Hidden tests |
|---|---|---|---|
| Sign-up keeps the reader's language | small fix | +34 −10 | 20 |
| Dedupe a lead for 10 minutes, not 24 hours | small fix | +30 −16 | 14 |
| HEAD requests on the book reader | small fix | +16 −9 | 14 |
| Keep ad click IDs on the contact | medium feature | +106 −30 | 14 |
| Year-long cache for hashed files | medium | +59 −4 | 15 |
| Country and UTMs on the contact | medium feature | +96 −44 | 16 |
| Server-side GTM preview from cookies | medium feature | +62 −2 | 21 |
| Serve a book's static site from the bucket | large, new module | +647 −4 | 14 |
The repo has one AGENTS.md and no CLAUDE.md, so both tools read the same instructions. Codex reads AGENTS.md natively. Claude Code reads it when there is no CLAUDE.md.
The models are matched on price, because price is how you actually choose. Sonnet 5.5 and GPT-6.1 Sol both list at $2 per million input tokens, $0.10 cached and $10 output (OpenAI, Anthropic), and GPT-6.1 Sol is the model Codex recommends. Haiku 5.5 and GPT-6 Luna both list at $0.10, $0.01 and $0.50. Effort is high on both. Both tools ran headless and sandboxed, each ticket in both at the same time on the same machine:
The two commands, per run
Claude Code
claude -p "$TICKET" --model claude-sonnet-5-5 --effort high --permission-mode acceptEdits --settings '{"sandbox":{"enabled":true,"autoAllowBashIfSandboxed":true}}' --setting-sources project --strict-mcp-config --output-format stream-json --verboseCodex
codex exec -m gpt-6.1-sol -c model_reasoning_effort="high" -s workspace-write --json "$TICKET"
Setup
| Claude Code | Codex | |
|---|---|---|
| Version | 2.1.307 (2.1.308 for the last 7 runs) | CLI 0.163.0 |
| Mid-price model | Sonnet 5.5 | GPT-6.1 Sol |
| Cheap model | Haiku 5.5 | GPT-6 Luna |
| Effort | high | high |
| Mode | claude -p, edits auto-accepted | codex exec, workspace writes |
| Sandbox | On, shell auto-allowed inside it | On, network off |
| Runs | 2 per ticket on Sonnet, 1 on Haiku | 2 per ticket on GPT-6.1 Sol, 1 on Luna |
Both sandboxes broke my checks, in different ways. Codex’s sandbox turns the network off, and pnpm tried to download the version the repo pins. In 21 of 24 runs Codex still got pnpm verify itself to run, most often by turning pnpm’s version switching off; in the other 3 it ran the steps one by one. In Claude Code’s sandbox, pnpm couldn’t lock its store. Claude Code asked to run outside the sandbox, headless mode declined, and it ran each step straight from node_modules/.bin. In a live session you approve each of these requests with one keypress. That is why every run’s checks were rerun outside the sandbox.
Cost is API list price, from each run’s token counts. Claude Code reports its own list-price cost per run. For Codex I priced its token counts at OpenAI’s list, cache writes included, at the 30-minute rate: Codex 0.163.0 predates OpenAI’s 12-hour cache option.
One of my tests was wrong
On the large ticket, every run failed the same assertion: a HEAD request had to reach the bucket as a HEAD. That assertion was my bug. The Worker reads the bucket through a presigned URL, and the signature covers the HTTP method, like a ticket stamped for one door: signed for GET, the bucket turns a HEAD away. I fixed it one commit later, and that fix is the third small ticket in this bench. All six runs had read “the Worker signs a GET” in the ticket and kept the GET. They were right and my test was wrong.
So I score the large ticket against its test as it stood after my fix, and I show both. With the original test no run passes, the totals are 21 to 21, and Claude Code’s cost per solved ticket with the mid-price model moves from $0.43 to $0.46. With the fixed one, Claude Code with Sonnet 5.5 passes once in two runs, which is where its 22 comes from. One run out of two is not a win I would bet on. The explorer at the top flips between the two.
Codex vs Claude Code, quick answers
Is Codex better than Claude Code?
Not on my tickets. On 8 real tickets at the same price per token, Claude Code solved 22 of 24 runs and Codex 21 of 24, and the cost per solved ticket tied with the mid-price models. Codex was more thorough: it fixed what was in its way, wrote twice the test lines with the mid-price model and left the checks green in every run. Claude Code finished in less than half the time. Artificial Analysis's public index puts Codex ahead, 60 to 55, on harder public tasks.
Which model writes better code, Codex or Claude Code?
On a clear ticket, none of the four I ran. Sonnet 5.5 and Haiku 5.5 in Claude Code, GPT-6.1 Sol and GPT-6 Luna in Codex: every run passed on my seven clear tickets. Every miss was on one large ticket that left values unsaid, and the agents filled them with their own defaults.
Which is cheaper, Codex or Claude Code?
Both plans start at $20 a month. At API prices with models of the same list price, cost per solved ticket tied in my test: $0.43 for Claude Code with Sonnet 5.5 and $0.44 for Codex with GPT-6.1 Sol. The small models differ: Haiku 5.5 bills 5x per token past 100K tokens of context, so on a long task Codex with GPT-6 Luna cost a tenth as much.
Which is faster, Codex or Claude Code?
Claude Code, in my runs: a median of 1.7 minutes per ticket with the mid-price model against 3.7 for Codex. Both spent the same time running commands; the gap was waiting on the model, and my Codex requests went through a gateway. Artificial Analysis measures the two within a minute of each other.
Does Claude Code edit files you didn't ask for?
Not in my 48 runs. Neither tool changed code outside what the ticket called for, and neither said done while the checks were red. The one file nobody asked about, a rules file that already failed the formatter, was fixed by Codex in all nine runs that met it and by Claude Code in five.
Can Codex and Claude Code share one instructions file?
Yes. Codex reads AGENTS.md natively, layered per directory. Claude Code reads AGENTS.md when the repo has no CLAUDE.md. In my test both tools read the same AGENTS.md.
Is Codex CLI free?
The Codex CLI is open source; the models are not. Sign in with a ChatGPT plan or use an API key. The Free and Go plans get GPT-6 Luna in the Codex desktop app as it rolls out, without Codex Cloud. Plus, at $20 a month, is the first plan with GPT-6.1 Sol.
Free book · 169 pages · PDF + EPUB
Whichever you pick, Codex or Claude Code builds what your ticket says. Take home the spec templates and Claude Code kit that shipped a 13-app crypto fintech in 70 days.
Get the free book

