Throttling Bandwidth on OS X

Recently I started pushing a repository to GitHub only to find out it was a couple of GB in size. Due to my ISPs network connection being made of soiled tissue paper, dead earwigs and lost hope, it quickly saturated it. This interrupted watching Breaking Bad on Netflix. Clearly something had to be done.

Enter ipfw.

ipfw is more generally thought of as a utility for managing firewall rules on OS X, but it’s also great for shaping traffic. Doing that is a simple two step process: create an ipfw pipe for a data flow and then configure how big that pipe is.

First, create a pipe which matches a flow of data. A pipe is a combination of source address, destination address and optional matching patterns. In my case I wanted to affect outgoing traffic to port 22 which is used by ssh, the program git generally talks to servers with:

$ sudo ipfw add pipe 1 ip from any to any out dst-port 22

I’ve been a bit lazy here by using any for the IP address fields. I know that only my connection to github will be using dst-port 22. The from IP address and to IP address may be written as a specifc IP, or a range of IPs using CIDR notation, instead of the any wildcard. I’ve specifically set the rule to only match out going traffic. If you want to control the flow of data in both directions, you would generally create an in pipe and an out pipe separately

Note that I’ve named this pipe 1. This number is used to uniquely identify the pipe when carrying out other operations on it. If you create more than one pipe, be sure to use unique numbers for each one.

Next, we have to configure the pipe to control the data flow:

$ sudo ipfw pipe 1 config bw 75KBytes/s

The bw setting ensures that data passing through pipe 1 is transferring at most 75 KBytes per second. You can set this to whatever value is suitable for your connection.

If you want, you can check what connections are being affected:

$ sudo ipfw pipe list
00001: 600.000 Kbit/s    0 ms   50 sl. 1 queues (1 buckets) droptail
    mask: 0x00 0x00000000/0x0000 -> 0x00000000/0x0000
BKT Prot ___Source IP/port____ ____Dest. IP/port____ Tot_pkt/bytes Pkt/Byte Drp
  0 tcp     685   991700 31 43792   0

Finally, don’t forget to remove the pipe when you no longer need to limit the data transfer rate:

$ sudo ipfw pipe delete 1

There are many other options in ipfw for shaping traffic, including commands for dropping a certain percentage of packets (great for testing game networking code), and you can limit the bandwidth to very small rates which is handy for seeing how slow connections experience websites you create. Check out the man page for more details.