Problem description
During network performance tests or high-concurrency operations, you may experience poor network performance, such as limited throughput or increased latency.
The output of the netstat -s command shows the following message:
$ netstat -s | grep "socket buffer overrun"
1617 packets pruned from receive queue because of socket buffer overrunCauses
Direct cause
When network packets arrive faster than the application can read data from the socket receive buffer, the receive queue gradually fills up.
Kernel behavior
When the current length of the receive queue plus the size of an incoming packet exceeds the maximum queue length:
Memory pruning or collapsing: The Linux kernel tries to prune the receive queue to make space for new packets. For example, it might merge small packets or release the metadata structures of out-of-order packets.
Performance impact: Pruning consumes CPU resources. If there is still no space after pruning, the packet is dropped. This causes TCP retransmissions, which increases network latency and reduces throughput.
Root cause
The socket receive buffer configuration, set by either kernel parameters or application settings, cannot handle the burst or throughput demands of the service traffic.
Solutions
Scenario 1: The application uses the default system buffer
If the application does not explicitly call `setsockopt(SO_RCVBUF)` to set the buffer size, the Linux kernel automatically adjusts the TCP receive window size based on the `tcp_rmem` parameter. This is called auto-tuning.
To adjust the buffer:
Modify the three values in `/proc/sys/net/ipv4/tcp_rmem`. The values are in bytes and represent the minimum, default, and maximum sizes.
Check the current values.
sysctl net.ipv4.tcp_rmem # Example output: 4096 87380 4194304 (4 KB, 87 KB, and 4 MB respectively)Increase the maximum value (the third number). This allows the kernel to allocate a larger receive buffer when enough memory is available.
# Example: Increase the maximum value to 16 MB. Set the value based on your server memory and service requirements. sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"Make the configuration persistent by writing it to `/etc/sysctl.conf`.
echo "net.ipv4.tcp_rmem = 4096 87380 16777216" >> /etc/sysctl.conf sysctl -p
Scenario 2: The application manually sets the buffer with setsockopt
If the application code calls `setsockopt(socket, SOL_SOCKET, SO_RCVBUF, ...)`, the kernel's auto-tuning mechanism is disabled. The buffer size becomes fixed.
Method 1 (Recommended): Modify the application code
Remove the `setsockopt(SO_RCVBUF)` call from the code. This allows the kernel to manage the buffer and use its efficient auto-tuning mechanism.Method 2: Increase the application's value and the kernel limit
If the application must set the buffer size manually, increase the value in the code. The maximum value that an application can set with `setsockopt` is limited by the `net.core.rmem_max` kernel parameter. For example, if an application requests 1 MB but `rmem_max` is only 256 KB, the kernel allocates only 256 KB. You must also increase the kernel limit:# Check the current limit sysctl net.core.rmem_max # Increase the limit (for example, to 16 MB) sysctl -w net.core.rmem_max=16777216
Verify the fix
After adjusting the configuration and restarting the application or its connections, run another performance test and monitor the following metrics:
Check if the counter stops increasing:
watch -d "netstat -s | grep 'socket buffer overrun'"If the value stops increasing or its rate of increase drops significantly, the adjustment was effective.
Monitor service performance:
Confirm that network throughput has increased and latency is stable.
Usage Notes
Estimate memory consumption: The TCP receive buffer uses physical memory, not swap space. If you have a very high number of concurrent connections, such as tens of thousands, setting the buffer limit too high can exhaust system memory. This can trigger the out-of-memory (OOM) Killer to terminate the service process.
Estimated memory consumption: Number of connections × Average buffer size.
Application read overhead: A larger buffer can reduce packet loss. However, if the buffer is much larger than the amount of data the application can read at one time, it can waste memory. It can also affect the cache hit ratio, although this impact is usually minor compared to packet loss.
Scope of effect
`net.ipv4.tcp_rmem` affects only TCP sockets.
`net.core.rmem_default` and `net.core.rmem_max` affect all types of sockets, including UDP and Unix Domain Sockets.