2 AM, I got an alert: database server throughput had dropped to 40% of normal, with latency spiking. SSH’d in to check the logs — nothing unusual. top, iostat, vmstat all looked fine. Finally I ran one command and immediately saw the problem: the network card was running at 100Mbps half-duplex instead of 1Gbps full-duplex because the switch port had been reset after a maintenance window. That command was ethtool.
This is a tool I use weekly managing the network for a 50-person office and a small datacenter. No complex installation needed — ethtool is available on most Linux distros and lets you see everything about your NIC that ip link or ifconfig can’t show you.
Quick Start: Up and Running in 5 Minutes
Install ethtool if you don’t have it:
# Debian/Ubuntu
sudo apt install ethtool
# RHEL/CentOS/Rocky Linux
sudo dnf install ethtool
Check your network card status right away:
# Check interface name first
ip link show
# Check NIC (replace eth0 with actual name: ens3, enp2s0, ...)
sudo ethtool eth0
Typical output:
Settings for eth0:
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Supports auto-negotiation: Yes
Speed: 1000Mb/s
Duplex: Full
Auto-negotiation: on
Link detected: yes
The three most important lines: Speed, Duplex, and Link detected. Seeing Speed at 100Mb/s or Duplex as Half on a production server — that’s a problem that needs immediate attention, no waiting.
Understanding ethtool Output
Speed and Duplex — The Troublesome Pair
Speed is easy to spot, but Duplex is what actually causes problems that many people overlook:
- Full-duplex: Send and receive data simultaneously — the normal mode for modern servers.
- Half-duplex: Only one direction at a time, like a walkie-talkie. Effective throughput drops to 30–50%, collisions skyrocket.
A classic scenario: a database server suddenly slows down after the infra team swaps a switch, without telling anyone. ethtool immediately reveals the new switch port defaulted to half-duplex. Force both ends to 1Gbps full-duplex — done in 2 minutes.
Auto-negotiation
Auto-negotiation automatically agrees on speed/duplex between the NIC and switch. In most cases, just leave it on — it handles itself. But older switches or cheap managed devices sometimes negotiate incorrectly, reporting Speed: 100Mb/s even when the cable and port are both 1Gbps capable. In those cases, forcing it manually is the only fix.
Link detected: no
If you see this line — the cable is broken, unplugged, or the switch port is down. Don’t waste time debugging software when the problem is physical.
Practical ethtool Commands
Check Driver and Firmware
sudo ethtool -i eth0
driver: e1000e
version: 3.2.6-k
firmware-version: 3.4.4
bus-info: 0000:00:19.0
supports-statistics: yes
When I hit a strange NIC issue, I always check the driver version first. Sometimes a kernel driver update is all it takes to fix things, without having to dig any deeper.
View Network Error Statistics
sudo ethtool -S eth0 | grep -E "error|drop|miss|fail"
Look for counters like rx_errors, tx_dropped, rx_missed_errors. If these values keep climbing — the problem is at the hardware or driver layer, not the application.
Configuring Speed and Duplex
Manually Force Speed and Duplex
When auto-negotiation isn’t working correctly:
# Force 1Gbps full-duplex, disable auto-negotiation
sudo ethtool -s eth0 speed 1000 duplex full autoneg off
# Force 100Mbps full-duplex
sudo ethtool -s eth0 speed 100 duplex full autoneg off
# Re-enable auto-negotiation
sudo ethtool -s eth0 autoneg on
Important: These changes are lost after reboot. See the Tips section below to make them persistent.
Enable/Disable Wake on LAN
# Enable WoL (magic packet)
sudo ethtool -s eth0 wol g
# Disable WoL (saves power on servers that don't need it)
sudo ethtool -s eth0 wol d
NIC Performance Optimization (Advanced)
Ring Buffer — The Buffer That Decides Whether Packets Survive or Drop During Traffic Bursts
The ring buffer is memory on the NIC used to queue packets before the kernel has a chance to process them. Many NICs default to just 256 slots — on a high-traffic server, that fills up in a few milliseconds during a burst, and packets start getting dropped outright.
# View current ring buffer settings
sudo ethtool -g eth0
Ring parameters for eth0:
Pre-set maximums:
RX: 4096
TX: 4096
Current hardware settings:
RX: 256
TX: 256
# Increase ring buffer to maximum
sudo ethtool -G eth0 rx 4096 tx 4096
I applied this setting across all servers in the datacenter after an incident: a log aggregation server was suddenly dropping packets during peak traffic. Increasing the RX buffer from 256 to 4096 — the problem completely disappeared without adding any hardware.
Offloading Features
Modern network cards don’t just transmit bits — they also offload many compute-intensive tasks from the CPU. That collection of capabilities is called offloading. Check what’s currently enabled:
sudo ethtool -k eth0
Features for eth0:
rx-checksumming: on
tx-checksumming: on
scatter-gather: on
tcp-segmentation-offload: on
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: off [fixed]
Key features:
- rx/tx-checksumming: NIC computes checksums instead of the CPU — keep this on.
- tso (TCP Segmentation Offload): NIC handles segmenting large TCP segments — significantly increases throughput.
- gro (Generic Receive Offload): Combines multiple small packets before passing them to the kernel — reduces interrupt overhead.
# Enable GRO if it's off
sudo ethtool -K eth0 gro on
# Disable TSO (sometimes needed with virtual NICs in VMs)
sudo ethtool -K eth0 tso off
Note for VMs: In virtualized environments (KVM, VMware), some offload features can cause unexpected throughput behavior. I usually disable LRO and sometimes TSO on VMs when I see unexplained performance issues.
Coalesce Settings — Reducing CPU Interrupts
Every packet arriving at the NIC triggers an interrupt to the CPU. On a server receiving tens of thousands of packets per second, this overhead adds up significantly. Coalescing batches multiple packets into a single interrupt — reducing how often the CPU gets interrupted, with a noticeable improvement in throughput:
# View current coalesce settings
sudo ethtool -c eth0
# Increase interrupt coalescing (reduces CPU interrupts, slightly increases latency)
sudo ethtool -C eth0 rx-usecs 50 tx-usecs 50
Trade-off to know: higher coalescing → fewer CPU interrupts, better throughput, but slightly higher latency. Well-suited for throughput-heavy workloads like backups and file transfers. For latency-sensitive workloads like real-time processing, keep the values low or leave them at default.
Practical Tips from Production Environments
Making Changes Persistent After Reboot
All ethtool changes are lost after a reboot. Here’s how to make them persistent on Ubuntu/Debian using networkd-dispatcher:
sudo nano /etc/networkd-dispatcher/routable.d/ethtool-tuning.sh
#!/bin/bash
IFACE="eth0"
ethtool -G $IFACE rx 4096 tx 4096
ethtool -K $IFACE gro on tso on
ethtool -C $IFACE rx-usecs 50
sudo chmod +x /etc/networkd-dispatcher/routable.d/ethtool-tuning.sh
On RHEL/CentOS with NetworkManager:
# Add to /etc/sysconfig/network-scripts/ifcfg-eth0
ETHTOOL_OPTS="speed 1000 duplex full autoneg off"
Quick NIC Health Check Script
I wrote this script to run immediately when taking on a new server or after any maintenance window:
#!/bin/bash
# check-nic-health.sh
for iface in $(ls /sys/class/net | grep -v lo); do
echo "=== $iface ==="
speed=$(ethtool $iface 2>/dev/null | grep Speed | awk '{print $2}')
duplex=$(ethtool $iface 2>/dev/null | grep Duplex | awk '{print $2}')
link=$(ethtool $iface 2>/dev/null | grep "Link detected" | awk '{print $3}')
echo " Speed: $speed | Duplex: $duplex | Link: $link"
rx_err=$(ethtool -S $iface 2>/dev/null | grep rx_errors | awk '{print $2}')
tx_drop=$(ethtool -S $iface 2>/dev/null | grep tx_dropped | awk '{print $2}')
[ -n "$rx_err" ] && echo " RX Errors: $rx_err | TX Dropped: $tx_drop"
echo ""
done
sudo bash check-nic-health.sh
When Should You Use ethtool?
- Abnormally low throughput while CPU/disk/application all look fine → check speed/duplex immediately.
- Unexplained packet loss →
ethtool -Sto view error counters. - Taking on a new server or after replacing a switch/cable → verify link speed and duplex.
- Optimizing servers handling high traffic (database, proxy, log aggregator) → tune ring buffer and offloading.
- VM with unusual throughput → check and adjust offload features.
ethtool isn’t a tool you use every day, but when you need it — it points you directly at the problem that ping, ss, or iperf3 can’t diagnose. Next time it’s 2 AM and the network is misbehaving for no apparent reason, sudo ethtool eth0 is the first command I run after SSH’ing into the server.

