DEV Community

Cover image for The ss Command Is More Powerful Than You Think: 10 Practical Examples
Asep Sayyad
Asep Sayyad

Posted on Edited on Originally published at asepsayyad007.in

The ss Command Is More Powerful Than You Think: 10 Practical Examples

Modern socket diagnostics, TCP queue inspection, and kernel-level network troubleshooting for Linux engineers

If you still type netstat -tulpn during a late-night production outage, you are leaning on an obsolete utility that was officially marked deprecated in 2001.

netstat crawls through /proc/net/tcp line by line. On a busy Kubernetes worker node, an API gateway, or a database replica handling thirty thousand active connections, parsing /proc/net/tcp line by line is slow and CPU-heavy. The command pauses, chews through memory, and can freeze your interactive shell while reading through tens of thousands of pseudo-file entries.

The modern standard is ss (Socket Statistics). Part of the iproute2 package, ss talks directly to the Linux kernel via Netlink sockets (NETLINK_INET_DIAG). Instead of string-parsing simulated procfs entries, the kernel dumps binary socket records straight into user space in batches. What takes netstat four or five seconds to crawl through on a congested edge proxy renders instantaneously with ss.

Beyond speed, ss gives you direct visibility into kernel socket buffers, TCP congestion windows, packet retransmissions, socket timers, and connection backlog drops that netstat could never expose.

Here are ten practical, real-world examples that show what ss can do during actual systems troubleshooting.


1. Fast Socket Triage with ss -tulpn

The foundational muscle memory command to inspect every active listening service on your host is:

sudo ss -tulpn
Enter fullscreen mode Exit fullscreen mode

Breaking down this flag combination:

  • -t filters for TCP sockets.
  • -u filters for UDP sockets.
  • -l displays listening sockets only (by default, ss lists established connections).
  • -p resolves and prints the owning process name, process ID (PID), and file descriptor numbers.
  • -n disables reverse DNS resolution and port name lookups (printing raw IP addresses and integer port numbers, avoiding terminal hangs caused by slow DNS servers).

The output provides an instant inventory of open ports and running daemons:

Netid  State   Recv-Q  Send-Q   Local Address:Port   Peer Address:Port  Process
tcp    LISTEN  0       128            0.0.0.0:22          0.0.0.0:*      users:(("sshd",pid=912,fd=3))
tcp    LISTEN  0       511          127.0.0.1:6379        0.0.0.0:*      users:(("redis-server",pid=1120,fd=6))
tcp    LISTEN  0       1024           0.0.0.0:80          0.0.0.0:*      users:(("nginx",pid=2045,fd=7))
Enter fullscreen mode Exit fullscreen mode

Notice the users:(("nginx",pid=2045,fd=7)) column. Seeing the exact PID and file descriptor lets you jump straight to process tracing with lsof -p 2045 or inspecting memory maps in /proc/2045/status.


2. Uncovering Backlog Bottlenecks with Recv-Q and Send-Q

Most engineers scan past the Recv-Q and Send-Q columns in ss output, assuming they are only useful for network engineers. During an incident where an application drops incoming traffic or responds with 502 Bad Gateway errors, these two columns pinpoint the problem immediately.

Crucially, their meaning changes depending on whether the socket is in a listening state or an established connection state.

For listening sockets (ss -ltn):

  • Send-Q represents the maximum listen backlog limit configured for that socket (the backlog parameter passed to the listen(fd, backlog) system call, capped by the kernel parameter net.core.somaxconn).
  • Recv-Q shows the number of completed TCP connections currently sitting in the kernel accept queue, waiting for the application process to invoke accept().
ss -ltn
Enter fullscreen mode Exit fullscreen mode

If you see:

State   Recv-Q  Send-Q   Local Address:Port   Peer Address:Port
LISTEN  512     511          127.0.0.1:8080        0.0.0.0:*
Enter fullscreen mode Exit fullscreen mode

Here, Recv-Q has surpassed Send-Q. The kernel accept queue for port 8080 is completely saturated. Incoming TCP handshakes are either being silently ignored or dropped, clients are timing out during initial connection establishment, and the application runtime (like Node.js, Python Gunicorn, or Java) is stuck in an event loop or CPU starvation lock and failing to process pending connections.

