Your coding agent isn't faster on Linux. Your environment is just less of a variable.
Coding agents really do run better on Linux, but mostly for contingent reasons. The lasting point is that determinism matters more than raw speed once you're running agents at volume.
There's a claim making the rounds in every team that has started running coding agents seriously: Claude Code and Codex are dramatically better on Linux than on Windows. I've been saying a version of it myself. The same agent harness that grinds happily for hours on Linux turns into a support ticket on a Windows laptop. macOS sits somewhere in between and mostly works.
The observation is real. The conclusion most people draw from it is wrong, and that wrong conclusion costs more than the original problem did.
Bundled factors
Three different things get bundled into "Linux is better for agents," and they have completely different fixes.
The harness. My setup is three agents in tmux: an orchestrator, a builder, a validator, with strict file ownership rules between them. That is a Unix-native architecture, and Windows has no equivalent primitive. So a large part of what I measured is that my own design doesn't port, which is a statement about my design, not about Windows.
The model's priors. Agents write bash because their training data is bash. PowerShell is arguably the better shell for structured work, since you pipe objects instead of re-parsing text with awk. But the models write mediocre PowerShell and routinely mix cmd and PowerShell quoting inside a single command. That gap narrows as models improve, and it tells you nothing about the platform's capability.
Unfixed configuration. Defender real-time scanning applied to a node_modules tree is a large constant multiplier on every file operation. Most people never add repository exclusions, then generalise from the result.
Strip those three out and there's still a genuine platform delta. It's just much narrower than the folklore, and it concentrates in a predictable place: JVM-based content management stacks, where you have a deeply nested content tree serialised to XML, an embedded repository process, and a build chain that mixes Maven with Node.
Real platform failures
Path length. Content-tree exports produce paths that nest a dozen levels deep before you reach the leaf XML file, and clientside builds stack node_modules on top of that. Windows' 260-character limit gets hit constantly. LongPathsEnabled and core.longpaths help, but the JVM only honours long paths through NIO, and plenty of tooling in this space still reaches for legacy java.io.File. A partial fix is the worst kind of fix: it works until it doesn't, unpredictably, in the middle of an eight-hour autonomous run.
File locking. Embedded repositories hold open handles on their storage directory. An agent loop that tears down and rebuilds between iterations will, on Windows, eventually find a half-dead process it cannot delete the working directory of. That failure mode simply does not exist on Linux, and an agent has no good recovery strategy for it: it will retry, fail identically, and burn tokens narrating its confusion.
Platform binaries. Reverse proxy modules, cache components, and similar native pieces in this ecosystem ship for Linux and macOS first. On Windows you run them in Docker anyway, which means the "Windows setup" is already a Linux setup with extra indirection. You've paid the container cost without collecting the benefit.
Line endings. CRLF drift in serialised XML and template files changes content hashes and produces diff noise. In a human workflow that's an annoyance. In an agent workflow, your validator spends real tokens reasoning about whitespace.
One factor I'd expected to matter and didn't: content repositories are typically case-sensitive about node names while default APFS isn't, so macOS should have been bitten too. It wasn't, which tells me the content had no case collisions. Worth knowing, because it means case sensitivity isn't driving the delta and shouldn't be in the argument.
Reproducibility
Most teams get this backwards. "Which OS should we develop on" is the wrong thing to optimise. The binding constraint on a long-running agentic workload is not the laptop. It is whether anyone other than you can reproduce the run.
Think about the shape of this kind of work. It runs repeatedly over months rather than once. The agents consume enormous volumes of tokens. The output is a codebase somebody maintains afterwards. If the answer to "can you re-run the last few hundred pages" is "only on my box," you don't have a tooling preference problem. You have a single point of failure, and it surfaces at exactly the wrong moment: when you're away, when someone new needs to pick it up, or when the numbers have to be reproduced for someone who wasn't there.
The Linux-is-better framing quietly encourages this. It tells you to solve the problem by choosing the right machine, which is an individual-level fix to what is really a structural constraint.
Containerised toolchain
The version that survives contact with other people is to stop having a host OS at all. Put the entire chain (JDK, Maven, Node, the platform CLIs, the agent CLIs, tmux) into a container image and pin it. Then Windows works via Docker Desktop, macOS works, CI works, and a new joiner is productive in one command instead of a two-day setup ritual.
Three things I'd insist on, having watched this go wrong:
Pin aggressively. Base image by digest, not by tag. Node, JDK, and Maven by exact version. npm ci against a committed lockfile, never npm install. The point isn't tidiness. Every unpinned dependency is a source of diff noise, and diff noise is validator work, and validator work is what you're paying for.
Enforce LF at the repository boundary. A .gitattributes that forces LF on serialised content, plus a container that never touches a Windows filesystem, eliminates a whole class of phantom changes.
Keep secrets out of image layers. Mount credentials at runtime from a config directory outside the repository. An image containing an API key is an image you can never push anywhere, which defeats the purpose of building it.
One trap worth naming: on Windows, WSL2 is the obvious escape hatch and it's easy to get wrong. A repository living on /mnt/c and accessed from Linux goes through a filesystem translation layer that is dramatically slower than either native option. Keep the code inside the Linux filesystem, or you end up worse off than where you started. Same principle inside the container: anything a human edits gets bind-mounted, anything a tool generates lives in a named volume.
Summary
Linux is better for this work today, but mostly for contingent reasons: my harness is built from Unix primitives, the toolchains in this ecosystem ship Linux binaries first, and the models write better bash than PowerShell. None of those are laws of nature.
The durable point is that determinism matters more than raw speed once you're running agents at volume. An environment that behaves identically everywhere is worth more than one that is fifteen percent faster in one place. Optimise for the thing that doesn't depend on who's sitting at the keyboard.