Engineering posts
Wrapping io.Copy silently disables Go zero-copy transfers
- Category: Engineering post
- Status: discussion
- Sources: segflow.github.io
- Summary: Assel Meher (Grafana Labs) walks through how Go's standard library dispatches
io.Copytosendfile(2)when copying an*os.Fileto a*net.TCPConnand tosplice(2)for socket-to-socket forwarding, keeping data in kernel buffers. A 512 MiB benchmark shows the direct path using about 2,958sendfilesyscalls, while wrapping the source in a plain reader falls back to userspace copies with roughly 131,000 read and write calls and 3.4 times the CPU. Only*io.LimitedReaderis recognized by the runtime, so middleware such as a logging reader disables the fast path. - Why it matters: Proxies and file servers written in Go lose kernel zero-copy transparently when a reader wraps the source, and the fix is to expose optional interfaces or avoid wrapping.