For established sockets (ss -tn):

  • Recv-Q is the number of bytes received by the network card and kernel TCP stack, but not yet read by the user-space application via read() or recv().
  • Send-Q is the number of bytes queued in the local socket write buffer waiting for acknowledgment (ACK) from the remote peer.

A steadily climbing Send-Q on an established connection signals a slow client, network packet loss, or a saturated egress pipe. A climbing Recv-Q signals that your local consumer application is falling behind and cannot drain its socket buffers fast enough.


3. Global Socket Summary Statistics with ss -s

When you first log in to an unstable or degraded Linux server, running detailed queries can overwhelm your terminal if thousands of sockets exist.

The -s (summary) flag reads high-level networking counters directly from kernel memory without iterating through individual sockets:

ss -s
Enter fullscreen mode Exit fullscreen mode

Sample output:

Total: 1842
TCP:   3420 (estab 215, closed 3110, orphaned 12, timewait 2980)

Transport Total     IP        IPv6
RAW   2         1         1        
UDP   14        9         5        
TCP   310       240       70       
INET      326       250       76       
FRAG      0         0         0        
Enter fullscreen mode Exit fullscreen mode

In three milliseconds, you get a clean breakdown of socket allocations.

If you see thousands of sockets stuck in timewait, your host is churning through short-lived connections (common on reverse proxies without HTTP keep-alive) and may be on the verge of local port exhaustion (net.ipv4.ip_local_port_range).

If the orphaned counter is elevated, connections have been closed by user space but the kernel is still holding the buffers to flush outbound packets or wait for FIN-ACK sequences. High orphan counts can trigger kernel memory pressure and invoke TCP socket drop routines.


4. Querying Sockets by State Names

With netstat, filtering for connection states required piping output through grep ESTABLISHED or grep TIME_WAIT. This approach is fragile because it can accidentally match IP addresses, hostnames, or process paths containing those words.

ss provides native state filtering built into its parser using the state keyword:

# List all sockets in the TIME-WAIT state
ss -tan state time-wait

# List all sockets actively establishing connections
ss -tan state syn-sent

# List all sockets waiting for a remote teardown
ss -tan state close-wait
Enter fullscreen mode Exit fullscreen mode

CLOSE_WAIT deserves special attention. A socket in CLOSE_WAIT means the remote peer sent a FIN packet and closed their side of the connection, the Linux kernel acknowledged it, but the local application process never called close() on the associated file descriptor.

Seeing hundreds of CLOSE_WAIT sockets indicates an application-level resource leak:

ss -tanp state close-wait
Enter fullscreen mode Exit fullscreen mode

The output reveals the exact process ID holding those dead descriptors open, giving you the information needed to patch the code or restart the leaky service.


5. Filtering Sockets by Source and Destination Ports

Piping command output into grep :80 or grep :443 frequently matches unrelated data such as ephemeral client ports, process identifiers, or random substrings.

ss supports native port and IP filter expressions. You pass the filter string at the end of the command:

# Find all established connections to or from port 443
ss -tan '( sport = :443 or dport = :443 )'

# Find all outgoing outbound connections to an external database port
ss -tan dport = :5432
Enter fullscreen mode Exit fullscreen mode

Note that sport stands for source port, and dport stands for destination port. When using spaces inside the filter syntax, always wrap the expression in quotes so your shell does not misinterpret parentheses or comparison operators.

You can also use numeric comparisons to isolate specific port ranges:

# Find connections where the remote port is a non-privileged high port
ss -tan 'dport >= :1024'
Enter fullscreen mode Exit fullscreen mode

6. Filtering by CIDR Subnets and Specific IP Addresses

When troubleshooting noisy network peers, security sweeps, or cluster communication problems, isolating traffic from a specific subnet is essential.

ss accepts standard CIDR notation for source and destination addresses:

# Find all connections originating from the internal VPC subnet
ss -tan src 10.0.0.0/16

# Find connections directed to an external storage cluster subnet
ss -tan dst 192.168.1.0/24

# Combine IP and port conditions
ss -tan 'src 10.0.0.0/16 and dport = :3306'
Enter fullscreen mode Exit fullscreen mode

This syntax filters at the kernel diagnostic level. The command bypasses user-space string regexes entirely, rendering matching sockets instantly even on nodes carrying tens of thousands of active network streams.


7. Deep TCP Telemetry and Retransmissions with ss -ti

