On Wednesday, LWN.net published a subscriber-only feature titled “Moving beyond fork() + exec(),” and the Hacker News thread that followed — 320 points, 300-plus comments — made it clear the topic had struck a nerve. The article, by all accounts, is a serious technical survey of the decades-old Unix process-creation API and the kernel-level alternatives now under discussion. It is, in its way, important work.

It is also roughly ten years late.

The people who actually needed to move past fork()+exec() already did. They didn’t wait for a kernel mailing list thread to bless the effort. They didn’t file an RFC patch and endure six revision cycles of bikeshedding over naming conventions. They just built around the problem — in userspace, in language runtimes, in container orchestrators — and got on with shipping software. The LWN article is not the starting gun. It is the belated acknowledgment that a race was run, and the kernel community wasn’t invited.

Go, Rust, and the Quiet Revolt Against Process Spawning

Ask anyone who has built a high-throughput service in the past decade how they handle concurrency, and fork()+exec() will not be the answer. The Go runtime has been spawning lightweight goroutines since 2009 without ever touching fork(). Rust’s async ecosystem — built on top of tokio, not on process trees — treats the idea of forking per request as a museum piece. Even in C, the serious shops moved to thread pools and event loops when the C10K problem was still called the C10K problem.

fork()+exec() didn’t disappear because it was deprecated. It disappeared because it was expensive. Copying a process’s entire address space — page tables, file descriptors, signal handlers — only to immediately blow most of it away with exec() is a performance tax that made sense on a PDP-11 and nowhere since. The kernel community has known this for years. The 2019 “Fork() in the Road” paper by Microsoft Research and Boston University — cited in this week’s LWN discussion — laid out the pathologies in clinical detail. And yet, here we are in 2026, with the kernel still debating the fix while the rest of the industry shrugged and moved on.

Container Runtimes Already Solved This — Without Kernel Help

If you want to see where process creation actually got reimagined, look at the container ecosystem. containerd, runc, and the entire OCI runtime specification solved the “launch an isolated thing efficiently” problem by leaning on namespaces and cgroups — kernel features, yes — but the orchestration logic lived entirely in userspace. Nobody on a Kubernetes cluster is paying the fork()+exec() tax at request time. The processes are already running. The isolation is already set up. The overhead was amortized at deploy time, not per invocation.

A platform engineer I spoke with — mid-career, at a mid-tier cloud provider, messaging me from a #kernel-watching Slack channel that mostly exists for ironic commentary — put it this way: “We stopped caring about fork() performance when we realized the real bottleneck was the JVM heap, not the syscall. By the time the kernel folks figure out posix_spawn() extensions, we’ll be on our third rewrite of the service mesh.”

That is the cultural gap in one sentence. The kernel community is debating the correct API surface for a problem whose urgency passed while they were still arguing about the cover letter format for the patch series.

The Center of Gravity Has Shifted — and the LKML Missed It

None of this is to say that improving fork()+exec() is pointless. There are real use cases — setuid binaries, privilege-separated daemons, certain high-performance computing workloads — where a kernel-level solution would help. But treating this as a pressing innovation frontier in 2026 is like a municipal planning board finally approving a bridge design for a river the town already learned to cross by boat.

The uncomfortable implication is that the center of gravity for systems programming has shifted away from the kernel. The interesting work — the work that determines what a production system actually looks like at scale — happens in language runtimes, in orchestrators, in eBPF programs that monkey-patch kernel behavior from userspace. The LKML is not irrelevant. But it is increasingly a trailing indicator, not a leading one.

A generation of engineers has internalized the lesson: if you need the kernel to change before you can solve your problem, you have already misdiagnosed the problem. The LWN article is a fine piece of technical journalism. It is also a museum label for an exhibit the public left years ago.

Sources