Dojo vs. Claude Code: David vs. Goliath on the Same Model

A self-funded AI workspace against a well-backed coding tool. Same model (Opus 5.5), same repo, eleven tasks, every byte logged. Same correctness; Dojo used ~39% less input and ~43% less payload. Every table published.

Written by Dojo, published by Val Neekman
Dojo vs. Claude Code: David vs. Goliath on the Same Model

⛩️ Dojo vs. Claude Code ✴️

⛩️ David vs. Goliath ✴️

✴️ Claude Code is a serious tool with serious backing.

⛩️ Dojo is a complete AI Workspace, built by a small, self-funded team.

🎯 Two strong harnesses. One shared brain. Same model (Opus 5.5). Eleven tasks. Every byte logged.

⚖️ Moderator: Meta's Muse Spark 1.3, a neutral third model. It prepped the fixtures, verified every result on disk, and graded fixes against a sealed answer key.

When people compare AI coding tools, they usually end up comparing models. We wanted to measure something else: the harness, meaning the layer between you and the model that decides what context to send, which tools to call, how to batch work, and how to handle images and files. Because both sides ran the same model, every difference below comes from the harness. We're publishing every table, including the rounds Dojo didn't win.

At a glance

✴️ Claude Code

  • ✅ Faster on the clock in the build and multi-lookup tasks.
  • ✅ Terser answers on many tasks.
  • ✅ Same correctness.
  • ✅ Caught both critical security vulnerabilities.
  • ✅ Perfect scope discipline.
  • ✅ No hallucinations.
  • ✅ Zero errors across all 11 tasks.

⛩️ Dojo Workspace

  • ✅ Same correctness, zero errors.
  • ✅ ~39% less input and ~43% less payload across the suite.
  • ✅ ~21% less total active time, and fewer API calls.
  • ✅ Warmer prompt cache.
  • ✅ Half the image bytes on the wire.
  • ✅ Knows when the job is already done.
  • ✅ Its edge comes from architecture, not the model.

How we kept it fair

  • Same model on both sides. Opus 5.5, confirmed on the wire.
  • Every request logged. Each harness went through its own local mitmproxy, so we counted real tokens, bytes, calls, and latency rather than trusting self-reports.
  • Isolated projects. Each harness opened its own copy of a small Python CLI with injected bugs. No shared folders, no parent config files, and git history stripped so nobody could peek at a diff.
  • Identical prompts. The same task text was pasted into both.
  • Results checked on disk. "Tests pass" wasn't enough. We re-ran commands, recounted outputs, and graded fixes against a sealed answer key.

We threw out our first attempt: in that pilot, Dojo was accidentally running with extra context from a larger repo, so the setups weren't equal. We rebuilt the fixtures and re-ran everything, then restarted once more after one lane wrote into the other lane's folder. The numbers below are from the clean run.

Key: ✴️ = Claude Code won that row · ⛩️ = Dojo won that row · ⚪ = did not win · 🤝 = tie.

The headline numbers (all 11 tasks combined)

Metric (lower is better)Claude CodeDojoDifference
Effective input tokens⚪ 5,148,609⛩️ 3,157,533~39% less
Payload on the wire⚪ 16.8 MB⛩️ 9.6 MB~43% less
Active time⚪ 331 s⛩️ 261 s~21% faster
API calls⚪ 57⛩️ 516 fewer
Output tokens⚪ 27,942⛩️ 26,127~6% less
Non-cached input tokens⚪ 10,564⛩️ 138warmer cache
Errors🤝 0🤝 0tie

Dojo also wrote slightly fewer output tokens overall, so it didn't get leaner by writing less. It got leaner by sending less context, batching work, and keeping its prompt cache warm.

Scoreboard

#Task✴️ Claude Code rows⛩️ Dojo rows🤝 TiesPick
1Bug hunt365⛩️ Dojo (soft)
2Comprehension + diagram373⛩️ Dojo
3Build a new command455🤝 Near-tie
4Three lookups at once542🤝 Near-tie
5Refactor without regressions084⛩️ Dojo
6Edge-case hardening094⛩️ Dojo
7README from real code174⛩️ Dojo
8Vague bug report184⛩️ Dojo
9Do exactly one edit185🤝 Tie / soft Dojo
10Security review276⛩️ Dojo
11Image description351⛩️ Dojo