When debugging intermittent latency, packet loss, or throughput collapse across distributed microservices, application logs only tell you that a request timed out. They do not tell you why the TCP layer struggled.

The -i (internal) flag instructs ss to extract the internal TCP control metrics tracked by the Linux kernel for that specific socket:

ss -ti 'dport = :443'
Enter fullscreen mode Exit fullscreen mode

Sample output:

ESTAB      0      0       192.168.1.50:54321    93.184.216.34:443
     cubic wscale:7,7 rto:204 rtt:4.12/0.05 ato:40 mss:1460 rcvspace:14600
     ssthresh:10 cwnd:10 unacked:1 retrans:0/2 lost:0 reordering:3
Enter fullscreen mode Exit fullscreen mode

This metric dump reveals vital networking indicators:

  • rtt:4.12/0.05: The smoothed round-trip time is 4.12 milliseconds with a tiny variance of 0.05ms.
  • rto:204: The retransmission timeout is 204ms. If an acknowledgment is not received within this window, the kernel retransmits the segment.
  • cwnd:10: The congestion window size in packets. A tiny cwnd on a high-bandwidth link indicates that the kernel recently cut its window due to packet drops.
  • retrans:0/2: Shows current active retransmissions alongside total retransmissions over the lifetime of the socket.
  • cubic: The active TCP congestion control algorithm handling the flow.

Seeing a high retrans count or a depressed cwnd for a specific peer confirms that throughput issues stem from physical link congestion or dropped packets, rather than slow application code.


8. Sizing Socket Memory Buffers with ss -tm

Every active TCP socket consumes kernel memory to buffer unacknowledged outbound packets and unread incoming data. If thousands of connections open simultaneously, socket memory consumption can starve the system, causing the kernel to trigger out-of-memory drops.

The -m flag displays memory allocations per socket:

ss -tm 'sport = :80'
Enter fullscreen mode Exit fullscreen mode

Sample output:

ESTAB      0      0       10.0.0.4:80          10.0.0.85:49152
     skmem:(r0,rb131072,t0,tb16384,f0,s0,uca0,d0)
Enter fullscreen mode Exit fullscreen mode

The skmem string details exact byte allocations:

  • r0: Receive buffer memory currently used by data chunks.
  • rb131072: Maximum allocated receive buffer limit (128 KB in this example).
  • t0: Transmit buffer memory currently used.
  • tb16384: Maximum allocated transmit buffer limit (16 KB).
  • f0: Free socket buffer memory forward-allocated.

If you suspect an edge server is running out of network buffer memory, checking ss -tm alongside the kernel sysctl limits (net.ipv4.tcp_rmem and net.ipv4.tcp_wmem) tells you whether individual connections are blowing past their expected buffer allocations.


9. Inspecting UNIX Domain Sockets with ss -xlp

Microservices, reverse proxies, and local daemons often bypass network stacks entirely, communicating over high-speed local UNIX domain sockets (such as Docker daemon sockets, Nginx upstream sockets, and systemd IPC endpoints).

Standard network monitoring commands miss these IPC sockets. With ss, you query them using the -x flag:

sudo ss -xlp
Enter fullscreen mode Exit fullscreen mode

Breaking down the flags:

  • -x selects UNIX domain sockets.
  • -l lists listening sockets.
  • -p identifies the owning daemon process and file descriptor.

Sample output:

Netid  State   Recv-Q  Send-Q   Local Address:Port             Peer Address:Port  Process
u_str  LISTEN  0       128      /var/run/docker.sock 18234            * 0          users:(("dockerd",pid=1420,fd=5))
u_str  LISTEN  0       511      /var/run/php/php-fpm.sock 23412       * 0          users:(("php-fpm7.4",pid=1890,fd=7))
Enter fullscreen mode Exit fullscreen mode

During periods of high traffic between a local Nginx instance and a PHP-FPM or Puma backend, checking Recv-Q on the UNIX domain socket reveals whether the backend worker pool is overwhelmed. If Recv-Q approaches Send-Q on /var/run/php/php-fpm.sock, the local socket queue is backing up, causing Nginx to drop connections with 504 Gateway Timeout errors.


10. Combining State and Port Filters for Targeted Incident Response

During a high-concurrency production incident, you need to isolate specific operational patterns without scrolling through thousands of lines of terminal noise.

You can combine boolean logic, state queries, and port filters into a single precision command:

