Linux Tune Network Stack (Buffers Size) To Increase Networking Performance

by Vivek Gite on May 20, 2009 · 20 comments

I've two servers located in two different data center. Both server deals with a lot of concurrent large file transfers. But network performance is very poor for large files and performance degradation take place with a large files. How do I tune TCP under Linux to solve this problem?

By default the Linux network stack is not configured for high speed large file transfer across WAN links. This is done to save memory resources. You can easily tune Linux network stack by increasing network buffers size for high-speed networks that connect server systems to handle more network packets.

The default maximum Linux TCP buffer sizes are way too small. TCP memory is calculated automatically based on system memory; you can find the actual values by typing the following commands:
$ cat /proc/sys/net/ipv4/tcp_mem
The default and maximum amount for the receive socket memory:
$ cat /proc/sys/net/core/rmem_default
$ cat /proc/sys/net/core/rmem_max

The default and maximum amount for the send socket memory:
$ cat /proc/sys/net/core/wmem_default
$ cat /proc/sys/net/core/wmem_max

The maximum amount of option memory buffers:
$ cat /proc/sys/net/core/optmem_max

Tune values

Set the max OS send buffer size (wmem) and receive buffer size (rmem) to 12 MB for queues on all protocols. In other words set the amount of memory that is allocated for each TCP socket when it is opened or created while transferring files:

WARNING! The default value of rmem_max and wmem_max is about 128 KB in most Linux distributions, which may be enough for a low-latency general purpose network environment or for apps such as DNS / Web server. However, if the latency is large, the default size might be too small. Please note that the following settings going to increase memory usage on your server.

# echo 'net.core.wmem_max=12582912' >> /etc/sysctl.conf
# echo 'net.core.rmem_max=12582912' >> /etc/sysctl.conf

You also need to set minimum size, initial size, and maximum size in bytes:
# echo 'net.ipv4.tcp_rmem= 10240 87380 12582912' >> /etc/sysctl.conf
# echo 'net.ipv4.tcp_wmem= 10240 87380 12582912' >> /etc/sysctl.conf

Turn on window scaling which can be an option to enlarge the transfer window:
# echo 'net.ipv4.tcp_window_scaling = 1' >> /etc/sysctl.conf
Enable timestamps as defined in RFC1323:
# echo 'net.ipv4.tcp_timestamps = 1' >> /etc/sysctl.conf
Enable select acknowledgments:
# echo 'net.ipv4.tcp_sack = 1' >> /etc/sysctl.conf
By default, TCP saves various connection metrics in the route cache when the connection closes, so that connections established in the near future can use these to set initial conditions. Usually, this increases overall performance, but may sometimes cause performance degradation. If set, TCP will not cache metrics on closing connections.
# echo 'net.ipv4.tcp_no_metrics_save = 1' >> /etc/sysctl.conf
Set maximum number of packets, queued on the INPUT side, when the interface receives packets faster than kernel can process them.
# echo 'net.core.netdev_max_backlog = 5000' >> /etc/sysctl.conf
Now reload the changes:
# sysctl -p
Use tcpdump to view changes for eth0:
# tcpdump -ni eth0

Recommend readings:

Featured Articles:

Share this with other sys admins!
Facebook it - Tweet it - Print it -

{ 20 comments… read them below or add one }

1 Shoaibi May 20, 2009

great… you always impress me by your level of knowledge and great explanation skills.

Reply

2 blink4blog May 20, 2009

it appears that these tuning is not suitable for average workstation users whom want to have a faster/solid network connection?

Reply

3 Vivek Gite May 20, 2009

For average user (Desktop / workstation) defaults are fine. These are for servers with lots of traffic generated while transferring large files.

@Shoaibi: no problem. I’m glade that information helped you to understand new things.

Reply

4 Samir May 20, 2009

Great article man. Quality stuff you got here… keep em coming.

Reply

5 blink4blog May 20, 2009

it will be great if there is another article to light boost network connectivity of workstation/notebook ubuntu.

Reply

6 Bash May 20, 2009

Hi

According to this page: http://www.psc.edu/networking/projects/tcptune/#Linux

“Kernels greater than 2.6.17 have full auto tuning and manual tuning is generally not recommended.”

If you are in a position to test the effects of auto vs manual tuning thoroughly, please do so.

Thanks

Reply

7 Michael May 21, 2009

Can you offer some specific information about this information:
1) What kernel were you using?
2) Do you have any numbers to show the changes in performance?
3) Are there any negative effects on your systems by doing this?
4) What are the hardware configs of the systems involved?

