TC - Traffic Control
The Linux kernel's network stack has network traffic control and shaping features. The iproute2 package installs the tc command to control these via the command line.
Queuing controls how data is sent; receiving data is much more reactive with fewer network-oriented controls. However, since TCP/IP packets are sent using a slow start the system starts sending the packets slow and keeps sending them faster and faster until packets start getting rejected - it is therefore possible to control how much traffic is received on a LAN by dropping packets that arrive at a router before they get forwarded. There are more relevant details, but they do not touch directly on queuing logic.
Direct TC / qdisc, tldr;
sudo sysctl -a | grep qdisc shows current default settings
sudo sysctl -a | grep net. shows all the net. parameters, additional deeper filters net.core, net.ipv4, net.ipv6, net.mptcp, and net.netfilter. There are a few additionals not shown in deeper filters!
sudo tc qdisc show dev eno1 shows current setting of interface dev eno1
it would seem that Linux has default settings for network interfaces, e.g.:
qdisc mq 0: root
qdisc fq_codel 0: parent :4 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
qdisc fq_codel 0: parent :3 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
qdisc fq_codel 0: parent :2 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
qdisc fq_codel 0: parent :1 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
Traffic Shaping with CAKE SQM
Bufferbloat is the reason your video calls stutter and your game ping spikes to 300ms whenever someone on your network starts a large download. When a router’s outgoing queue fills up, every packet - including latency-sensitive VoIP and gaming traffic - has to wait behind megabytes of bulk transfer data. A 10ms base latency turns into 200-500ms under load.
Test your connection at the Waveform Bufferbloat Test before doing anything. If you get a grade of C or worse, you have bufferbloat.
CAKE (Common Applications Kept Enhanced) is the modern Linux qdisc that fixes this. It combines Active Queue Management (AQM), Fair Queuing (FQ), and traffic shaping into a single qdisc. CAKE has been in the mainline kernel since 4.19, so no extra kernel modules are required on any modern distro. It replaced the older approach of combining fq_codel with htb shaping - CAKE does everything in one shot with less configuration.
Upload Shaping
Apply CAKE to your WAN interface with your upload bandwidth set to 90-95% of measured speed:
Key options:
bandwidth 450mbit - set to 90-95% of your actual upload speed (if your upload is 500 Mbps, use 450)
nat - enables proper flow identification for traffic behind NAT (required for routers)
wash - clears DSCP markings from upstream that might not match your local policy
ack-filter-aggressive - reduces TCP ACK congestion on asymmetric links (important if your download is much faster than upload)
Download Shaping with IFB
CAKE can only shape outgoing (egress) traffic. To shape incoming (ingress) traffic - which is where download bufferbloat lives - you redirect incoming packets through an Intermediate Functional Block (IFB) device and apply CAKE there:
bash script for ingress traffic
# Create and bring up IFB device
ip link add ifb-wan0 type ifb
ip link set ifb-wan0 up
# Redirect incoming WAN traffic to IFB
tc qdisc add dev wan0 handle ffff: ingress
tc filter add dev wan0 parent ffff: u32 match u32 0 0 \
action mirred egress redirect dev ifb-wan0
# Apply CAKE on the IFB device
tc qdisc replace dev ifb-wan0 root cake bandwidth 900mbit besteffort wash
Set the IFB bandwidth to 90-95% of your measured download speed.
Persist Across Reboots
These tc commands do not survive a reboot on their own. Create a systemd service:
sudo vim /etc/systemd/system/sqm.service
# /etc/systemd/system/sqm.service
[Unit]
Description=SQM (CAKE) Traffic Shaping
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
# Upload shaping
ExecStart=/sbin/tc qdisc replace dev wan0 root cake bandwidth 450mbit besteffort wash nat ack-filter-aggressive
# Download shaping via IFB
ExecStart=/sbin/ip link add ifb-wan0 type ifb
ExecStart=/sbin/ip link set ifb-wan0 up
ExecStart=/sbin/tc qdisc add dev wan0 handle ffff: ingress
ExecStart=/sbin/tc filter add dev wan0 parent ffff: u32 match u32 0 0 action mirred egress redirect dev ifb-wan0
ExecStart=/sbin/tc qdisc replace dev ifb-wan0 root cake bandwidth 900mbit besteffort wash
# Cleanup on stop
ExecStop=/sbin/tc qdisc del dev wan0 root
ExecStop=/sbin/tc qdisc del dev wan0 ingress
ExecStop=/sbin/ip link del ifb-wan0
[Install]
WantedBy=multi-user.target
Enable it: sudo systemctl enable --now sqm.service
Verify It Works
After applying CAKE, rerun the Waveform Bufferbloat Test. You should see latency under load drop from 200-500ms down to 5-15ms. Video calls stop freezing mid-sentence and game ping stays flat even during large transfers.
Monitor CAKE statistics
This shows drops, ECN marks, and per-tin flow counts. If you see high drop rates, your bandwidth setting may be too close to the actual line speed. Lower it by another 5%.
Links