How to simulate a slow network (after all, QT_FLUSH_PAINT=1 doesn't work with Qt3)

I think it is time to reveal a nifty little tool that I like to simulate a slow network connection, even without a network. It is called "tc" (think "traffic control") and is present on every modern Linux system. It is part of the "iproute" or "iproute2" package.

tc lets you simulate (amongst other things) latency. We all know how network latency of even the slightest degree kills off every amount of remote X11 usability. Even if you throw multi-Megabits of bandwidth towards it, that will never compensate -- because it is just the wrong cure for an illness that consists of many thousand roundtrips undertaken by minuscule packets.

Aaron hinted at the cool Qt4 builtin feature that allows for easy diagnosing of superfluous repaint operations of certain widgets (which also induce shitloads of roundtrips on the wire if an app displays its GUI across a network link). But what about Qt3 and KDE 3.x applications? Obviously setting "QT_FLUSH_PAINT=1" will be useless here. Adriaan proposed to test an application remotely over a not-too-fast DSL line; "ssh -X" should run it securely, and even add a tad bit more of latency to the link.

That's fine; but it is not good enough. (Well, maybe for Adriaan, since he does not seem to use Linux too much -- he's more a FreeBSD type of guy. But for the *BSDs there is "trickle" to achieve similar things as "tc" can do for our purpose.) After all, you're not always on a "not-too-fast DSL line"; plus, you probably want to have full control over the network parameters. You want to emulate slowness even if you are on a *fast* DSL line. You want to see how an app behaves over a network even if all that you have is lo on localhost...

So, back to tc. We use tc quite regularly to test FreeNX and NoMachine NX with it. The beauty of tc is that it does work even *without* a network connection. Because you can apply traffic control parameters even to the loopback interface. Travel Bundesbahn, fly Lufthansa, hitchhike on the backseat of a Porsche, enjoy a hacking session in the Norwegian woods... and always be able to simulate a network connection for your application to run across; no need for having an ethernet cable plugged in, or a Wifi card switched on.

Be very cautious if you run SUSE, though! I found a bug in SUSE kernels which make the system to freeze completely if you enable such a traffic control queueing discipline; as soon as you then actually start having traffic, you better had saved your open documents. I filed a bug back in September, but it is not yet fixed. The bug number is 116309 in Novell's bugzilla. It affects at least SUSE-9.1, 9.2, 9.3 and 10.0 default kernels for i386 architectures.

This bug did so far not happen on Debian/Knoppix/Kanotix systems where I tested various tc commandline.

OK, here is what I remember (I don't have my notes here -- I'm using a company WinXP notebook with NX Client currently to read mail remotely and browse the 'Net right now, all from a cold, loud Hotel room. Actually I'm accessing mail via KMail in an NX session running on a SUSE system; so no way in hell will I now test the command for you to verify...). The base command (for root) is like:

  {/usr}/sbin/tc qdisc add dev lo root handle 1:0 netem delay 20msec

(I *hope* I remember correctly; otherwise, the syntax should be at least close to the above line). You need to be root to execute the tc command. SUSE places it in /usr/sbin/, Debian in /sbin/.

This command adds a queueing disciplin ("qdisc") to the loopback device ("dev lo") that enforces a network emulation ("netem") with a (fixed) delay of 20 milliseconds for each package.

Now to test the result. You can see the practical effect of the currently active queueing discipline on the loopback interface simply by using ping:

  ping localhost

Note, that ping roundtrip times should now be around 40 milliseconds; because the given delay of 20 msec is applied to both directions. To display the currently active queuing disciplin on all devices use simply:

  tc qdisc

To remove an active queueing discipline for "dev lo", use "del":

  tc qdisc del dev lo root

You can change "lo" for "eth1", "wlan2", "lan0" or whatever device name may be appropriate. (I myself tested mostly with "lo" and it worked very well):

  tc qdisc add dev eth0 root handle 1:0 netem delay 55msec

Also, you can add more parameters:

  tc qdisc add dev lo root handle 1:0 netem delay 60msec 12msec 25%

This will add a 25% probability that the avarage 60msec delay will have a deviation of +12/-12msec. Finally, to modify an active queuing disciplin, use "change" instead of "add" or "del":

  tc qdisc change dev lo root handle 1:0 netem delay 110msec 5msec 50%

On SUSE, the "tc" command comes as part of the "iproute2" package. On Debian it's "iproute".

And tc can do even more sophisticated traffic shaping. You can insert a probability for packet losses, enforce packet duplications, simulate packet corruption, create packet re-ordering and what-not. (But I personally never played with *these* much).

You can probably find more info by googling for "netem" and "Stephen Hemminger". Hemminger is the author of the tool.

Stephen is an OSDL employee, and also maintains the "linux-net" Wiki with articles about tc and netem. This is where I originally found the utility. Before that, I played with "trickle" which is not as powerful overall as tc (but can be used without root privileges).

If I had a wish free with the KDE4 programming guideline drafting gods, I'd ask for this test to be passed as a mandatory one to each application:

  • $APP runs just fine remotely even over a slow line and is fully usable without too much annoyance. Tested with "tc qdisc" delays of 40-80 msecs. --> Check!

Cheers. Kurt


I was able to reproduce the system freeze on both of my Debian testing machines. It therefore also affects Debian testing default kernel.


By eckhart wörner at Fri, 03/24/2006 - 13:40


So you have filed a bug report with the Debian kernel packagers?

By Kurt Pf. at Fri, 03/24/2006 - 21:09

I did so, yes.


By eckhart wörner at Sat, 03/25/2006 - 16:10

>20 milliseconds for each package.

Get your network terms right - packets (=datagrams) not packages (=agglomeration, such as files in an RPM).

By bugmenot at Thu, 10/01/2009 - 13:00