How Zero‑Copy and sendfile Boost Server Performance
This article explains the concepts of user space and kernel space, shows how traditional file‑to‑socket transfers involve multiple data copies with read/write system calls, and demonstrates how the Linux sendfile system call implements zero‑copy to reduce copies and system calls for high‑performance servers.
User Space and Kernel Space
In a 32‑bit Linux process the virtual address space is 4 GB. The lower 0 GB–3 GB region is the user space where application code runs. The upper 3 GB–4 GB region is the kernel space that holds the operating system and its data structures.
File Transfer Without Zero‑Copy
A typical server that sends a file to a client performs two system calls: read – copies data from the file’s page cache into a user‑space buffer. write – copies the buffer from user space into the socket’s kernel buffer.
This results in two memory copies: kernel page cache → user buffer → kernel socket buffer .
while ((n = read(file, buf, 4096)) > 0) {
write(sock, buf, n);
}Zero‑Copy Transfer with sendfile
The Linux sendfile system call moves data directly from the kernel page cache to the socket buffer, bypassing user space. Its prototype is:
#include <sys/sendfile.h>
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);Parameters: out_fd – destination descriptor, usually a socket. in_fd – source descriptor, typically an open file. offset – pointer to the file offset; if NULL, the current file position is used. count – number of bytes to transfer.
Using sendfile eliminates one read system call and the associated copy from kernel to user space, reducing CPU usage and increasing throughput.
Practical Example
Assume in_fd is an opened regular file and out_fd is a connected TCP socket. The following loop sends the entire file in chunks of up to count bytes:
off_t off = 0;
size_t chunk = 65536; // 64 KB per call
while (1) {
ssize_t sent = sendfile(out_fd, in_fd, &off, chunk);
if (sent == 0) break; // EOF reached
if (sent < 0) {
perror("sendfile");
break;
}
// 'off' is advanced automatically by the kernel
}After the loop the file descriptor can be closed; the kernel has transferred the data without copying it into user memory.
Other Zero‑Copy Mechanisms
Linux provides additional APIs that achieve similar zero‑copy behavior: mmap – map a file directly into the process address space and let the network stack DMA from the mapped pages. splice – move data between file descriptors (including pipes and sockets) without user‑space buffers.
Direct I/O ( O_DIRECT) – bypasses the page cache for file I/O, allowing the application to manage buffers that can be DMA‑ed.
All these techniques reduce the number of memory copies and system calls, which is essential for high‑performance servers.
Conclusion
The sendfile system call demonstrates a simple and efficient zero‑copy method for sending files over a network. By moving data directly from the kernel’s page cache to the socket buffer, it saves one copy and one system call compared with the traditional read / write loop. Developers needing higher throughput should also consider mmap, splice, and direct I/O, depending on the specific use case.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Liangxu Linux
Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
