Operations 9 min read

How to Reach One Million TCP Connections on a Single Linux Server – Full Guide

This step‑by‑step tutorial shows how to configure Linux kernel limits, set up multiple client IPs, and run PHP‑based server and client scripts to achieve and monitor over one million concurrent TCP connections on a single machine.

ITPUB
ITPUB
ITPUB
How to Reach One Million TCP Connections on a Single Linux Server – Full Guide

1. Server preparation

Increase system-wide file descriptor limits and per-process limits to support >1 000 000 open sockets.

# vi /etc/sysctl.conf
fs.file-max=1100000
fs.nr_open=1100000

Apply with sysctl -p and verify with sysctl -a. Then raise user limits in /etc/security/limits.conf for all users:

# vi /etc/security/limits.conf
* soft nofile 1010000
* hard nofile 1010000
Hard nofile must be smaller than fs.nr_open , otherwise login may fail.

Confirm new limits with ulimit -n (should show 1010000).

Start the PHP server listening on all interfaces:

php server.php 0.0.0.0 8090

Verify with netstat -nlt | grep 8090.

2. Client preparation

Adjust the kernel's local port range because the default (~30 000 ports) is insufficient for 50 000 concurrent connections per client process.

# vi /etc/sysctl.conf
net.ipv4.ip_local_port_range = 5000 65000

Apply with sysctl -p. Increase file‑descriptor limits: system-wide to 1 100 000, per‑process to 60 000.

# vi /etc/sysctl.conf
fs.file-max=1100000
fs.nr_open=60000

Set per‑user limits to 55 000 (soft and hard) in /etc/security/limits.conf:

# vi /etc/security/limits.conf
* soft nofile 55000
* hard nofile 55000

Confirm with ulimit -n (should show 55000).

Configure multiple IP aliases on the same NIC (e.g., eth0:0eth0:19) so that up to 20 source IPs can be used simultaneously:

ifconfig eth0:1 CIP1 netmask 255.255.248.0 up

Update the $ips array in clientd.php with the chosen IPs and subnet mask. Verify that none of the IPs conflict with other machines using the provided ping helper:

php clientd.php ping

When all pings return false, bring the interfaces up:

php clientd.php ifup

Check the configuration with ifconfig (should list eth0, eth0:0eth0:19).

3. Running the connection test

Edit clientd.php to point to the server’s IP and port, then start the clients:

php clientd.php start

In another terminal, monitor the number of ESTABLISHED sockets in real time:

watch "ss -ant | grep ESTABLISHED"

When the count exceeds one million, the experiment succeeded. Stop the clients with:

php clientd.php stop

Terminate the server with Ctrl+C. If the port remains busy, wait briefly for the OS to release it before restarting.

Inspect memory usage, especially the slab allocator, to understand kernel overhead:

cat /proc/meminfo
# Example excerpt
MemTotal:        3922956 kB
MemFree:           96652 kB
Slab:           3241244 kB

Use slabtop to see which kernel objects consume the most memory.

slabtop output
slabtop output

4. Cleanup

Terminate the server ( Ctrl+C) and stop the client processes:

php clientd.php stop

Remove the temporary IP aliases:

php clientd.php ifdown

Source code for the experiment is available at:

https://github.com/yanfeizhang/coder-kung-fu/tree/main/tests/network/test01
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

performance tuningTCPhigh concurrencyPHPnetwork testingLinux sysctl
ITPUB
Written by

ITPUB

Official ITPUB account sharing technical insights, community news, and exciting events.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.