1. Introduction

In this article, we are going to talk about limiting our network bandwidth. But, why would we want that in the first place? There may be several reasons throttling the network usage could come in handy.

For example, not everyone may enjoy fast and reliable internet access. In some cases, web developers might want to test their applications with limited network bandwidth. In other cases, we may want to restrict a process from taking most of our bandwidth.

Fortunately, we have several tools to control both upload and download bandwidth for specific processes and network interfaces. In the subsequent sections, we will explore some of those tools in-depth.

2. Traffic Control With tc

tc is a tool that gives us the power to manipulate traffic control settings in the Linux kernel. With tc, we can control and simulate various network configurations in general.

In this article, we will use tc to limit the egress network bandwidth rate on a specific network interface.

2.1. Getting the Network Interface Name

In order to control traffic in the kernel, the first thing we need to do is to learn the name of the network interface on our device. To do that, we can use the ifconfig (interface configuration) utility:

$ ifconfig
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.2.15  netmask 255.255.255.0  broadcast 10.0.2.255
        inet6 fe80::846d:f936:a75f:1067  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:bd:64:f3  txqueuelen 1000  (Ethernet)
        RX packets 123570  bytes 161331587 (161.3 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 43692  bytes 24001029 (24.0 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 1040  bytes 90834 (90.8 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1040  bytes 90834 (90.8 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

The second interface we see is just a loopback. In this case, the interface name of our physical network card is enp0s3.

2.2. Simple tc Usage

First, we’ll look at a simple tc example:

$ sudo tc qdisc add dev enp0s3 root netem loss 3%

Since we’re dealing with kernel function modifications, sudo or root privileges are required. In particular, we’re modifying how packets in the enp0s3 device (dev enp0s3) are queued for processing (qdisc) by adding (add) a rule affecting the outbound (also called root) traffic.

The rule simply directs data through the netem (network emulator) queuing discipline, enforcing a loss of 3%.

2.3. Limiting the Egress Traffic

Let’s now see how we can limit the outbound traffic using tc:

$ sudo tc qdisc add dev enp0s3 root tbf rate 500kbit burst 16kbit latency 50ms

In this case, we use tbf (token bucket filter) instead of netem. This discipline works with tokens, which, similar to bytes, roughly represent the ability of our queue to handle traffic in different ways.

For example, we limit the transfer rate to 500kbit. Further, we configure the burst: a buffer, which gets filled with each incoming packet. Importantly, it should be big enough to hold however many packets we might have to send in one tick.

Finally, we enforce a traffic delay of 50ms with the latency option.

2.4. Network Performance Comparison

We need to test whether this command works properly by inspecting the network performance before and after its application. If we have access to both a server and a client, we can utilize the iperf tool for our purposes.

However, it would be simpler to use speedtest-cli.

Let’s check the results before and after applying our ruleset:

$ speedtest
Retrieving speedtest.net configuration...
.
.
.
Testing download speed................................................................................
Download: 14.98 Mbit/s
Testing upload speed......................................................................................................
Upload: 4.56 Mbit/s
$
$ sudo tc qdisc add dev enp0s3 root tbf rate 500kbit burst 16kbit latency 50ms
$
$ speedtest
Retrieving speedtest.net configuration...
.
.
.
Testing download speed................................................................................
Download: 14.98 Mbit/s
Testing upload speed......................................................................................................
Upload: 0.66 Mbit/s

Our upload speed drops from 4.56Mbit/s to 0.66MBit/s as expected.

2.5. Displaying and Deleting Present Rules

When we want to see the existing rules on a particular interface, we can again use tc:

$ sudo tc qdisc show dev enp0s3
qdisc tbf 8003: root refcnt 2 rate 500Kbit burst 16Kb lat 50.0ms 

In addition, we can also delete rules:

$ sudo tc qdisc del dev enp0s3 root

This command deletes (del) all outbound (root) rules. Of course, we can apply the same to ingress rules as well, but we’ve not set any in this case.

3. Wondershaper Script Utility

Wondershaper is a simple Bash script that enables shaping the network traffic in Linux. It uses the aforementioned tc command in its backend to control the network bandwidth.

3.1. Limiting the Bandwidth System-Wide

We can easily use the utility in a command line for the purpose of throttling the downlink and uplink traffic on a particular network interface:

$ wondershaper [interface] [downlink] [uplink]

Let’s say we want to set the downlink limit to 2048 Kbits/sec and the uplink limit – to 512 Kbits/sec:

$ wondershaper enp0s3 2048 512

After that, we can confirm with speedtest:

$ speedtest
Retrieving speedtest.net configuration...
.
.
.
Testing download speed................................................................................
Download: 2.14 Mbit/s
Testing upload speed......................................................................................................
Upload: 0.62 Mbit/s

As with the previous example, our rates are limited as expected.

3.2. Clearing Existing Settings

Furthermore, we can delete the existing configuration for the bandwidth:

$ wondershaper clear enp0s3
Wondershaper queues have been cleared.

Consequently, we would now see our original bandwidth intact.

3.3. Apply the Configuration Permanently With Service Setting

The network configurations with Wondershaper last until the system reboots. Hence, if we want to make the changes permanent, we’d need to write a systemd configuration and service files accordingly.

4. Trickle

Last but not least, we can utilize a lightweight tool to throttle the network bandwidth called trickle. Trickle shapes the bandwidths of applications by manipulating the data traffic across sockets. It also enables us to manage the bandwidth over applications and processes, not interfaces like others.

4.1. Controlling the Bandwidth With Trickle

Using trickle for bandwidth control is quite intuitive, like wondershaper. Let’s launch a web browser with limited bandwidth:

$ trickle -s -d 2048 -u 512 firefox

The above command will launch the Firefox web browser with approximately 2 MB/sec download (-d 2048) and 0.5 MB/sec upload (-u 512) speeds by using Trickle’s standalone (-s) non-daemon mode. Also, note that, unlike wondershaper, we don’t need sudo privileges.

4.2. Limiting the Bandwidth of Commands

Moreover, we can make trickle limit the bandwidth of commands as well:

$ trickle -s -d 512 wget https://releases.ubuntu.com/20.04.4/ubuntu-20.04.4-desktop-amd64.iso
--2022-05-29 14:54:28--  https://releases.ubuntu.com/20.04.4/ubuntu-20.04.4-desktop-amd64.iso
Resolving releases.ubuntu.com (releases.ubuntu.com)... 91.189.91.124, 91.189.91.123, 185.125.190.40, ...
Connecting to releases.ubuntu.com (releases.ubuntu.com)|91.189.91.124|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3379068928 (3.1G) [application/x-iso9660-image]
Saving to: ‘ubuntu-20.04.4-desktop-amd64.iso.3’

ubuntu-20.04.4-desktop-amd64.iso.3                   0%[                                             ]   2.12M   526KB/s    eta 1h 54m 

Here, we started to download a file with wget with the bandwidth limit of roughly 512 KB/sec, as can be seen from the snapshot above.

4.3. Launching a Bash Shell With Desired Bandwidth Settings

Conveniently, we can launch an entire Bash shell with specified bandwidth limitations:

$ trickle -s -d 1000 -u 50 bash

In it, every command will have the specified amount of bandwidth. To remove the limitations, we can simply exit that Bash shell.

5. Conclusion

In this article, we learned how to throttle the network bandwidth both system-wide and per session and process using several tools like tc, wondershaper, and trickle.

2 Comments
Oldest
Newest
Inline Feedbacks
View all comments
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.