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.
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.