July 5, 2026
Copy, paste, and chaos
Zero-copy in Go: sendfile, splice, and the cost of io.Copy
One tiny wrapper wrecked speed, and the comments instantly turned feral
TLDR: A one-line change made a Go server dramatically slower because it accidentally disabled a built-in fast lane for sending files. Commenters split between “great reminder, hidden magic is dangerous” and “this post is AI slop,” turning a niche bug story into a classic internet pile-on.
A programmer thought they’d made a tiny, harmless tweak: wrap a file with a little reader so they could count bytes for logging. Instead, their server basically face-planted. CPU use doubled, speed got cut in half, and the villain was hilariously small: that wrapper stopped Go from using a special kernel shortcut that moves file data to the network the fast way, without dragging it through the app first. In plain English: one extra layer turned a freeway into a school-zone traffic jam.
And the comments? Pure tech-forum theater. Some readers loved the lesson, calling it a brutal but useful reminder that “performance is observable behavior” and that “magic is an antipattern” — basically, if your code is fast only because of hidden tricks, expect heartbreak. Others chimed in with the classic cross-language flex, noting that Rust has similar smart-copy shortcuts too, because no programming thread is complete without a little language rivalry. Rust docs even got name-dropped like receipts in a feud.
But then came the real spice: several commenters didn’t just debate the code, they dragged the writing itself. More than one person bluntly called it “AI slop,” saying the post was padded with fluff and “meaningless information.” Another commenter went full philosophy-brain, comparing the bug to the expression problem, which is the most Hacker News way possible to say: “Congrats, your innocent new wrapper created a weird edge case nobody saw coming.” So yes, the article was about file copying — but the comments turned it into a brawl over hidden complexity, programming “magic,” and whether the post itself deserved a performance optimization.
Key Points
- •The article reports that wrapping an `*os.File` in a custom logging reader before calling `io.Copy` disabled Go’s `sendfile(2)` optimization, increasing CPU usage and reducing throughput.
- •The benchmark setup used a 512 MiB file, warm page cache, plain TCP on the same machine, pinned client/server CPUs, and syscall tracing with `strace`.
- •The article explains that `sendfile(2)` avoids the usual userspace `read()` and `write()` path by moving data from the page cache to the socket buffer inside the kernel.
- •In Go, `io.Copy(conn, f)` can trigger zero-copy because `*net.TCPConn` implements `io.ReaderFrom` and its `ReadFrom` method checks for an `*os.File` source or an `*io.LimitedReader` wrapping one.
- •A minimal custom `io.Reader` wrapper around a file hides the concrete `*os.File` type and causes fallback copying, while `io.LimitReader` preserves the optimization because Go explicitly unwraps `*io.LimitedReader`.