TNX

Reply

8 Vivek Gite May 21, 2009

OS RHEL 4.7 server – RHEL kernel 2.6.9.xx – 64bit system.

Hardware – Server Dual Core Xeon 53xx with 16GB RAM – RAID 10 with x 15kx 73GB server.

A clear performance decline is observed when using a low value of rmem_max and wmem_max limit used. This causes small window sizes and creates a performance ceiling for large data transfers. However, I lost my data file with trasfer per rate per sec by received size. However, you can easily test things your self try comparison with socket buffer 4 KB and 132 bytes.

I’ve same experience with RHEL 5 64 bit kernel 2.6.18 with 32GB RAM and SAN storage. You need to tweak the kernel.

HTH.

Reply

9 Pramod Walke May 23, 2009

good information, can have any trick to increase wine application’s performance.. i am using tally on wine, it works slow..

Reply

10 James Pearce June 18, 2009

Very nice article. I tweaked these parameters a little to obtain almost twice the real throughput in Samba over a high-latency VPN link.

Reply

11 Sam Hall July 8, 2009

I think this command is a typo:

# echo ‘sysctl net.ipv4.tcp_sack = 1′ >> /etc/sysctl.conf

…should not contain sysctl?

Reply

12 Vivek Gite July 8, 2009

@Sam,

Thanks for the heads-up!

Reply

13 Muhammad July 14, 2009

Great info. thanks.

How can I check how much Linux TCP buffer sizes are used on my system?

Reply

14 Bill Ward March 8, 2010

Interesting, but only close to what I’m looking for. I have a very large number of small connections (client connects via TCP, sends a message that has a maximum size of 64K, and disconnects). The client may reconnect to send an additional message, but EVERY message has it’s own connection. I need to handle >20K (and perhaps over 40K) connections per second over GigE; my server seems to be similar in some ways (32GB of RAM on a SAN, running vanilla Linux 5.2 x86-64, with 2 Quad Core Opterons).

Raising the various memory for individual buffers settings seems futile, since I’m sending large amounts of very small data and would be unlikely to see any performance for mostly unused memory; however,

# echo ‘net.core.netdev_max_backlog = 5000′ >> /etc/sysctl.conf

seems promising, although I think 5K may be low in my case. Any other tuning that might be helpful that you can recommend?

Reply

15 Darwin May 26, 2011

Quite interesting. However, many of the settings are already default on the new Linux kernel (using 2.6.32 on Ubuntu 10.04). I still can’t crack why my Linux workstation with GigE have a transfer rate of 35MBps while my new iMac (OSX) have 65MBps downloading same file from the same NAS using the same port & cable. Is there something I miss?

Reply

16 Vivek Gite May 26, 2011

Are you using CIFS, NFS, or anything else? What about jumbo frame and the
/proc/sys/net/ipv4/tcp_moderate_rcvbuf ? By default most modern Linux kernel comes with autotuning. Also, it depends upon your network card and driver.

Reply

17 eh June 15, 2011

I think wmem and rmem are generic for sockets and can be used by any protocol. For tcp it is tcp_wmem and tcp_rmem.

Reply

18 anony October 19, 2011

Very Very nice aritlce …Very much helpfull….

Reply

19 Rocky Patel November 15, 2011

Hi Vivek,

I have a small qeury.Please clear me.

As per your word:
“Tune values

Set the max OS send buffer size (wmem) and receive buffer size (rmem) to 12 MB for queues on all protocols. In other words set the amount of memory that is allocated for each TCP socket when it is opened or created while transferring files:”

suppose i set 12 MB for wmem and rmem so that time each tcp socket will take 12 MB ?

means suppose we have bussy server which having 1000 concurrent users so in that time each tcp connection taking 12 MB of ram ?

Please clear me that how to calculate it.

And for such tunning , do we need more ram ?

From where system set 12 mb for each tcp socket ? is from ram ?

Thanks,
Rocky

Reply

20 moa December 13, 2011

“suppose i set 12 MB for wmem and rmem so that time each tcp socket will take 12 MB ?

means suppose we have bussy server which having 1000 concurrent users so in that time each tcp connection taking 12 MB of ram ?”

same question. anybody?

Reply

Leave a Comment

You can use these HTML tags and attributes for your code and commands: <strong> <em> <ol> <li> <u> <ul> <blockquote> <pre> <a href="" title="">




Previous post:

Next post: