Many developers encounter scenarios where they need to simulate ISP-style bandwidth throttling - where initial connections get full speed but gradually get throttled after sustained usage. This technique is crucial for:
- Testing application behavior under limited bandwidth
- Creating fair usage policies
- Simulating real-world network conditions
- Preventing bandwidth hogging by specific processes
Linux offers two primary tools for traffic shaping:
# Basic check for required tools
which iptables tc || echo "Install iproute2 and iptables first"
The real magic happens when we combine iptables for packet marking with tc (Traffic Control) for actual shaping.
Here's a complete solution that throttles TCP connections after they exceed 10MB of transfer:
#!/bin/bash
# Clean existing rules
tc qdisc del dev eth0 root 2>/dev/null
iptables -t mangle -F
# Create HTB hierarchy
tc qdisc add dev eth0 root handle 1: htb
tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit
# Default class (full speed)
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 100mbit
# Throttled class (1mbit after threshold)
tc class add dev eth0 parent 1:1 classid 1:20 htb rate 1mbit
# SFQ for fairness
tc qdisc add dev eth0 parent 1:10 handle 10: sfq
tc qdisc add dev eth0 parent 1:20 handle 20: sfq
# Mark packets in iptables
iptables -t mangle -A POSTROUTING -o eth0 -p tcp -m connbytes --connbytes 10485760: --connbytes-dir both --connbytes-mode bytes -j CLASSIFY --set-class 1:20
For more precise control, consider these parameters:
# Gradual throttling based on transfer size
iptables -t mangle -A POSTROUTING -o eth0 -p tcp -m connbytes --connbytes 5242880:10485760 --connbytes-dir both --connbytes-mode bytes -j CLASSIFY --set-class 1:30
# Time-based throttling (slow after 30 seconds)
iptables -t mangle -A POSTROUTING -o eth0 -p tcp -m connmark --mark 0x0 -m recent --name slowlink --seconds 30 --set
iptables -t mangle -A POSTROUTING -o eth0 -p tcp -m recent --name slowlink --rcheck -j CLASSIFY --set-class 1:20
Check your traffic shaping with these commands:
# Show current classifications
tc -s class show dev eth0
# Monitor real-time bandwidth
iftop -i eth0 -f 'port 80 or port 443'
# Detailed connection tracking
conntrack -L
If throttling isn't working as expected:
- Verify your interface name (eth0 vs enp0s3 etc.)
- Check kernel modules:
lsmod | grep xt_connbytes
- Test basic iptables rules first before adding tc complexity
- Consider connection tracking limits in
/proc/sys/net/netfilter/
For high-traffic servers:
- Use connection marking early in mangle table
- Consider hashlimits instead of connbytes for scale
- Offload shaping to hardware if available
- Monitor CPU usage during peak traffic
When it comes to network traffic management on Linux systems, iptables remains one of the most powerful tools in a sysadmin's arsenal. While primarily known for firewall functionality, its combination with tc (traffic control) provides robust bandwidth shaping capabilities.
Static rate limiting is straightforward, but many real-world scenarios require more sophisticated approaches. Consider these use cases:
- Preventing bandwidth-hogging applications from starving other services
- Simulating ISP-style throttling for development/testing
- Implementing fair usage policies in shared environments
- Creating QoS rules that adapt to network conditions
Here's how to implement dynamic throttling that kicks in after initial bursts:
# Clear existing rules
tc qdisc del dev eth0 root
# Create HTB queuing discipline
tc qdisc add dev eth0 root handle 1: htb default 30
# Add root class
tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit ceil 100mbit
# Create throttled class (will activate after burst)
tc class add dev eth0 parent 1:1 classid 1:30 htb rate 512kbit ceil 1mbit burst 15k
# Add filter to direct traffic
tc filter add dev eth0 protocol ip parent 1:0 prio 1 handle 1 fw classid 1:30
# Mark packets with iptables
iptables -t mangle -A POSTROUTING -o eth0 -j MARK --set-mark 1
For more sophisticated control, we can implement time-dependent rules:
# Create time-based throttling (9am-5pm work hours)
iptables -t mangle -A POSTROUTING -o eth0 -m time --timestart 09:00 --timestop 17:00 -j MARK --set-mark 1
Verify your settings with these commands:
tc -s qdisc show dev eth0
tc -s class show dev eth0
iptables -t mangle -L -v -n
Some frequent challenges and solutions:
- Throttle not applying: Check if your interface uses eth0 or another name (ip link show)
- Rules disappearing: Make sure to persist rules across reboots (consider using iptables-persistent)
- Unexpected behavior: Double-check burst and ceil values - these significantly impact throttle behavior