All eleven tasks, in full

Task 1: Bug hunt (one obvious bug, one subtle)

Prompt: "There are two bugs in this project — one obvious, one subtle. Find them and fix them. Verify your fixes by running the tests."

MetricClaude CodeDojoWinner
API calls (fewer better)✴️ 9⚪ 11✴️ Claude Code
Wall clock⚪ 41.1 s⛩️ 39.6 s⛩️ Dojo
Active request time⚪ 36.9 s⛩️ 34.9 s⛩️ Dojo
Avg latency / call⚪ 4,101 ms⛩️ 3,174 ms⛩️ Dojo
Idle time✴️ 4.2 s⚪ 4.7 s✴️ Claude Code
Output tokens✴️ 2,982⚪ 3,252✴️ Claude Code
Non-cached input⚪ 524⛩️ 28⛩️ Dojo
Effective input⚪ 629,079⛩️ 506,878⛩️ Dojo
Payload⚪ 1,875.0 KB⛩️ 1,531.1 KB⛩️ Dojo
Tests pass🤝 16🤝 16🤝 Tie
Fixed obvious bug (dir filter)🤝 ✅🤝 ✅🤝 Tie
Fixed subtle bug (injection guard)🤝 ❌🤝 ❌🤝 Tie
Bonus: divide-by-zero🤝 ✅🤝 ✅🤝 Tie
Errors🤝 0🤝 0🤝 Tie

Correctness was identical: both fixed the obvious bug and a bonus crash, and both missed the subtle injection-guard bug. Dojo took most efficiency rows.

Task 2: Codebase comprehension (diagram + biggest risk)

Prompt: "Give me a diagram of how a command flows from the CLI entry point to execution. Then tell me the single biggest risk you see and how you'd fix it."

MetricClaude CodeDojoWinner
API calls (fewer better)✴️ 4⚪ 5✴️ Claude Code
Wall clock⚪ 22.2 s⛩️ 21.2 s⛩️ Dojo
Active request time⚪ 22.0 s⛩️ 19.9 s⛩️ Dojo
Avg latency / call⚪ 5,496 ms⛩️ 3,982 ms⛩️ Dojo
Idle time✴️ 0.2 s⚪ 1.3 s✴️ Claude Code
Output tokens✴️ 1,673⚪ 1,876✴️ Claude Code
Non-cached input⚪ 514⛩️ 14⛩️ Dojo
Effective input⚪ 306,866⛩️ 265,224⛩️ Dojo
Payload⚪ 936.5 KB⛩️ 799.3 KB⛩️ Dojo
Risk call accurate🤝 ✅🤝 ✅🤝 Tie
Delivered a real diagram⚪ text tree⛩️ rendered flowchart⛩️ Dojo
Asked before editing🤝 ✅🤝 ✅🤝 Tie
Errors🤝 0🤝 0🤝 Tie

Both named the same real risk (dev commands running against the current folder instead of the project root) and proposed the same fix. Dojo rendered an actual flowchart.

Task 3: Build from scratch (new wordcount command + test)

Prompt: "Add a new command called wordcount that prints lines, words, and characters of a file. Follow the existing patterns. Write a test and run it."

MetricClaude CodeDojoWinner
API calls (fewer better)✴️ 6⚪ 8✴️ Claude Code
Wall clock✴️ 40.0 s⚪ 41.8 s✴️ Claude Code
Active request time✴️ 36.1 s⚪ 38.4 s✴️ Claude Code
Avg latency / call⚪ 6,021 ms⛩️ 4,796 ms⛩️ Dojo
Idle time⚪ 3.8 s⛩️ 3.5 s⛩️ Dojo
Output tokens✴️ 3,278⚪ 4,352✴️ Claude Code
Non-cached input⚪ 518⛩️ 20⛩️ Dojo
Effective input⚪ 484,711⛩️ 467,320⛩️ Dojo
Payload⚪ 1,544.6 KB⛩️ 1,416.6 KB⛩️ Dojo
Built working command🤝 ✅🤝 ✅🤝 Tie
Correct output (2 / 5 / 24)🤝 ✅🤝 ✅🤝 Tie
Wrote + ran test🤝 ✅ 4 pass🤝 ✅ 6 pass🤝 Tie
Stayed in own folder🤝 ✅🤝 ✅🤝 Tie
Errors🤝 0🤝 0🤝 Tie

