ZetCode

Linux ss Command

last modified October 23, 2026

The ss (socket statistics) command in Linux displays network sockets: listening ports, established connections, and Unix domain sockets. It is part of the iproute2 package and replaces netstat. Since it reads the information directly from the kernel, it is fast even on servers with many thousands of connections.

ss answers questions such as which ports are open, which program listens on a port, and who is connected to a service. Showing process information for sockets of other users requires root privileges.

Test setup

To have something to look at, we start a few services in the background.

python3 -m http.server 8000 --bind 0.0.0.0 &
nc -lk 127.0.0.1 9000 &
nc -lu 5353 &
nc -lkU /tmp/app.sock &
sleep 300 | nc 127.0.0.1 9000 &

We have a web server on TCP port 8000, a TCP listener on port 9000 bound to the loopback address, a UDP listener on port 5353, and a listener on a Unix domain socket. The last command opens a TCP connection to port 9000 and keeps it open.

Listening TCP ports

The most common use of ss is listing listening TCP ports.

ss -tln

The -t option selects TCP sockets, -l shows listening sockets, and -n prints numeric addresses and ports instead of resolving service names. A local address of 0.0.0.0 means the port accepts connections on all IPv4 interfaces, while 127.0.0.1 accepts only local connections. For listening sockets, Recv-Q is the number of connections waiting to be accepted and Send-Q is the maximum backlog.

$ ss -tln
State  Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0      1          127.0.0.1:9000      0.0.0.0:*          
LISTEN 0      5            0.0.0.0:8000      0.0.0.0:*          

Showing processes

The -p option shows the process that owns each socket.

ss -tlnp

The users field contains the program name, its PID, and the file descriptor of the socket. Run sudo ss -tlnp to see processes of all users, such as system services.

$ ss -tlnp
State  Recv-Q Send-Q Local Address:Port Peer Address:PortProcess                    
LISTEN 0      1          127.0.0.1:9000      0.0.0.0:*    users:(("nc",pid=11,fd=3))
LISTEN 0      5            0.0.0.0:8000      0.0.0.0:*    users:(("python3",pid=10,fd=3))

UDP sockets

The -u option selects UDP sockets. Options can be combined to show several protocols.

ss -uln
ss -tuln

UDP is connectionless, so a bound UDP socket is in the UNCONN state rather than LISTEN. With both -t and -u, the Netid column shows the protocol. The ss -tuln command is a handy overview of all open ports.

$ ss -uln
State  Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
UNCONN 0      0            0.0.0.0:5353      0.0.0.0:*          
$ ss -tuln
Netid State  Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
udp   UNCONN 0      0            0.0.0.0:5353      0.0.0.0:*          
tcp   LISTEN 0      1          127.0.0.1:9000      0.0.0.0:*          
tcp   LISTEN 0      5            0.0.0.0:8000      0.0.0.0:*          

Connections

Without -l, ss shows established connections; the -a option shows sockets in all states.

ss -tn
ss -tan

Our client connection appears twice, because both ends are on the same machine: once from the client's ephemeral port to port 9000 and once from port 9000 back to the client. On a server, the peer address shows the remote clients.

$ ss -tn
State Recv-Q Send-Q Local Address:Port  Peer Address:Port Process
ESTAB 0      0          127.0.0.1:9000     127.0.0.1:58392       
ESTAB 0      0          127.0.0.1:58392    127.0.0.1:9000        
$ ss -tan
State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process
LISTEN 0      1          127.0.0.1:9000       0.0.0.0:*           
LISTEN 0      5            0.0.0.0:8000       0.0.0.0:*           
ESTAB  0      0          127.0.0.1:9000     127.0.0.1:58392       
ESTAB  0      0          127.0.0.1:58392    127.0.0.1:9000        

Filtering

ss has built-in filters for connection states, ports, and addresses.

ss -tn state established
ss -tln sport = :8000
ss -tn '( dport = :9000 or sport = :9000 )'

The state filter selects a TCP state such as established, listening, or time-wait; the State column is then omitted. sport and dport match the source and destination port, and dst and src match addresses, for example dst 192.168.1.0/24. Expressions can be combined with and, or, and not; the parentheses must be quoted for the shell.

$ ss -tn state established
Recv-Q Send-Q Local Address:Port  Peer Address:Port Process
0      0          127.0.0.1:9000     127.0.0.1:58392       
0      0          127.0.0.1:58392    127.0.0.1:9000        
$ ss -tln sport = :8000
State  Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0      5            0.0.0.0:8000      0.0.0.0:*          
$ ss -tn '( dport = :9000 or sport = :9000 )'
State Recv-Q Send-Q Local Address:Port  Peer Address:Port Process
ESTAB 0      0          127.0.0.1:9000     127.0.0.1:58392       
ESTAB 0      0          127.0.0.1:58392    127.0.0.1:9000        

Summary statistics

The -s option prints a summary of socket counts.

ss -s

The summary shows totals per protocol, including closed and TIME-WAIT TCP sockets. It is a quick way to spot an unusual number of connections on a busy server.

$ ss -s
Total: 10
TCP:   41 (estab 2, closed 37, orphaned 1, timewait 0)

Transport Total     IP        IPv6
RAW	  0         0         0        
UDP	  1         1         0        
TCP	  4         4         0        
INET	  5         5         0        
FRAG	  0         0         0        

Finding which program uses a port

When a service fails to start because its port is in use, we need to find the process that holds the port.

ss -tlnp | grep -w 8000
ss -Htlnp sport = :8000

The first command filters the output with grep; the second one uses the built-in port filter. The -H option suppresses the header line, which is useful in scripts. The PID can then be passed to ps or kill.

$ ss -tlnp | grep -w 8000
LISTEN 0      5            0.0.0.0:8000      0.0.0.0:*    users:(("python3",pid=10,fd=3))
$ ss -Htlnp sport = :8000
LISTEN 0      5      0.0.0.0:8000 0.0.0.0:* users:(("python3",pid=10,fd=3))

Unix domain sockets

The -x option shows Unix domain sockets, which processes on the same machine use to communicate, for example the Docker daemon or a local database.

ss -xlp

Instead of an address and port, the listing shows the socket path and an inode number. A plain ss without options lists all connected sockets, including many Unix sockets, so it is usually combined with -t, -u, or -x.

$ ss -xlp
Netid State  Recv-Q Send-Q Local Address:Port   Peer Address:PortProcess
u_str LISTEN 0      5      /tmp/app.sock 124142            * 0    users:(("nc",pid=13,fd=3))

ss versus netstat

The following table maps common netstat commands to ss.

netstatss
netstat -tlnss -tln
netstat -tulnpss -tulnp
netstat -tnss -tn
netstat -anss -an
netstat -sss -s (summary), nstat (counters)
netstat -rip route
netstat -iip -s link

Routes and interface statistics are covered by the ip command.

Best practices for ss

Source

ss(8) manual page

In this article, we have used the ss command to list listening ports and connections, show owning processes, filter sockets, and display summary statistics.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Linux tutorials.