Adding simulated network latency to your Linux server
Have you ever said to yourself, “man I really need to slow down my internet”?
Probably not very often, but recently I found myself in a dilemma where I needed to simulate 120ms of network latency in my test environment which consists of servers that are racked right next to each other. That is where the command
tc comes in.
Within the current distributions of Linux there is a kernel component called netem, which adds Network Emulation and is used for testing and simulating the same types of issues one would see in a WAN (Wide Area Network).
tc Is a command that allows one to add rules to netem, specifically we will cover how to add network latency on a specific device with tc.
The tc command ships with the iproute package which is installed by default; we will not need to install any packages to use tc.
The tc command will add the amount of latency specified, in order to simulate the same rate of latency as my production environment I will need to take my desired latency and subtract my test targets latency to figure out the amount of latency I need netem to add.
"Production Target Latency" - "Test Target Latency" = "Latency to Add via netem"
In order to determine the latency of your test target you can perform a simple ping and use the ping's round-trip time to determine your networks latency. In this case google.com will be our test target.
# ping google.com PING google.com (126.96.36.199) 56(84) bytes of data. 64 bytes from lax04s08-in-f6.1e100.net (188.8.131.52): icmp_req=1 ttl=56 time=24.1 ms 64 bytes from lax04s08-in-f6.1e100.net (184.108.40.206): icmp_req=2 ttl=56 time=24.2 ms 64 bytes from lax04s08-in-f6.1e100.net (220.127.116.11): icmp_req=3 ttl=56 time=21.9 ms
My average latency to google.com is 23.6ms in order to get 120ms of latency I need to add 96.6ms, for ease of use I will round-up to 97.
# tc qdisc add dev eth0 root netem delay 97ms
To verify the command set the rule run
# tc -s qdisc qdisc netem 8002: dev eth0 root refcnt 2 limit 1000 delay 97.0ms
As you can see the 97ms delay rule has been added to netem, now we test with another ping.
# ping google.com PING google.com (18.104.22.168) 56(84) bytes of data. 64 bytes from lax04s09-in-f8.1e100.net (22.214.171.124): icmp_req=1 ttl=56 time=122 ms 64 bytes from lax04s09-in-f8.1e100.net (126.96.36.199): icmp_req=2 ttl=56 time=120 ms 64 bytes from lax04s09-in-f8.1e100.net (188.8.131.52): icmp_req=3 ttl=56 time=120 ms
Now my round-trip ping time is taking 120ms.
Note: Because you are adding this rule to a specific interface all traffic out of that interface will have the 97ms delay.
Remove the rule
After you have completed testing you can remove the delay with the tc command as well.
# tc qdisc del dev eth0 root netem # tc -s qdisc qdisc pfifo_fast 0: dev eth0 root refcnt 2 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
These settings will not survive a reboot, be sure to check your netem rules after any reboot.