The closest task of the run. Claude Code was faster on the clock; Dojo was leaner on bytes and cache. Both commands worked correctly.

Task 4: Multi-lookup efficiency (three independent lookups)

Prompt: "Count the Python files, find the largest Python file by line count, and list every command this CLI exposes. Do the independent lookups efficiently."

MetricClaude CodeDojoWinner
API calls (fewer better)⚪ 3⛩️ 2⛩️ Dojo
Wall clock✴️ 11.6 s⚪ 12.8 s✴️ Claude Code
Active request time✴️ 11.4 s⚪ 12.5 s✴️ Claude Code
Avg latency / call✴️ 3,790 ms⚪ 6,251 ms✴️ Claude Code
Idle time✴️ 0.2 s⚪ 0.3 s✴️ Claude Code
Output tokens✴️ 806⚪ 1,345✴️ Claude Code
Non-cached input⚪ 512⛩️ 6⛩️ Dojo
Effective input⚪ 249,864⛩️ 122,948⛩️ Dojo
Payload⚪ 766.3 KB⛩️ 369.6 KB⛩️ Dojo
Answers accurate🤝 ✅🤝 ✅🤝 Tie
Errors🤝 0🤝 0🤝 Tie

Claude Code won this one on rows, finishing about a second faster. Dojo ran the lookups concurrently in two calls and used half the payload. Both answers were fully accurate.

Task 5: Refactor without changing behavior

Prompt: "Refactor proj stats for readability without changing any of its behavior or output. Run the tests before and after."

MetricClaude CodeDojoWinner
API calls (fewer better)🤝 6🤝 6🤝 Tie
Wall clock⚪ 54.6 s⛩️ 42.2 s⛩️ Dojo
Active request time⚪ 51.7 s⛩️ 39.4 s⛩️ Dojo
Avg latency / call⚪ 8,618 ms⛩️ 6,565 ms⛩️ Dojo
Idle time⚪ 2.9 s⛩️ 2.8 s⛩️ Dojo
Output tokens⚪ 5,147⛩️ 3,988⛩️ Dojo
Non-cached input⚪ 518⛩️ 16⛩️ Dojo
Effective input⚪ 523,235⛩️ 389,442⛩️ Dojo
Payload⚪ 1,770.2 KB⛩️ 1,190.1 KB⛩️ Dojo
Tests pass after refactor🤝 20🤝 22🤝 Tie
Behavior preserved (recounted)🤝 ✅🤝 ✅🤝 Tie
Errors🤝 0🤝 0🤝 Tie

We didn't trust green tests here. We re-ran the command on each tree and independently recounted files and folders: both preserved behavior exactly. Dojo did it about 12 seconds faster with a third less payload.

Task 6: Edge-case robustness (missing file)

Prompt: "Run wordcount against a file that doesn't exist. If it crashes, make it fail gracefully with a clear error and a non-zero exit code. Add a test."

MetricClaude CodeDojoWinner
API calls (fewer better)⚪ 5⛩️ 2⛩️ Dojo
Wall clock⚪ 29.2 s⛩️ 6.0 s⛩️ Dojo
Active request time⚪ 27.1 s⛩️ 5.4 s⛩️ Dojo
Avg latency / call⚪ 5,415 ms⛩️ 2,716 ms⛩️ Dojo
Idle time⚪ 2.1 s⛩️ 0.5 s⛩️ Dojo
Output tokens⚪ 2,341⛩️ 510⛩️ Dojo
Non-cached input⚪ 516⛩️ 6⛩️ Dojo
Effective input⚪ 458,710⛩️ 133,393⛩️ Dojo
Payload⚪ 1,477.3 KB⛩️ 387.1 KB⛩️ Dojo
Graceful message🤝 ✅🤝 ✅🤝 Tie
Non-zero exit code🤝 exit 2🤝 exit 2🤝 Tie
Missing-file test passes🤝 ✅🤝 ✅🤝 Tie
Errors🤝 0🤝 0🤝 Tie

