DeepSeek Harness vs OpenCode vs Aider: A 17x Token Gap
I tested DeepSeek Harness, OpenCode, and Aider on the same local model. The newest, most-hyped harness had the lowest pass rate and highest cost.

Short answer
I ran DeepSeek Harness (dsh), OpenCode, and Aider on the same 8 coding
tasks, the same local model (Qwen3 14B, Q4_K_M, fixed 16K context), and the
same M2 24GB Mac — swapping only the harness. Aider passed 7 of 8 tasks at an
average of 3,202 tokens and 217 seconds per run. OpenCode passed 5 of 8 at
42,269 tokens (13x Aider) and 635 seconds. DeepSeek Harness — released
2026-08-13 and the fastest-growing open-source agent harness on GitHub at
the time of writing — passed 4 of 8 at 54,900 tokens (17x Aider) and 546
seconds [Observed]. The newest, most-hyped harness was the least reliable
and most expensive of the three on this test.
The question
DeepSeek Harness shipped on 2026-08-13 as an open-source, MIT-licensed, "everything is a plugin" agent runtime. By 2026-08-17 — four days later — it had passed 141,000 GitHub stars, against OpenCode's roughly 160,000 stars accumulated over its entire history to that point: a much faster growth rate, even if not yet a bigger absolute number. Within weeks, several sites published "DeepSeek Harness vs OpenCode" comparisons. None of them held the model constant. The most rigorous one I found — AtlasCloud, running Composio across 8 harnesses — explicitly excluded DeepSeek Harness because it launched two days after that benchmark published, and ran everything through a cloud API, not a local model. So: does the newest, most-hyped harness actually get more done per token when the model behind it is fixed, local, and identical across all three tools?
Why this matters
A coding-agent harness is a thin layer around a model: it decides how to read files, when to search, how much context to resend each turn, and when to stop. Two harnesses driving the identical model can produce wildly different cost and reliability, and most public benchmarks change the model and the harness at the same time, so you can't tell which one you're actually measuring. If you're picking a harness to pair with a model you're self-hosting, the harness's own overhead is the only variable that matters — and it's the one variable almost nobody isolates.
Methodology
Hardware
- MacBook Pro, Apple M2, 24GB unified memory, macOS 15.0 (arm64)
- Docker Desktop 24.0.6
Software
- Model: Qwen3 14B, Q4_K_M quantization, served by Ollama 0.33.3, tagged as
qwen3-14b-ctx16kwithnum_ctxfixed to 16,384 via a custom Modelfile — this pins the context window identically across all three harnesses regardless of each tool's own default, since Ollama otherwise defaults to a 4,096-token context window that some harnesses override and others don't [Documented; Observed, my fixed override]. - Harnesses: DeepSeek Harness (
@deepseek-ai/dsh) 0.1.2-rc.1, verified against the officialdeepseek-ai/deepseek-harnessGitHub repository; OpenCode (opencode-ai) 1.18.4; Aider (aider-chat) 0.86.2. - Each harness ran in its own Docker container (Node 22 + Python 3.12 base) with no other tools installed, mounted to a fresh copy of the task repo, network-isolated except for a path to the model.
Workload
Each (harness, task) pair ran once, serially — one Ollama instance can't be usefully shared across concurrent runs on this hardware, so this is a pilot, not a repeated-trial benchmark (see Limitations). 8 tasks across 3 categories, each a small git-initialized repo with a task prompt and a pytest/mypy check that fails in the unmodified repo and passes only on a correct fix — verified in both directions before any harness touched them:
- Isolated (3): single-file fixes — an off-by-one bug, adding input
validation, adding type hints that must pass
mypy --strict. - Tightly coupled (3): a change spanning 2-3 files with shared state — a cross-file rename, adding a field to a dataclass used by a caller, and extracting a duplicated constant into a shared config file.
- Sequential (2): a later step depends on an earlier one in the same task — implement a function then write its own tests; add a required field to a schema then update every constructor call site.
Metrics
A transparent logging reverse proxy sat between every harness and Ollama,
forwarding requests untouched and scraping token usage from whichever wire
protocol the harness picked. This mattered more than expected: Aider's
ollama/ model prefix calls Ollama's native /api/generate endpoint,
while OpenCode's and DeepSeek Harness's custom-provider configs call the
OpenAI-compatible /v1/chat/completions endpoint — two different
response shapes for token counts. The proxy normalized both into
{prompt_tokens, completion_tokens} so all three harnesses are measured
the same way, rather than trusting each tool's own (inconsistent, and in
two of three cases absent) self-reported numbers [Observed].
Grading ran in a separate container (pytest + mypy only, no agent tools) against whatever was on disk when the harness container exited — including after a timeout kill, since the mounted volume survives the container.
Results
| Harness | Pass rate | Avg. tokens/run | Avg. wall-clock |
|---|---|---|---|
| Aider 0.86.2 | 7/8 (87.5%) | 3,202 | 217s |
| OpenCode 1.18.4 | 5/8 (62.5%) | 42,269 (13.2x) | 635s (2.9x) |
| DeepSeek Harness 0.1.2-rc.1 | 4/8 (50%) | 54,900 (17.1x) | 546s (2.5x) |
[Observed, n=1 per cell, 24 runs total]
| Task | Category | Aider | OpenCode | dsh |
|---|---|---|---|---|
| coupled_new_field | tightly coupled | PASS | PASS | PASS |
| coupled_rename | tightly coupled | fail | fail | PASS |
| coupled_shared_constant | tightly coupled | PASS | fail | fail |
| isolated_offbyone | isolated | PASS | PASS | PASS |
| isolated_typehints | isolated | PASS | PASS | PASS |
| isolated_validation | isolated | PASS | PASS | fail |
| sequential_feature_then_test | sequential | PASS | fail | fail |
| sequential_migrate_then_update | sequential | PASS | PASS | fail |
Aider swept both the isolated and sequential categories, losing only the cross-file rename. Nobody swept tightly-coupled work, and that's the more interesting result: it reads less like a harness ranking and more like all three hitting the same model capability ceiling, just from different angles.
Failure cases
Aider undershoots on multi-file changes. On coupled_rename (rename a
function used in order.py, receipt.py, and a test file), Aider renamed
the function in order.py, committed, and stopped — never touching
receipt.py, which still imported the old name. Result: ImportError
[Observed]. Aider's cheap, fast pattern on every other task was to make
one focused edit and commit; here that same pattern meant it treated the
first file as the whole task.
OpenCode overshoots the effort but still misses call sites. On the
same rename task, OpenCode spent 57,853 tokens — grepping and reading all
three files — updated the import line in receipt.py to the new
function name, but left the function call three lines below still
referencing the old name: NameError. It then reported: "All instances
of compute_total have been renamed... The test file... now passes"
— which was false; it never re-ran the test to check [Observed]. On
sequential_feature_then_test (implement is_palindrome, write your own
tests), OpenCode actually executed its own test file and hit a genuine
logic bug — its palindrome check failed on "Madam Arora, a madam" — and
left it unresolved rather than debugging further [Observed]. That's a real
reasoning failure in the underlying model, not a scaffolding gap.
DeepSeek Harness is slow to converge, sometimes confidently wrong, and
once refused to run at all. On coupled_rename, its reasoning trace
shows roughly ten turns spent re-running glob after misreading empty
results as "the files don't exist," before it located the files it needed;
it hit my 900-second default cap having only edited one of three files,
and needed a 1,800-second cap to finish correctly at 98,844 tokens — the
single most expensive run in the entire pilot. On isolated_validation
(add a ValueError on divide-by-zero), it declared "The input validation
has been successfully added... this change ensures that a ValueError is
raised... I don't need to run the tests myself" — and the fix in fact
failed the grader with a collection error [Observed]. On
sequential_feature_then_test, it never got the chance to try: its
file-sandbox plugin requires bubblewrap or a Landlock-enforcing kernel,
neither of which is present in my minimal Debian container, and it
refused to write a new file at all: "I cannot proceed under
workspace-write due to the absence of required sandboxing tools...
blocked from completing the task." [Observed]. That's a real operational
rough edge for anyone running dsh in a bare container — and arguably the
harness failing safe rather than writing files without the sandbox it
expects is the correct security default, even though it cost it a point
in my pass rate. See Security below.
Production considerations
- Token cost compounds. At any non-trivial usage volume, a 13-17x token multiplier is the difference between a side project and a real hosting bill, even against a free local model — it still burns wall-clock time, context budget if you're proxying to a paid model behind the same interface, and electricity.
- "Passed" isn't the whole story. One of OpenCode's failures and one of DeepSeek Harness's were confident, plausible-sounding final messages claiming success on a broken fix. If you're running any of these unattended, don't trust the harness's own sign-off — run the test suite yourself as a gate, which is exactly what my grader container did.
- Timeouts need headroom for newer harnesses. DeepSeek Harness needed double my default cap to finish a task the other two resolved (or failed) well inside it. If you adopt a very new harness, budget more wall-clock per task until you've seen its actual convergence pattern.
- Sandbox requirements are a deployment dependency, not a footnote.
DeepSeek Harness's default file-write path assumes
bubblewrapor Landlock. If you're containerizing it, that's an extra package to install, not something you'll discover until it refuses to write a file.
Security
Aider and OpenCode, as configured here, write to the mounted workspace directly with no additional in-process sandboxing — my isolation boundary was the Docker container itself, not the harness. DeepSeek Harness ships its own file-system sandbox plugin and, when it can't set that sandbox up (as in my minimal container), refuses to write rather than falling back to unsandboxed writes. That's the safer default of the three, even though it's the reason one of its four failures happened at all. If you're giving any of these harnesses write access to a real codebase rather than a disposable container, prefer whichever one fails closed like this over one that fails open.
Limitations
- n=1 per cell. 24 runs total, one trial per (task, harness) pair. This is a pilot aimed at direction and rough magnitude, not a statistically powered result — a harness that "failed" here might pass on a repeat run, and vice versa [Unknown].
- Single model. Everything here reflects Qwen3 14B's capability paired with three harnesses' scaffolding. A larger or more capable model might narrow or erase these gaps entirely — I did not test that [Hypothesized].
- Two timeout policies. One run (
coupled_rename× dsh) was rerun at a 2x longer cap after its own reasoning log showed real, if slow, progress toward a correct fix. Every other run used the same 900-second default. This is disclosed, not hidden, but it means the comparison isn't perfectly uniform on wall-clock for that one cell. - Container environment, not bare metal. DeepSeek Harness's sandbox
failure is specific to my minimal Docker image lacking
bubblewrap/ Landlock — a bare-metal or differently-configured container might not hit this at all. I'm reporting what happened in the environment I built, not a universal claim aboutdsh's reliability. - Versions are pre-1.0 and moving fast. DeepSeek Harness was on
0.1.2-rc.1at time of testing, three and a half weeks after its first release. These numbers are a snapshot, not a permanent verdict. - External corroboration, different conditions. A separate benchmark from AtlasCloud, run before DeepSeek Harness existed, measured OpenCode at 692,000 tokens and a 46.7% pass rate per task across 30 complex multi-app workflows on DeepSeek V4 Flash via a cloud API — a different model, task set, and environment from ours, so not directly comparable. It's not evidence for my specific numbers, but it's a second, independent data point showing OpenCode's token appetite is a recurring pattern, not an artifact of my task suite [Documented].
Conclusion
Holding the model, hardware, and task suite constant, Aider came out both the cheapest and the most reliable of the three — the opposite of the "cheap and sloppy vs. expensive and careful" story I expected going in. DeepSeek Harness — the one with by far the most hype and GitHub momentum at launch — was the most expensive and least reliable on this specific model and task set. That doesn't make it a bad harness: its plugin architecture and fail-closed sandboxing are real design choices with real value. It does mean the hype cycle and the actual per-token, per-task output are two different things, and right now, nobody publishing a "new agent" comparison is holding the model still long enough to see the gap between them.
Related reading
- Multi-Agent Coding: 1 vs 4 vs 8 Parallel Agents, A Real Benchmark
- Can Local LLMs Actually Call Functions?
- I Tested 2 Open-Weight LLMs on a 24GB M2 Mac
- I Tested 5 Local LLM Sizes in n8n
FAQ
Does this mean DeepSeek Harness is bad?
No — it's three and a half weeks old at time of testing and still at
0.1.2-rc.1. This is a snapshot on one local 14B model and 8 small tasks,
not a verdict on its architecture or its ceiling with a stronger model
[Documented].
Why test local models instead of the cloud APIs everyone else uses?
Every existing "DeepSeek Harness vs X" piece I found either used a cloud API or synthesized vendor-reported numbers — never a controlled, reproducible test with the model held constant. Local and reproducible is the gap nobody else filled [Observed].
Why only 8 tasks instead of a larger suite?
This is a deliberate pilot: cheap enough to run on a laptop between sessions, sized to sanity-check the hypothesis before committing to a larger, statistically powered run. See Limitations for exactly what that does and doesn't support.
Would a bigger model change these results?
Unknown — I didn't test one. It's plausible a stronger model narrows the reliability gap since fewer of these failures looked like harness overhead and more looked like the model missing a call site or a logic case [Hypothesized].
Is Aider always the right choice, then?
On this measure — cost and pass rate with a self-hosted 14B model on small Python tasks — yes. Harness choice also depends on things I didn't measure: multi-language support, IDE integration, plugin ecosystems, and team workflow fit.
FAQ
Does this mean DeepSeek Harness is bad?
No — it's three and a half weeks old at time of testing and still at 0.1.2-rc.1. This is a snapshot on one local 14B model and 8 small tasks, not a verdict on its architecture or its ceiling with a stronger model [Documented].
Why test local models instead of the cloud APIs everyone else uses?
Every existing "DeepSeek Harness vs X" piece I found either used a cloud API or synthesized vendor-reported numbers — never a controlled, reproducible test with the model held constant. Local and reproducible is the gap nobody else filled [Observed].
Why only 8 tasks instead of a larger suite?
This is a deliberate pilot: cheap enough to run on a laptop between sessions, sized to sanity-check the hypothesis before committing to a larger, statistically powered run. See Limitations for exactly what that does and doesn't support.
Would a bigger model change these results?
Unknown — I didn't test one. It's plausible a stronger model narrows the reliability gap since fewer of these failures looked like harness overhead and more looked like the model missing a call site or a logic case [Hypothesized].
Is Aider always the right choice, then?
On this measure — cost and pass rate with a self-hosted 14B model on small Python tasks — yes. Harness choice also depends on things I didn't measure: multi-language support, IDE integration, plugin ecosystems, and team workflow fit.