Tweak Linux for Broadband

Tux, as originally drawn by Larry Ewing

Image via Wikipedia

Okay, here’s the reason this page is here, I visit the Forums over on SpeedGuide frequently.   And occationally someone will ask “How do I tweak Linux for broadband?”.

So, I thought it might be helpful to write a small snippet (not an authoritative guide or HOW-TO) on how to tweak Linux for broadband, and what each setting does.   This document applies to kernel 2.4.x, and will also work on the 2.6.x kernel provided it is compiled with /proc file system support enabled (in the kernel configuration menu: File systems -> Pseudo filesystems -> /proc file system support).   Part of these tweaks can also be used on kernel 2.2.x, although it doesn’t support some features that the newer kernels do.   Let’s begin.

One of the values you will see mentioned quite often is the RWIN (Receive WINdow) value.   More often than not most folks who are into tweaking their TCP/IP setting will ask you what you have your RWIN set to, in order to see if you have it set optimally–at least in the “Windows World”.   However, in the “Linux World” this value is dynamic–Linux 2.4 kernels use a feature called auto-tuning which scales the window size during the life of a connection.   It basically works like this:

  1. You make a TCP connection to another computer, sending a packet with a small window (say 5280 bytes)
  2. The other computer responds with a packet that has a window size larger than the one you sent (say 8450 bytes)
  3. Your computer then scales the window size to a little more than the window size you just received (say 9460 bytes)
  4. The other computer responds with a packet that has a window size larger than the one you sent
  5. This continues throughout the connection until either your computer or the other computer reaches its maximum window size

What does this mean?   Well, you can pick an arbitrarily large window size (for the most part) and not have to worry too much about making it too big.   I use a window size of 512 KB (or 524288 bytes) myself, and I have no problems at all.   My brother, who runs Linux over a different broadband provider than I have, had some trouble with using 512 KB–so, instead he used 256 KB (or 262144 bytes) which worked better for him.   Typically, you will notice that your connection is actually slower than the default settings if your window size is too big.   That being said, you should try out different size window sizes and see what works best for you–but, in most cases either 512 KB, 256 KB, or 128 KB seem to do the trick quite nicely.

Now that the window size has been somewhat explained, there are two things that need to be pointed out.   First, most of the web-based bandwidth testers will not correctly assess your windows size.   They usually show the size of the window that they first received, and do not take into account auto-tuning–this is probably because they are written by Windows Users for Windows Users.   And, second, Linux only supports window sizes of up to 64 KB (or 65536 bytes) without enabling window scaling (See rfc1323 “TCP Extensions for High Performance” for additional info on this).

Continuing on, I would like to give you an idea of where these settings actually reside and what they mean.   The first set of four are located in /proc/sys/net/core.   They are:

  1. rmem_default – Receive Window default value
  2. rmem_max – Receive Window maximum value
  3. wmem_default – Send Window default value
  4. wmem_max – Send Window maximum value

The second set of eleven are located in /proc/sys/net/ipv4.   They are:

  1. tcp_wmem – Send Window vector–contains 3 integer values: <min> <default> <max>
  2. tcp_rmem – Receive Window vector–contains 3 integer values: <min> <default> <max>
  3. tcp_mem – TCP stack memory vector–contains 3 integer values: <low> <pressure> <high>
  4. tcp_rfc1337 – See rfc1337 “TIME-WAIT Assassination Hazards in TCP” for an explanation; 1 enables, 0 disables
  5. ip_no_pmtu_disc – Path Maximum Transfer Unit discovery–disable this and the MTU settings are derived from the MTUs of all the hops along the path to the host you are connecting to, including the host itself; 1 enables, 0 disables
  6. tcp_sack – See rfc2883 “An Extension to Selective Acknowledgement (SACK) Option for TCP” for an explanation; 1 enables, 0 disables
  7. tcp_fack – Forward Acknowledgement is a special algorithm that works on top of the SACK options, and is geared at congestion controlling; 1 enables, 0 disables
  8. tcp_window_scaling – window scaling, explained in the previous paragraph; 1 enables, 0 disables
  9. tcp_timestamps – controls timestamping packets as described in rfc1323, since we will be using window scaling we might as well use this too; 1 enables, 0 disables
  10. tcp_ecn – See rfc3168 “The Addition of Explicit Congestion Notification (ECN) to IP” and rfc2884 “Performance Evaluation of Explicit Congestion Notification (ECN) in IP” for an explanation; 1 enables, 0 disables
  11. route/flush – flushes the routing cache; 1 enables, 0 disables

Now we know what we are going to set, let’s go over how we are going to set the values.   There are a few ways to do this, you could echo the values into the “files” in a script that you add to your boot process, you could use the sysctl command to set the values in one shot (`sysctl -w net.ipv4.tcp_sack=1 net.ipv4.tcp_fack=1 …`) then create a script that you add to your boot process.   Or, you could take the easy route (which is always the preferred route in my book), and add the following to /etc/sysctl.conf (substituting your window size in place of 524288, if necessary):

# Tweaks for faster broadband…
net.core.rmem_default = 524288
net.core.rmem_max = 524288
net.core.wmem_default = 524288
net.core.wmem_max = 524288
net.ipv4.tcp_wmem = 4096 87380 524288
net.ipv4.tcp_rmem = 4096 87380 524288
net.ipv4.tcp_mem = 524288 524288 524288
net.ipv4.tcp_rfc1337 = 1
net.ipv4.ip_no_pmtu_disc = 0
net.ipv4.tcp_sack = 1
net.ipv4.tcp_fack = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_ecn = 0
net.ipv4.route.flush = 1

Then to have the settings take effect immediately, run:

sysctl -p

I should point out that there are many other options/settings that are available in /proc/sys/net, some of which are not there unless you compiled them into your kernel (all the ones I mentioned above “should” be in most distro’s stock kernel).   I only went over, and set, the ones that have a direct impact on broadband performance–and left out some other settings that can improve security, but at the cost of speed.   For more information on what’s available in ipsysctl read the Ipsysctl tutorial.

Finally, there is a GUI called Powertweak that you can use to set these settings–instead of editing /etc/sysctl.conf.   It’s fairly easy to use, and is a bit easier to understand.   So, if you are a “GUI” type of person, it might be a little less intimidating using this utility.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s