In high-performance Linux server administration, network packet drops can occur even when physical bandwidth and CPU utilisation remain well below maximum capacity. When high-speed applications generate sudden microbursts of network traffic, packets that exceed the network interface card’s hardware buffer must wait in the operating system’s software transmission queue. If this buffer fills up, incoming packets are dropped immediately.
The parameter governing this buffer is txqueuelen (transmit queue length), which specifies the maximum number of packets allowed to queue in the Linux kernel network stack before being handed off to the physical NIC driver. Using the modern ip link utility, system administrators can inspect, tune, and persist queue lengths to cushion bursty workloads or eliminate bufferbloat. Here is how to change network interface transmit queue lengths in Linux using ip link.
Understanding txqueuelen and Buffer Tuning
On most Linux distributions, the default txqueuelen for standard 1GbE Ethernet adapters is set to 1000 packets. However, optimal tuning depends on your workload and link speeds:
- High-Throughput and 10GbE/40GbE/100GbE Environments: For high-bandwidth database replication, storage clusters (Ceph, NFS, iSCSI), or core routers, a queue length of 1000 is often too shallow. Increasing
txqueuelento 5000 or 10000 absorbs transient traffic spikes, preventing packet loss. - Low-Latency and Real-Time Systems: For VoIP, live video conferencing, or high-frequency financial trading, large queues can introduce undesirable latency known as bufferbloat. Lowering
txqueuelenensures stale packets are dropped rather than delayed in deep queues. - Virtual Interfaces: Certain virtual tunnel devices and bridges default to
qlen 0or1000, which may require tuning when routing heavy container or VM payloads.
Step 1: Check the Current Transmit Queue Length
To view the current transmit queue length for a network interface (e.g. eth0 or enp3s0), use the ip link command:
ip link show dev eth0
Inspect the output line following state UP:
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
link/ether 00:1a:2b:3c:4d:5e brd ff:ff:ff:ff:ff:ff
The parameter qlen 1000 represents your interface’s current transmit queue capacity.
Step 2: Change txqueuelen at Runtime Using ip link
To adjust the transmit queue length on an active network device, execute ip link set with administrative privileges:
Increasing txqueuelen for High-Bandwidth Servers
sudo ip link set dev eth0 txqueuelen 5000
For 10GbE or 25GbE enterprise adapters under heavy load, an even higher value is common:
sudo ip link set dev eth0 txqueuelen 10000
Verifying the Update
Run the inspection command once more to confirm that the kernel has accepted the new queue boundary:
ip link show dev eth0
Verify that qlen 5000 (or your chosen value) is now active.
Step 3: Monitor Transmit Packet Drops and Overruns
To determine whether increasing txqueuelen has resolved packet loss issues on your server, inspect the detailed interface statistics using the -s (statistics) flag:
ip -s link show dev eth0
Examine the TX (transmit) section of the output:
TX: bytes packets errors dropped carrier colls overrun
94812301 645120 0 0 0 0 0
If the dropped or overrun counters are incrementing during peak traffic hours, your queue depth was likely overflowing, indicating that a higher txqueuelen or enhanced queuing discipline (such as fq_codel or cake) is warranted.
Step 4: Persisting txqueuelen Across System Reboots
Commands executed via ip link are volatile and reset upon system reboot. To make your transmit queue length permanent, configure one of the following persistent mechanisms:
Method A: Using a Persistent udev Rule (Universal Across All Linux Distributions)
The most reliable method across Debian, Ubuntu, Red Hat, Rocky Linux, and Arch is creating a dedicated udev rule:
- Create a new udev rule file in
/etc/udev/rules.d/:sudo nano /etc/udev/rules.d/99-network-txqueuelen.rules - Add the following line, replacing
eth0with your adapter name and5000with your desired queue length:
(Alternatively, match by interface name usingSUBSYSTEM=="net", ACTION=="add", ATTR{address}=="00:1a:2b:3c:4d:5e", ATTR{tx_queue_len}="5000"KERNEL=="eth0", ATTR{tx_queue_len}="5000"). - Save the file and exit. The rule will trigger automatically during hardware initialization on every subsequent boot.
Method B: Using systemd-networkd
If your distribution relies on systemd-networkd, edit your network matching file (e.g. /etc/systemd/network/10-eth0.network):
[Match]
Name=eth0
[Link]
TransmitQueueLength=5000
[Network]
DHCP=yes
Commit your changes with sudo systemctl restart systemd-networkd.