Gentoo Wiki


This article is part of the HOWTO series.
Installation Kernel & Hardware Networks Portage Software System X Server Gaming Non-x86 Emulators Misc

Apache2 Series



Addons & Tunnels





Please improve it in any way that you see fit, and remove this notice {{Cleanup}} from the article. For tips on cleaning and formatting see Cleanup process


This is a work-in-progress how to on limiting bandwidth for an Apache 2 webserver. For Apache version 1.3 I recommend using mod_throttle or mod_bandwidth.

Meanwhile there is for details.

What are we going to do? We will limit the outgoing total traffic from our Apache 2 webserver to the rest of the world.

So, if you have an internet connection with a low upload speed (e.g. 256 or 192 kbit/s) you will be able to cap your webserver-upload-speed to anything you want so that you can still comfortably browse the web or do other things on-line.

What are the steps to get it working?

Because we use a built-in kernel packet scheduler called 'htb' we have several advantages over a per-connection based limiter. The biggest advantage is that clients will always have an equal share of limited bandwidth: if there's one client, it gets the full-limited bandwidth. In the case of two clients, they both get half of the full-limited bandwidth.

Get ready because here we go, please buckle your seatbelts! Oh, and don't forget to su as you'll need root privileges for the largest part of this guide.

Kernel configuration

We are going to start the menu setup of your kernel:

cd /usr/src/linux
make menuconfig

Make sure that the following options is enabled:

Linux Kernel Configuration: Packet Scheduling
Code maturity level options  --->
   [*] Prompt for development and/or incomplete code/drivers
Networking Support --->
     Networking Options --->
       [*]     QoS and/or fair queueing
       [*]     HTB packet scheduler
       [*]     QoS support  --->
                  [*]       Rate estimator
       [*]     Packet classifier API
                 [*]     TC index classifier
                 [*]     Routing table based classifier
                 [*]     Firewall based classifier
                 [*]     U32 classifier
       [*]     Traffic policing

Now Compile and install the kernel.

The kernel is ready. Reboot with the new -htb kernel.

Emerging packages

There's not a lot we're going to need, just iproute2, so type:

emerge -av iproute2

Check that the package is fully working by issueing the 'tc' command as root:

Code: tc
Usage: tc [ OPTIONS ] OBJECT { COMMAND | help }
where  OBJECT := { qdisc | class | filter }
       OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] | -b[atch] file }

This is good as it means 'tc' is working. Now let's head over to our script creation!

Designing and implementing our script

FIXME: explain what is happening here

For now, just assume I'm right. We're going to build a htb tree with only two leaves and one parent node. One leaf is going to be the traffic limiting node, the other is the rest of the unshaped traffic. You must now decide what upload speed you want Apache to have in kilobytes per second. The tree we will build looks like this:

     X kbps
      /  \
     /    \
    /      \
   /        \
Y kbps    X-Y kbps

Now you must think up the following data:

kBps is kilobytes per second kbps is kilobits per second 1 kBps = 8 kbps

Let's call the ethernet device ETHERNET_DEVICE, the linkspeed LINK_SPEED and the Apache upload speed UPLOAD_SPEED. We will have to create the following script using our favourite editor (as long as it's vi(m)):

File: /etc/
# change these values to suit your needs

# delete previous root node
tc qdisc del dev $ETHERNET_DEVICE root

# create root node
tc qdisc add dev $ETHERNET_DEVICE root handle 1: htb default 11

# create LINK class
tc class add dev $ETHERNET_DEVICE parent 1: classid 1:1 htb rate $LINK_SPEED

# create our HTTP shaping class
tc class add dev $ETHERNET_DEVICE parent 1:1 classid 1:10 htb rate $UPLOAD_SPEED

# create our REST class for unutilized bandwidth
tc class add dev $ETHERNET_DEVICE parent 1:1 classid 1:11 htb rate $LINK_SPEED

# create the filter for the HTTP class, we filter on source port 80 (http)
tc filter add dev $ETHERNET_DEVICE protocol ip parent 1:0 prio 1 u32 match ip sport $PORT 0xffff flowid 1:10

Save this script somewhere you can remember, for instance /etc/

Making the script startup at boot

We must now create a script to stop our traffic shaping activities, so create a file with your editor containing:

File: /etc/

tc qdisc del dev $EDEV root

We must make sure we can execute our scripts later on, so chmod them:

chmod +x /etc/
chmod +x /etc/

We will now create a script that is going to be placed in /etc/init.d, so fire up your editor again and create this:

File: /etc/init.d/htb

depend() {
        use logger
        need net

start() {
        ebegin "Starting htb"
        eend $?

stop() {
        ebegin "Stopping htb"
        eend $?

Save the script as /etc/init.d/htb. And chmod it as well:

chmod +x /etc/init.d/htb

We want to run this script at boot time, so we will add it to the default runlevel using:

rc-update add htb default

Everything is now in place. To start our script without rebooting type:

/etc/init.d/htb start

That should do it!

Famous last words

Help with the FIXME's is appreciated. This page has been edited and formatted for use in the Gentoo Wiki and is derived from this Gentoo forums post: . Feel free to add comments and changes to my guide. I wish you luck!


Retrieved from ""

Last modified: Sun, 24 Aug 2008 10:18:00 +0000 Hits: 44,672