The ss command in Linux
ss (socket statistics) shows the sockets on your machine: which ports are listening, which connections are established, and — crucially — which process owns each. It answers "what is running on port 8080?" and "is anything actually listening?", the two questions behind most service-won't-connect incidents. It replaces netstat, whose flags it deliberately mirrors.
How ss works
ss queries sockets through the kernel's sock_diag netlink interface: the kernel serializes its own socket tables directly to the tool. netstat, its predecessor, parsed the text files under /proc/net/ — thousands of lines to format on a busy server. The direct channel is why ss remains instant with a hundred thousand connections while netstat visibly grinds.
Each line is a socket identified by its five-tuple (protocol, local address:port, peer address:port) plus a TCP state. The states tell operational stories: hundreds in TIME-WAIT are the normal afterglow of many short connections; a pile of SYN-RECV suggests a flood or a broken handshake path; CLOSE-WAIT accumulating means YOUR application is not closing sockets the peer already closed — a file-descriptor leak announcing itself.
Syntax
ss [OPTIONS] [FILTER] Common options
| Option | What it does |
|---|---|
-t / -u | TCP / UDP sockets. |
-l | Only listening sockets. |
-n | Numeric: no port-name or DNS resolution (fast, unambiguous). |
-p | Show the owning process (needs sudo for others' processes). |
-s | Summary statistics by protocol. |
state established | Filter by TCP state. |
How to use ss: examples
$ ss -tlnp THE incantation: all listening TCP ports with owning processes. Memorize it as a word: "tlnp".
$ sudo ss -tlnp | grep :443 What (if anything) is bound to port 443.
$ ss -tn state established Current established connections — who is talking to this machine right now.
$ ss -tn dst 10.0.0.7 All connections to a specific destination host.
Real-world use cases for ss
"Address already in use"
Your app won't start: sudo ss -tlnp | grep :8080 names the squatter and its PID in one line — an orphaned previous instance nine times out of ten. Kill it, restart, done.
Is it exposed or local-only?
Security review of a server: ss -tlnp, then read the address column. Databases on 0.0.0.0 that should be 127.0.0.1 are the most common accidental exposure there is, and this is the two-second check that catches them.
Pro tips and common mistakes
- Memorize ss -tlnp as one word; add -u when hunting UDP services.
- A growing pile of CLOSE-WAIT states is your application leaking sockets — the bug is in your code, not the network.
- ss state established dst :443 style filters beat piping to grep once connections number in the thousands.
Frequently asked questions about ss
How do I see what is using a port?
sudo ss -tlnp | grep :PORT shows the listener with its PID and name. (lsof -i :PORT is the older equivalent.)
ss or netstat?
ss — it reads kernel socket info directly, is faster, and is what modern distros ship. netstat -tlnp translates 1:1 to ss -tlnp.
What does 0.0.0.0 vs 127.0.0.1 mean in the listen address?
0.0.0.0 listens on every interface (reachable from the network); 127.0.0.1 only on loopback (local-only). Services accidentally bound to the wrong one cause both outages and security holes.
Things people do with ss
Find which process holds a port and stop it cleanly.
Find the process using a portIdentify the PID and program listening on a Linux TCP port.
Errors you may hit with ss
Something is already listening on the port your program wants.
Connection refusedYou reached the machine, but nothing was listening on that port — or a firewall said no.
Related commands
See what is running, find a process ID, and combine with grep to hunt down a program.
killTerminate processes politely or forcibly — and understand what -9 really does.
ipThe modern tool for addresses, links and routes — replacing ifconfig and route.