# Find all established connections on port 80 or 443 where the send buffer is backing up
ss -tan '( sport = :80 or sport = :443 )' state established 'Send-Q > 0'

# Identify all connections from an external database cluster stuck in FIN-WAIT states
ss -tan dst 10.100.5.0/24 state fin-wait-1

# Track connection attempts that have not yet completed handshakes
ss -tan state syn-recv
Enter fullscreen mode Exit fullscreen mode

Running queries like Send-Q > 0 directly isolates connections with blocked egress buffers. Instead of writing custom parsing scripts or dumping network captures, you spot clogged streams with one command.


Quick Reference: Essential ss Commands

Listen sockets with process details:
Run sudo ss -tulpn. It displays active TCP and UDP listening ports alongside their owning process names, PIDs, and listen backlog sizes.

High-level socket counters:
Run ss -s. It returns instant summary statistics for established, closed, orphaned, and time-wait sockets directly from the kernel.

Inspect queue backlogs:
Run ss -ltn. For listening ports, Recv-Q shows connections waiting for user space accept(), while Send-Q shows the maximum backlog limit.

Find dead connections:
Run ss -tanp state close-wait. It isolates sockets where the remote peer closed the connection but the local application process leaked the descriptor.

Track packet loss and latency:
Run ss -ti 'dport = :443'. It exposes round-trip time (rtt), congestion windows (cwnd), and retransmission counts (retrans) for active connections.

Inspect local IPC sockets:
Run sudo ss -xlp. It checks UNIX domain socket health for services like Docker, Redis, and PHP-FPM communicating over local filesystem paths.


An Interesting Fact About ss and Netlink

The original netstat command read socket information by opening and reading /proc/net/tcp and /proc/net/udp. In Linux, the kernel generates the text for /proc/net/tcp on the fly every time a process reads the file. For a machine with 50,000 active sockets, the kernel has to allocate memory, format 50,000 lines of ASCII text, and pass it through a file descriptor.

The ss utility was developed specifically to solve this scalability bottleneck. Alexey Kuznetsov, the primary author of the modern Linux network stack and iproute2, designed the sock_diag subsystem inside the Linux kernel.

Instead of generating human-readable text in /proc, ss sends a Netlink message (NETLINK_INET_DIAG) asking the kernel for binary socket state structs. The kernel streams the raw binary records directly across the Netlink socket without text formatting overhead, making ss orders of magnitude faster on production servers.


Practical Takeaways for Your Daily Workflow

Continuing to rely on netstat means accepting slower diagnostics and missing out on kernel-level TCP telemetry.

To help transition your workflow, add these aliases to your shell configuration (~/.bashrc or ~/.zshrc):

# Fast socket triage
alias ports="sudo ss -tulpn"

# Instant socket summary
alias sockstat="ss -s"

# Check for saturated accept queues
alias backlogs="ss -ltn 'Recv-Q > 0'"
Enter fullscreen mode Exit fullscreen mode

Mastering ss turns socket inspection from a blunt port check into a precision diagnostic tool. You can spot saturated accept queues, trace packet loss to physical link drops, and isolate leaky file descriptors before an outage impacts your end users.


Which ss flags or custom aliases do you find most helpful when diagnosing network problems in production?

If this breakdown saved you hours of debugging or gave you something practical to use in production, consider buying me a coffee. Your support directly fuels independent, zero-fluff Linux and DevOps technical guides.


About the Author

Asep Sayyad is a Linux and DevOps engineer passionate about Linux administration, automation, cloud technologies, containers, and open-source software. He enjoys solving real-world infrastructure challenges and sharing practical knowledge through in-depth technical articles, tutorials, and hands-on guides.

His goal is to help aspiring and experienced engineers build stronger Linux and DevOps skills with content focused on real production scenarios rather than theory alone.

Connect with Me

Enjoyed this article?

If this guide saved you hours of debugging or gave you something practical for production, consider:

  • Buying me a coffee: Your support directly fuels independent, zero-fluff Linux and DevOps engineering breakdowns.
  • Starring my open-source projects on GitHub.
  • Sharing this article with fellow Linux and DevOps engineers.

You can also follow me for more practical content on Linux, DevOps, Cloud, Containers, Automation, and Open Source. Thanks for reading, and enjoy your learning!

© 2026 Asep Sayyad

Top comments (0)