benchmarks
Why SWE-bench scores don't predict daily developer productivity
SWE-bench scores measure isolated patch generation on open-source issues, not the multi-file refactoring and codebase navigation that dominates real development work.

SWE-bench has become the headline number for every new coding assistant: "We hit 47% on SWE-bench Verified!" But after watching teams adopt AI tooling in production codebases, a pattern emerges. The model that aces SWE-bench often stalls on a three-file refactor in your actual repository, while a "lower-scoring" agent might ship the feature cleanly. The benchmark measures something real—but it's not the thing that determines whether your sprint velocity doubles or your pull request queue fills with half-baked diffs.
The gap comes down to what SWE-bench optimizes for versus what daily development actually demands. Understanding that gap helps you evaluate tools on the dimensions that matter for your workflow, rather than chasing a single score that conflates dozens of distinct engineering skills.
SWE-bench tests a narrow slice of the task distribution
SWE-bench draws from GitHub issues in popular open-source Python repositories. Each task: read an issue, produce a patch that passes the project's existing tests. The benchmark measures whether the final diff resolves the bug or implements the feature described in the issue text.
What it doesn't measure:
- Multi-file refactors across domain boundaries. Most SWE-bench tasks touch one or two files. Real features often span a half-dozen modules—updating an API contract, changing a database schema, propagating the change through service layers, and adjusting frontend consumers.
- Ambiguous requirements. The issues in SWE-bench are well-formed: someone already triaged the bug, identified root cause, and wrote a clear description. Day-to-day work includes "the dropdown is slow sometimes" and "we need this to scale better"—problems that require investigation before you can write code.
- Codebase-specific conventions. A repository might use a custom ORM wrapper, a specific error-handling pattern, or a homegrown testing harness. SWE-bench tasks live in popular OSS projects with standard tooling and extensive documentation. Your private monorepo has none of that external context.
- Interaction with existing PRs. The benchmark assumes a clean main branch. Real development happens in parallel: you're working on a feature while three teammates modify adjacent code. The AI needs to understand merge conflicts, rebase cleanly, and avoid clobbering in-flight changes.
- Compile/lint/typecheck gates. Python projects in SWE-bench often lack strict static analysis. An agent can submit a patch that passes pytest but would immediately fail
mypy --strictor acargo check. In TypeScript, Rust, Go, or Java codebases, half the development loop is satisfying the compiler—a skill SWE-bench doesn't exercise.
The benchmark is valuable for tracking progress on a specific capability: can a model read an issue and produce a working patch in a popular Python library? But it's a single data point in a much larger space.
What predicts productivity: the full agent loop
When we watch AI coding tools in real repositories, the difference between productive and frustrating comes down to how the agent handles the loop:
1. Plan: break the task into sub-steps or identify files to modify
2. Constrain: respect linters, type checkers, architectural boundaries
3. Edit: make the actual code changes
4. Validate: run tests, check types, verify behavior
5. Retry: when validation fails, adjust and re-attempt
SWE-bench collapses this into "produce a patch." It doesn't penalize an agent that writes broken code ten times before stumbling onto a working diff, as long as the final submission passes tests. But in production, a tool that generates five broken attempts before succeeding burns developer time reviewing nonsense, cleaning up half-applied changes, and losing confidence in the assistant.
The models that score highest on SWE-bench often use massive retries under the hood: try a patch, run tests, read the error, generate a new patch, repeat until success or token budget exhausted. This works for a benchmark—an automated harness will happily run 50 test cycles. It doesn't work for a human developer who needs to review each iteration or whose CI/CD has a cost per run.
Goatfied's architecture prioritizes small, validated steps. The agent runs compile and lint checks after each edit, catches type errors before generating the next file, and surfaces failures immediately rather than stacking up broken changes. You see a three-file diff where all three files typecheck and pass local tests, not a twelve-file sprawl with import errors in six of them.
This discipline doesn't always maximize SWE-bench score. If the fastest path to a passing patch is "try eight things and pick the one that works," a more cautious agent might take longer or need a second attempt. But the cautious agent produces diffs you can actually merge.
The hidden cost of context window waste
SWE-bench tasks come with a known, bounded codebase. The agent can read the relevant files, and they'll fit comfortably in a large context window. Real repositories—especially polyglot monorepos—don't fit. You have hundreds of thousands of lines across multiple languages, nested dependencies, generated code, and legacy modules you'd rather the AI not touch.
High SWE-bench scores often correlate with "read everything, then decide." That strategy works when everything is ten files. It fails when the agent dumps your entire src/ directory into context, burns tokens on irrelevant files, and runs out of space for the actual diff.
Productivity in large codebases depends on selective context loading: understanding which files matter, which functions are entry points, which modules are stable versus actively changing. An agent that scores 50% on SWE-bench by reading the full repo every time will score 0% in a 400k-line codebase because it can't load the context at all.
We've seen this repeatedly when benchmarking tools on large repositories. The systems that thrive in SWE-bench's small Python projects either crash or hallucinate when pointed at a multi-package TypeScript monorepo. They haven't learned to navigate by module boundaries, import graphs, or type definitions—because SWE-bench doesn't require it.
Type systems and compile gates change the game
The majority of SWE-bench tasks are in Python repositories without strict type-checking. An agent can produce a patch that works at runtime but would never survive a mypy --strict pass or a Rust clippy run.
In strongly-typed languages, the development loop is:
1. Write code
2. Compiler yells at you
3. Fix types
4. Compiler yells at you again
5. Eventually: code compiles
6. Run tests
Half the effort is satisfying static analysis before you even reach tests. An agent trained on SWE-bench hasn't practiced this loop. It knows how to make pytest pass, but it doesn't know how to iteratively fix borrow-checker errors or satisfy TypeScript's strict null checks.
Goatfied runs compile and lint gates after every edit. The agent sees the same errors you would see, adjusts types or borrows, and re-checks until the code is valid—before moving to the next file. This mirrors how experienced developers work in typed languages: fix the compiler errors as you go, don't stack up broken code and hope it resolves later.
This is invisible in SWE-bench scores but critical in real productivity. A tool that can't navigate a type system will generate diffs that don't compile, forcing you to manually fix imports, type annotations, and interface mismatches—exactly the grunt work you wanted the AI to handle.
Benchmark-tuned versus workflow-tuned
Another hidden variable: some tools are explicitly optimized for SWE-bench performance. They recognize the benchmark's structure (issue text → patch → test suite), tune prompts and retry logic specifically for that flow, and publish the resulting score.
That's fine—benchmarks exist to be optimized. But a system tuned for SWE-bench may not generalize to your workflow. If your process involves:
- Writing tests first, then implementing
- Updating API specs before touching code
- Generating database migrations alongside model changes
- Running security scans or license checks before merge
…then an agent optimized for "read issue, write patch" hasn't practiced your actual loop.
Self-hosted or managed deployment matters too. SWE-bench runs in an isolated container with full repository access. Your production environment might have network restrictions, secrets management, private package registries, or compliance gates. A tool that aces the benchmark in a clean container might fail in your infrastructure.
Goatfied offers both self-hosted (run in your VPC, your network, your compliance boundary) and managed options. The agent's validate-first architecture works the same in both, but deployment flexibility means you can test in an environment that mirrors production rather than hoping benchmark performance transfers.
What to measure instead
If SWE-bench doesn't predict daily productivity, what does? Track metrics that reflect your actual development loop:
- Time to first reviewable PR. How long from task assignment to a diff that passes CI and is ready for human review?
- Revision cycles per merge. How many back-and-forth iterations before the code ships?
- Compile/lint/test pass rate on first submission. Does the agent produce diffs that pass your gates, or do you spend time fixing errors?
- Context efficiency. How much irrelevant code does the tool load? Can it work in a large repository without hitting token limits?
- Merge rate. What percentage of AI-generated PRs actually land in main, versus getting abandoned or rewritten?
These are harder to measure than a single benchmark score, but they're the numbers that determine whether AI coding tools ship features or create review backlog.
Run small internal pilots. Pick three real tasks from your backlog—not toy problems, not SWE-bench issues, but actual features or bugs your team needs to ship. Give the AI tool the same context a junior engineer would get. Measure how much human intervention is required to get the code merged.
That's your real benchmark.
