Herr Bischoff

Throttling Linux Network Bandwidth by IP Address and Time of Day

Just now I found a fantastic and low-friction way to throttle network bandwidth on a Linux server — by use of the tc command. This command comes as part of any Linux or BSD installation, which is nice because I like working with standard utilities whenever possible.

It’s a three-step process.

First, create a class based queue on your interface (in my case eth0). This command tells the kernel to assume a 100mbit interface speed to base calculations on.

tc qdisc add dev eth0 root handle 1: cbq avpkt 1000 bandwidth 100mbit

Then create a 512kbit class with some reasonable defaults.

tc class add dev eth0 parent 1: classid 1:1 cbq rate 512kbit allot 1500 prio 5 bounded isolated

Finally, tell which traffic should go to the shaped class. Only traffic matched by this rule gets shaped. In our case, we define an IP address.

tc filter add dev eth0 parent 1: protocol ip prio 16 u32 match ip dst flowid 1:1

That’s it. You can effectively limit the bandwidth that goes to a specific IP address. Add more filters if you like. If you made an unrecoverable error, just run tc qdisc del dev eth0 root to delete everything and start with a clean slate.

For extra awesomeness, you could set up a cronjob that sets different limits for different times of day, for example. The following is an example I use on a clients’ Debian-based server with a severely contrained internet connection to rate limit the bandwidth for offsite backups during regular work hours. Because sometimes a backup has to run for several days on that connection.

30 8 * * * /sbin/tc class change dev eth0 classid 1:1 cbq rate 0.5mbit allot 1500 prio 5 bounded isolated
30 18 * * * /sbin/tc class change dev eth0 classid 1:1 cbq rate 4mbit allot 1500 prio 5 bounded isolated

This starts limiting traffic to the backup server starting at 8.30 am and restores full bandwidth at 6.30 pm.