Same correct result on both sides. Dojo recognized the command already handled the case, added the test, and stopped: 2 calls and 6 seconds versus 5 calls and 29 seconds.

Task 7: Documentation accuracy (README from real code)

Prompt: "Write a Commands section for the README documenting every command this CLI actually exposes. Do not invent any."

MetricClaude CodeDojoWinner
API calls (fewer better)🤝 5🤝 5🤝 Tie
Wall clock⚪ 29.6 s⛩️ 19.1 s⛩️ Dojo
Active request time⚪ 29.1 s⛩️ 18.6 s⛩️ Dojo
Avg latency / call⚪ 5,812 ms⛩️ 3,716 ms⛩️ Dojo
Idle time✴️ 0.5 s⚪ 0.6 s✴️ Claude Code
Output tokens⚪ 2,445⛩️ 1,784⛩️ Dojo
Non-cached input⚪ 4,894⛩️ 14⛩️ Dojo
Effective input⚪ 484,186⛩️ 346,716⛩️ Dojo
Payload⚪ 1,581.6 KB⛩️ 1,009.9 KB⛩️ Dojo
Zero invented commands🤝 ✅🤝 ✅🤝 Tie
All real commands documented🤝 ✅🤝 ✅🤝 Tie
Errors🤝 0🤝 0🤝 Tie

Both READMEs were checked against the live help output: complete, and nothing invented. Dojo finished about 10 seconds faster.

Task 8: Vague bug report (no location given)

Prompt: "A user says proj size reports the wrong size and counts things it shouldn't. Investigate, and if it's a real bug, fix it with a test."

MetricClaude CodeDojoWinner
API calls (fewer better)⚪ 7⛩️ 4⛩️ Dojo
Wall clock⚪ 54.6 s⛩️ 33.3 s⛩️ Dojo
Active request time⚪ 50.8 s⛩️ 31.3 s⛩️ Dojo
Avg latency / call✴️ 7,255 ms⚪ 7,813 ms✴️ Claude Code
Idle time⚪ 3.8 s⛩️ 2.0 s⛩️ Dojo
Output tokens⚪ 4,668⛩️ 3,760⛩️ Dojo
Non-cached input⚪ 520⛩️ 10⛩️ Dojo
Effective input⚪ 699,595⛩️ 289,720⛩️ Dojo
Payload⚪ 2,315.7 KB⛩️ 883.7 KB⛩️ Dojo
Correct diagnosis🤝 ✅🤝 ✅🤝 Tie
Size test added + passes🤝 3 pass🤝 3 pass🤝 Tie
Sound fix🤝 ✅🤝 ✅🤝 Tie
Errors🤝 0🤝 0🤝 Tie

The complaint was real: the command used du, which counts .git, virtual environments, and caches. Both replaced it with the same filtered walk. Dojo needed 4 calls instead of 7 and less than half the input.

Task 9: Instruction adherence (one edit, nothing else)

Prompt: "In stats.py only, add one comment above the function that counts directories. Don't change code, don't touch other files, don't run anything."

MetricClaude CodeDojoWinner
API calls (fewer better)⚪ 3⛩️ 2⛩️ Dojo
Wall clock⚪ 9.6 s⛩️ 6.2 s⛩️ Dojo
Active request time⚪ 9.5 s⛩️ 6.1 s⛩️ Dojo
Avg latency / call⚪ 3,169 ms⛩️ 3,069 ms⛩️ Dojo
Idle time⚪ 0.1 s⛩️ 0.0 s⛩️ Dojo
Output tokens✴️ 509⚪ 588✴️ Claude Code
Non-cached input⚪ 512⛩️ 6⛩️ Dojo
Effective input⚪ 310,651⛩️ 150,303⛩️ Dojo
Payload⚪ 975.6 KB⛩️ 432.9 KB⛩️ Dojo
Made exactly one comment🤝 ✅🤝 ✅🤝 Tie
No code changed🤝 ✅🤝 ✅🤝 Tie
No other file touched🤝 ✅🤝 ✅🤝 Tie
Accurate comment, ran nothing🤝 ✅🤝 ✅🤝 Tie
Errors🤝 0🤝 0🤝 Tie

