The Evolution of Network Monitoring in Linux
For decades, Linux system administrators relied on the venerable netstat command to view active network connections, listening ports, and routing tables. However, netstat suffers from severe performance limitations on modern, high-traffic servers. Because it gathers information by reading files sequentially from the /proc filesystem, running netstat on a server with tens of thousands of active connections can consume massive CPU resources and take several seconds to execute.
To solve this, the Linux networking community introduced the ss (socket statistics) command. Built directly into the iproute2 package, ss communicates directly with the kernel via the Netlink API. This makes it exponentially faster, highly efficient, and capable of displaying deeper TCP state information than netstat ever could.
Basic Socket Inspection
At its core, ss is used to list open sockets. To quickly see all listening TCP ports on a server—a standard security auditing task—you can use the -l (listening), -t (TCP), and -n (numeric, do not resolve DNS) flags.
ss -ltn
This instantly returns a clean table of local addresses and ports that are actively waiting for incoming connections. If you want to see which specific application process is bound to that port, add the -p flag (requires root privileges):
sudo ss -ltnp
Monitoring TCP Socket States
When diagnosing network bottlenecks, it is critical to understand the state of your TCP connections. Are connections hanging in TIME-WAIT? Are clients failing to complete the three-way handshake, resulting in SYN-RECV pileups?
You can instruct ss to filter output by specific TCP states. For example, to view all connections currently established:
ss -t state established
If you suspect a server is under a SYN flood attack (a type of DDoS), you can count how many sockets are stuck in the SYN-RECV state:
ss -t state syn-recv | wc -l
By filtering at the command level, ss prevents you from having to pipe massive amounts of text into grep, utilizing kernel-level filtering for maximum performance.
Diagnosing Application Bottlenecks: Send and Receive Queues
One of the most powerful features of ss is its ability to display the exact size of the socket queues. When you run a standard ss -tn command, the second and third columns in the output are Recv-Q and Send-Q.
These columns mean different things depending on the state of the socket:
For ESTABLISHED Connections:
- Recv-Q (Receive Queue): The amount of data (in bytes) that the kernel has received from the network but the local application has not yet read from the buffer. If this number is consistently high, your application (e.g., Nginx, Python backend) is frozen, overloaded, or reading data too slowly.
- Send-Q (Send Queue): The amount of data (in bytes) that the local application has handed to the kernel to send, but the remote client has not yet acknowledged receiving. If this number is high, the remote client is slow, or there is network congestion causing packet loss.
For LISTENING Sockets:
- Recv-Q: The current number of connections in the socket’s accept queue (connections that have completed the 3-way handshake but haven’t been picked up by the application).
- Send-Q: The maximum size of the accept queue (the backlog limit).
If the Recv-Q hits the limit defined in the Send-Q for a listening socket, the kernel will start dropping incoming connections. This is the definitive metric for proving that an application needs its somaxconn backlog increased.
Advanced Filtering by IP and Port
In complex environments, you often need to isolate traffic between specific nodes. ss includes a powerful built-in filtering syntax.
To view all TCP connections specifically communicating with the IP address 192.168.1.50:
ss -nt dst 192.168.1.50
To view all connections to a specific remote port (e.g., port 443 for HTTPS traffic):
ss -nt dport = :443
You can combine these for granular troubleshooting. For example, to find all established SSH connections coming from a specific subnet:
ss -nt state established src 10.0.0.0/8 dport = :22
Conclusion
The ss command is an indispensable tool for modern Linux network diagnostics. Its integration with the Netlink API provides unparalleled speed, while its advanced filtering and deep inspection of socket queues give system administrators the exact metrics needed to prove whether a network issue is caused by the infrastructure, the client, or an overloaded local application.