Reduce Queueing Delay with tc fq_codel
You will finish with an fq_codel queueing discipline on a Linux network interface, a way to inspect its live counters, and a recovery path if the change does not suit the link. FQ_CoDel combines per-flow fair queuing with CoDel delay management, so busy flows are less likely to let one large queue dominate the interface.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about 15 minutes, including a short observation period. You need the tc command from the iproute2 package and root privileges for changes. These examples were checked with iproute2 6.1.0-1ubuntu6.4, whose utility reports iproute2-6.1.0. Replace eth0 with the interface that actually carries the traffic.
Checkpoint
This guide changes the live root qdisc. Do it during a maintenance window if the interface carries a production connection. Keep an existing network-management configuration handy, because deleting or replacing a qdisc can affect latency, packet drops and traffic shaping immediately.
1. Identify the interface and current qdisc
Use an ordinary, read-only shell to find the interface and its current queueing discipline:
$ ip -br link
$ tc qdisc show dev eth0
The first command gives you the interface name. The second may show noqueue, fq_codel or another qdisc. Record that output before changing anything. If a traffic shaper, virtual machine manager or network service owns the interface, make the change through that system's configuration instead of fighting it with a one-off command.
On the installed machine, an existing FQ_CoDel queue reports fields such as limit 10240p, flows 1024, quantum 1514, target 5ms, interval 100ms, memory_limit 32Mb and ecn. Your interface may differ.
2. Apply the default FQ_CoDel queue
Replacing the root qdisc is an elevated operation and can interrupt or reorder how traffic is queued. Set a shell variable first, then run the command with sudo:
DEV=eth0
sudo tc qdisc replace dev "$DEV" root fq_codel
This uses the documented defaults: a 10,240-packet hard queue limit, 1,024 flow slots, a 1,514-byte fair-queuing quantum, a 5 ms target, a 100 ms interval, a 32 MB memory limit and ECN marking enabled. The packet and byte limits are both enforced, with the lower effective capacity controlling the queue.
FQ_CoDel hashes packets into flow slots. Hashing is stochastic, so two flows can share a slot. Packets within a flow remain FIFO, which avoids deliberately reordering that flow. A newer flow can receive service before an older one, but this does not create an unlimited priority scheme.
Checkpoint
Verify the installed qdisc before generating traffic:
$ sudo tc qdisc show dev eth0
qdisc fq_codel 8002: dev eth0 root refcnt 2 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
The handle and reference count can vary. Check for qdisc fq_codel and the settings, not for one exact handle.
3. Inspect counters while the link is busy
Use the statistics form after a transfer, download or other representative workload:
$ sudo tc -s qdisc show dev eth0
qdisc fq_codel 8002: dev eth0 root refcnt 2 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
Sent 428514 bytes 2269 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
maxpacket 256 drop_overlimit 0 new_flow_count 0 ecn_mark 0
Real counts will differ. backlog shows packets waiting now. dropped is the total dropped by the qdisc, while drop_overlimit counts drops caused by reaching a limit. ecn_mark counts packets marked for ECN. A zero counter immediately after installation is normal, not proof that the queue will never build.
Run the same command before and after a known workload. Interpret the counters with the link's normal traffic pattern. A rising drop count can mean sustained congestion, a queue limit that is too small for the workload, or a downstream bottleneck that this interface cannot fix.
4. Tune only a measured requirement
For a first deployment, leave the defaults alone. The manpage describes target as the acceptable minimum standing or persistent queue delay. interval keeps the measured minimum fresh and should be on the order of the worst-case round-trip time through the bottleneck. Those values are latency decisions, not universal speed settings.
If measurement justifies a smaller queue and a shorter observed delay, apply explicit values:
sudo tc qdisc replace dev "$DEV" root fq_codel \
limit 2000 target 3ms interval 40ms
This retains the other defaults, including ECN. The limit value is packets, not bytes. Do not copy these numbers merely because they appear in an example. A limit that is too low can drop bursts; an interval that is too short can give CoDel too little time to observe and react to the path.
To disable ECN marking explicitly, add noecn. That is a compatibility decision: marking lets ECN-capable endpoints react without a drop, but endpoints and equipment must handle ECN correctly. Do not assume that noecn is safer just because it is familiar.
5. Undo the live change safely
There is no generic undo command that can reconstruct the qdisc you replaced. Use the output saved in step 1 and the configuration manager that normally owns the interface. If you intentionally want to remove the root qdisc and accept the system fallback, run:
sudo tc qdisc del dev "$DEV" root
sudo tc qdisc show dev "$DEV"
Deletion is service-disrupting. It may leave the interface with a fallback such as noqueue, and it does not restore a previous TBF, CAKE, HTB or vendor-managed configuration. Restore the recorded qdisc using its documented configuration, then verify again with tc qdisc show.
Done means
- You identified the correct interface and recorded its original qdisc.
sudo tc qdisc show dev eth0reportsfq_codelafter the change.- You checked
tc -s qdiscduring representative traffic and understand the counters. - You left
target,intervalandlimitat their defaults unless measurements justified tuning. - You know which configuration owner and recorded command will restore the previous queue.