How to Use the Linux ethtool Command to Optimize Network Interface Card (NIC) Offloading

The CPU Networking Bottleneck

When an enterprise Linux server is pushing massive amounts of network traffic—such as a 10-Gigabit video streaming server or a high-frequency trading database—the primary bottleneck is rarely the physical ethernet cable. The bottleneck is the server’s CPU.

Historically, when a 1500-byte network packet arrived at the Network Interface Card (NIC), the NIC generated a hardware interrupt, forcing the CPU to stop what it was doing, calculate the complex TCP checksum to ensure the packet wasn’t corrupted, and reassemble the payload. If a server receives one million packets per second, the CPU is completely paralyzed by interrupts and checksum calculations. The web server or database application starves because the CPU spends 90% of its time acting as a network traffic cop.

To eliminate this catastrophic bottleneck, hardware manufacturers engineered modern NICs with dedicated onboard silicon processors. However, the Linux kernel does not always utilize these processors optimally. To manually offload the mathematical burden from the CPU to the physical network card, UNIX engineers use the ethtool command. By enabling advanced hardware offloading (like Checksum Offload, TSO, and GRO), administrators can instantly drop CPU utilization by 40% while pushing maximum line-rate bandwidth.

Step 1: Interrogating the Current NIC Capabilities

Before modifying any parameters, you must ask the physical network card what specific hardware features its silicon supports.

Identify your primary interface (e.g., eth0) and run the interrogation command:

sudo ethtool -k eth0

The -k (lowercase k) flag dumps the exhaustive list of offloading features. You will see a massive list of parameters, such as:

rx-checksumming: on
tx-checksumming: on
tcp-segmentation-offload: off
generic-receive-offload: on

If a feature says [fixed] next to it, the hardware physically cannot change that state (either it doesn’t support the feature, or the driver permanently locked it). If it does not say fixed, you can programmatically toggle it.

Step 2: Enabling Checksum Offloading

The most fundamental optimization is the Checksum Offload. Every single TCP and IP packet contains a mathematical checksum header. Validating this header is computationally expensive.

If rx-checksumming (Receive) or tx-checksumming (Transmit) is listed as off, the CPU is doing the math.

To command the hardware NIC to execute the checksum math on its own internal silicon, you use the -K (Uppercase K) flag to modify the state:

sudo ethtool -K eth0 rx on tx on

The exact millisecond you press Enter, the Linux kernel stops calculating checksums for eth0. The CPU load will instantly drop, as the raw mathematical processing is offloaded to the Broadcom or Intel chip on the PCIe card.

Step 3: Enabling Segmentation Offloading (TSO and GSO)

When an application (like an Apache web server) wants to send a massive 64-Kilobyte image to a client, it cannot send it all at once. The standard Ethernet frame size (MTU) is only 1500 bytes. The CPU must violently slice that 64KB image into roughly 44 tiny packets, attach headers to every single one, and queue them for the NIC.

TCP Segmentation Offload (TSO) fixes this. If TSO is enabled, the CPU simply hands the massive 64KB block of data directly to the NIC. The physical NIC’s silicon performs the tedious slicing and header generation autonomously.

To enable TSO (and its generic counterpart, GSO):

sudo ethtool -K eth0 tso on gso on

This single command drastically reduces the number of interrupts the CPU must process, massively increasing total outbound throughput on 10Gbps or 40Gbps links.

Step 4: Managing Receive Offloading (GRO and LRO)

The inverse of TSO is for inbound traffic. If a server receives 44 tiny packets from a client, the CPU normally has to process 44 separate interrupts and reassemble them.

Generic Receive Offload (GRO) and Large Receive Offload (LRO) command the NIC to wait for a microsecond, intercept all the tiny packets, merge them into a single massive 64KB block, and deliver exactly one interrupt to the CPU.

sudo ethtool -K eth0 gro on lro on

Warning: While GRO is highly stable and widely recommended, LRO can actually break a Linux server if it is acting as a Router or Firewall (forwarding packets), because LRO fundamentally alters the packet headers. Only enable LRO on destination endpoints (like a Database or Web Server).

Step 5: Making the Changes Persistent

Like iptables or ip route, ethtool changes are highly volatile. The exact millisecond the server reboots, the NIC driver resets, and all your offloading optimizations are wiped out.

To make the changes permanent in modern Ubuntu deployments, you must integrate the ethtool command directly into the network interface configuration.

If you are using Netplan (the modern Ubuntu standard), you cannot natively define offloads inside the YAML file. The most robust enterprise solution is to write a systemd service that automatically fires the ethtool command immediately after the network stack initializes.

Create a file at /etc/systemd/system/ethtool-optimization.service:

[Unit]
Description=Optimize Network Interfaces
After=network.target

[Service]
Type=oneshot
ExecStart=/sbin/ethtool -K eth0 rx on tx on tso on gso on gro on

[Install]
WantedBy=multi-user.target

Enable the service (sudo systemctl enable ethtool-optimization), and your NIC will autonomously tune itself for maximum throughput on every reboot.

Conclusion

Pushing multi-gigabit throughput across enterprise Linux servers requires a fundamental decoupling of network processing from the main CPU. By mastering the ethtool utility, infrastructure engineers bypass the kernel’s software networking stack and directly address the physical silicon of the Network Interface Card. The ability to programmatically enable checksum offloading, TSO segmentation, and GRO batching transforms the CPU from a congested traffic controller back into a dedicated application processor, mathematically guaranteeing maximum line-rate performance.

RELATED POSTS

  • How to Use the Linux journalctl Command to Read systemd Logs
  • How to Use the Linux tar Command for Advanced Archive Compression and Extraction
  • How to Use the Linux lsof Command to Identify Open Files and Network Sockets
  • How to Use the Linux strace Command to Debug System Calls and Application Hangs
  • How to Use the Linux tty Command to Identify the Current Terminal Session
  • Get the best tech tips delivered straight to your inbox.

    Join thousands of readers mastering Apple, Google, Microsoft, and Linux.