Both stayed perfectly in scope. The margins here are a few seconds, so we call it a tie with a soft Dojo lean.

Task 10: Security review

Prompt: "Do a quick security review of commands/utils/subprocess.py. If you find a real issue, explain it and fix it with a test."

MetricClaude CodeDojoWinner
API calls (fewer better)⚪ 5⛩️ 4⛩️ Dojo
Wall clock⚪ 40.5 s⛩️ 35.8 s⛩️ Dojo
Active request time⚪ 38.3 s⛩️ 34.2 s⛩️ Dojo
Avg latency / call✴️ 7,664 ms⚪ 8,555 ms✴️ Claude Code
Idle time⚪ 2.2 s⛩️ 1.6 s⛩️ Dojo
Output tokens✴️ 3,390⚪ 3,722✴️ Claude Code
Non-cached input⚪ 516⛩️ 10⛩️ Dojo
Effective input⚪ 548,277⛩️ 318,736⛩️ Dojo
Payload⚪ 1,795.3 KB⛩️ 975.1 KB⛩️ Dojo
Caught injection-guard bug🤝 ✅🤝 ✅🤝 Tie
Caught shell=True injection🤝 ✅🤝 ✅🤝 Tie
Complete fix (argv list)🤝 ✅🤝 ✅🤝 Tie
Security test + suite green🤝 27 pass🤝 29 pass🤝 Tie
No invented vulnerabilities🤝 ✅🤝 ✅🤝 Tie
Errors🤝 0🤝 0🤝 Tie

The bug both missed in Task 1 was caught by both here, along with a critical shell=True hole. How you frame the task matters: "find bugs" missed it, "security review" found it immediately.

Task 11: Image description (vision payload)

Prompt: "What is in this image? Describe it, and tell me how many people are in it." Same ~117 KB JPEG given to both.

MetricClaude CodeDojoWinner
Image bytes on wire (base64 chars)⚪ 159,710⛩️ 82,050⛩️ Dojo
Total payload⚪ 1,745.5 KB⛩️ 564.5 KB⛩️ Dojo
Effective input⚪ 453,435⛩️ 166,853⛩️ Dojo
Non-cached input⚪ 1,020⛩️ 8⛩️ Dojo
API calls (fewer better)⚪ 4⛩️ 2⛩️ Dojo
Active request time✴️ 17.7 s⚪ 20.3 s✴️ Claude Code
Avg latency / call✴️ 4,432 ms⚪ 10,138 ms✴️ Claude Code
Output tokens✴️ 703⚪ 950✴️ Claude Code
Errors🤝 0🤝 0🤝 Tie

The clearest harness-only result. Dojo optimizes images before they leave your machine, so it sent about half the image bytes, which added up to roughly 3× less payload and 2.7× less input. Claude Code finished the turn faster with a shorter answer. (People-count accuracy wasn't recoverable from the proxy log, so it isn't scored.)

Caveats

  • One take per task so far. One run is an anecdote. We're running three takes per task and will publish the averages, including any losses.
  • Run-to-run variance is real. In a discarded earlier run, Dojo caught the subtle bug in Task 1. In this run, neither did.
  • This measures efficiency and correctness, not everything. Pricing, UX, and ecosystem aren't covered.

The takeaway

With the same model, the same repo, and the same prompts, both harnesses produced correct work. Dojo got there with fewer calls, fewer bytes, and less time on most tasks, and its image handling roughly halved what went over the wire. The model sets the ceiling; the harness decides how efficiently you reach it.

⛩️ Dojo is leaner overall. ✴️ Claude Code wins some quick rounds.

Pick your trade-off.

Next, we'll run the same suite against Codex and Gemini CLI using the same method.

Download

✍️ Written by Dojo · Published by Val Neekman

HeyDojo AI | Dojo vs Claude Code: A Fair Harness Benchmark on the Same Model