Zero-copy techniques eliminate CPU-heavy data migration, boosting throughput by up to 300%. Master mmap, sendfile, and eBPF integration. Full breakdown.
Why Copying Is the Hidden Cost
In a conventional read-then-write path, data crosses the kernel boundary several times: from a device or socket into a kernel buffer, from there into a user-space buffer, and back into another kernel buffer on its way out. Each hop consumes CPU cycles, evicts useful cache lines, and adds latency that scales with payload size. For a system moving large files, video streams, or network packets at high volume, those copies dominate the profile long before application logic does.
Zero-copy techniques attack this directly by letting data move between sources and destinations without redundant trips through user space. The CPU stops acting as a byte-shuffling middleman and instead sets up the transfer, letting the kernel and hardware do the heavy lifting. Removing that migration is where the headline gains — throughput improvements reported as high as 300% — actually come from.
The Core Primitives: mmap and sendfile
The two most accessible tools are mmap and sendfile. With mmap, a file is mapped directly into a process's address space, so reads and writes touch the page cache instead of copying into a separate buffer. This is well suited to random access and to sharing the same pages across processes without duplicating them in memory.
sendfile targets the common case of moving bytes from a file descriptor to a socket. Instead of reading into user space and then writing back out, it instructs the kernel to transfer data internally, often keeping it entirely within kernel buffers. When you choose between them, weigh the access pattern:
- Use
mmapwhen you need to inspect or transform the data, or share it between processes. - Use
sendfilewhen you are relaying bytes untouched from storage to the network. - Watch for the tradeoffs: memory-mapped I/O can incur page-fault overhead and complicate error handling, while
sendfilegives you no chance to modify the payload in flight.
Pushing Logic Into the Kernel with eBPF
Zero-copy removes unnecessary movement, but you often still need to make decisions about the data — filtering, routing, or rewriting headers. eBPF lets you run small, verified programs inside the kernel at strategic hook points, so those decisions happen where the data already lives rather than after it has been copied up to a user-space process.
Paired with zero-copy paths, eBPF closes the loop: the transfer stays in the kernel, and the logic that inspects it does too. This is the pattern behind high-performance packet processing and observability tooling, where pulling every packet into user space would erase the gains that zero-copy just delivered.
Applying It Without Overreaching
Zero-copy is not free of tradeoffs. It ties your code more tightly to kernel behavior, makes buffer lifetimes and alignment your responsibility, and can complicate portability across platforms. The right move is to profile first and confirm that copying is actually your bottleneck before restructuring around these APIs.
When the profile does point at data migration, start with the narrowest primitive that fits — often sendfile for relay workloads — and reach for mmap or eBPF only where the access pattern demands it. The goal is to eliminate copies that never needed to happen, not to rebuild your whole I/O layer for its own sake.