← Back to Conduits Index

Conduit 05: Zero-Copy File Streaming via Linux sendfile() and splice()

⏱️ Reading Time: 15 mins 📅 Updated: August 2026 🏷️ Subsystem: Linux I/O Subsystem & DMA Controller 🎯 Author: Zhabrosima Technical SRE Team
Table of Contents

1. Production Bottleneck Context: CPU Context Switch Saturation

When delivering static assets, large firmware binary images, or video streams over a high-bandwidth 40Gbps backbone, traditional file I/O pipelines introduce severe system CPU overhead.

During a global release distribution event, media delivery proxy nodes running standard read/write routines saturated all 32 CPU cores at 100% utilization, while network interface throughput plateaued at less than 12Gbps (far below line rate).

System Metrics Baseline (dstat & perf top)
# 1. dstat System Performance Metrics
----total-cpu-usage---- -dsk/total- ---system--
usr sys idl wai stq| read writ| int   csw 
  8  82   0  10   0| 1.2G    0| 320k 1.8M  <-- 1.8 Million CPU Context Switches/sec!

# 2. perf top Kernel Profile
  42.10%  [kernel]  copy_user_generic_unrolled
  21.40%  [kernel]  page_fault
  12.80%  [kernel]  __fget_light

2. Deep Kernel Mechanics: Traditional I/O vs. DMA Zero-Copy Pipeline

To understand why system CPU utilization spiked to 82%, we must trace data buffer copies and CPU context switches during traditional read() / write() system calls.

[ 1. Traditional 4-Copy File Pipeline ]
 Disk ──> Page Cache ──> User Space Buffer ──> Socket Buffer ──> NIC Wire
          (DMA Copy)     (CPU Copy #1)        (CPU Copy #2)     (DMA Copy)
          [ 4 Context Switches + 2 Wasted CPU Buffer Copies ]

[ 2. Linux sendfile() Zero-Copy Pipeline ]
 Disk ──> Page Cache ══════════════════════════════════════════> NIC Wire
          (DMA Copy)       (Descriptor Pointer Copy Only)       (DMA Copy)
          [ 2 Context Switches + ZERO CPU Buffer Copies ]
            

Traditional 4-Copy File Delivery Pipeline

  1. Context Switch 1 (User → Kernel): The application invokes read(). The OS issues a DMA transfer from Disk to Kernel Page Cache.
  2. Copy 2 (Kernel → User): CPU copies data from Kernel Page Cache to Application User Buffer. (Context Switch 2: Kernel → User).
  3. Copy 3 (User → Kernel): The application invokes write(). CPU copies data from Application User Buffer to Socket Buffer. (Context Switch 3: User → Kernel).
  4. Copy 4 (Kernel → Device): DMA controller transfers data from Socket Buffer to Network Interface Card (NIC). (Context Switch 4: Kernel → User).
The Zero-Copy DMA Revolution (sendfile & Scatter-Gather)

By invoking the sendfile() syscall combined with NIC Scatter-Gather DMA, data is transferred directly from the kernel Page Cache to the Network Controller with ZERO CPU data copying and only 2 context switches. CPU usage drops from 80%+ down to near zero!

3. Production Nginx / OpenResty Zero-Copy Optimization Master Config

Configure Nginx to leverage Linux kernel sendfile(), tcp_nopush, and asynchronous Direct I/O (AIO) for large static media assets:

http {
    # ----------------------------------------------------------------------
    # Linux DMA Zero-Copy Engine Settings
    # ----------------------------------------------------------------------
    # 1. Enable Kernel sendfile() syscall
    sendfile            on;

    # 2. Bundle TCP headers and payload into single full-sized MTU packets
    tcp_nopush          on;
    
    # 3. Disable Nagle algorithm for low-latency header transmission
    tcp_nodelay         on;

    # 4. Asynchronous Thread Pool & Direct I/O for files > 16MB
    # Prevents large file reads from blocking PageCache lock
    aio                 threads;
    directio            16m;
    directio_alignment  4k;

    # Open File Descriptor Cache
    open_file_cache          max=10000 inactive=30s;
    open_file_cache_valid    60s;
    open_file_cache_min_uses 2;
    open_file_cache_errors   on;

    server {
        listen 80 reuseport;
        server_name cdn.zhabrosima.com;

        location /static/ {
            root /var/www/assets;
            
            # Browser Cache Control for static media
            expires 30d;
            add_header Cache-Control "public, no-transform";
        }
    }
}

4. Real-World SRE Live Diagnostic Toolkit

Use system-level diagnostic tools to measure context switch frequency and kernel I/O wait on live media streaming nodes:

1. Monitor System Context Switches (vmstat)

# Display system context switches (cs) and interrupts (in) every 1 second
vmstat 1

# Key Metric: Ensure 'cs' column remains under 50,000 under high throughput

2. Trace sendfile System Calls with strace

# Trace Nginx worker process sendfile64 syscall execution
sudo strace -p $(pgrep -f "nginx: worker" | head -n 1) -e trace=sendfile64

5. Kernel TLS (kTLS) Acceleration for Encrypted Zero-Copy

Historically, HTTPS encryption broke sendfile() because TLS payload transformation required copying packets into user-space memory (OpenSSL) for AES encryption before transmitting.

6. Verified Load Test Benchmarks: Traditional vs. Zero-Copy

We conducted a 10Gbps streaming file delivery benchmark (100MB video file payloads, 2,000 concurrent clients):

Performance Metric Traditional Read/Write Tuned DMA Zero-Copy System Impact
Network Throughput 11.8 Gbps (CPU Bound) 38.9 Gbps (Line Rate) +229.6% Throughput Gain
CPU Utilization (System Space) 82.4% System CPU 4.1% System CPU -95.0% CPU Load Drop
Context Switches / sec 1,840,000 /sec 22,400 /sec -98.7% Reduction

7. Prometheus Observability (PromQL Queries)