Alright, let’s get our hands dirty with the plumbing of your network. When things are slow, flaky, or just plain broken, you need to know what’s talking to what. Forget the fancy GUI tools that try to pretty this up; we’re going straight to the source. For decades, the go-to for this has been netstat. It’s the old guard, and it’ll get the job done. But on modern Linux systems, we have a faster, more informative successor: ss. Think of netstat as your reliable but slightly creaky old toolbox, and ss as the shiny new socket wrench set that does the same job but better and faster. I’ll show you both, because you’ll still see netstat everywhere, but you should default to ss.

Why ss Exists and Why You Should Use It

Here’s the deal: netstat gets its information by rummaging through the /proc filesystem (/proc/net/tcp, etc.). It’s a bit like getting the weather report by going outside and sticking your hand in the air—it works, but it’s not exactly efficient. The ss tool, part of the iproute2 package that’s replacing the old net-tools suite, gets its data directly from the kernel via a netlink socket. This is a direct line to the source, and the difference is staggering.

Try it yourself. Let’s list all connections and time how long it takes:

time netstat -an > /dev/null
time ss -an > /dev/null

On a system with thousands of connections, netstat might take a second or two. ss will finish in a blink. This speed is why, when you’re SSH’d into a struggling machine, ss is your best friend. You’re not waiting for a tool to catch up while you’re diagnosing a crisis.

The Absolute Essentials: Listing Connections

Both tools can show you the same core information, but the default outputs are slightly different. The most common flags you’ll use are -t for TCP, -u for UDP, -l for listening sockets, -a for all sockets, -n to avoid costly DNS lookups (always use this for troubleshooting), and -p to show the process that owns the socket (requires sudo).

To see all TCP and UDP connections and listening ports, without resolving hostnames:

netstat -tunap # The old classic
ss -tunap      # The new hotness

The ss output is more condensed and informative. For example, it clearly shows the state of the connection (ESTAB, LISTEN, TIME-WAIT, etc.) right next to the addresses, which is often the first thing you’re looking for.

The Gold Mine: Socket State Filters

This is where ss truly leaves netstat in the dust. ss lets you filter connections based on their state with a simple syntax. This is pure magic for narrowing down problems.

Want to see only established TCP connections?

ss -t state established

Troubleshooting a web server? See only connections listening on port 80 and 443:

ss -ltn 'sport = :80 or sport = :443'

Is your machine being used as a spam relay? Look for a ton of connections in the SYN-SENT state:

ss -t state syn-sent

The ability to filter on state, port, IP address, and more is an absolute game-changer. netstat can show you everything, but then you have to grep through it yourself. ss does the filtering for you, right in the kernel.

Decoding the Arcane: Understanding the Output

Let’s break down a typical line from ss -tpn:

ESTAB   0      0              192.168.1.42:53022       142.251.32.110:443     users:(("chrome",pid=1234,fd=123))
  • ESTAB: The state. Established. This connection is alive and talking.
  • 0: The amount of data in the kernel’s receive queue waiting for the application to read. If this number is huge and growing, the app is probably struggling.
  • 0: The amount of data in the send queue, waiting to be acknowledged by the remote host. A huge number here could indicate network congestion.
  • 192.168.1.42:53022: The local address and port. The OS chose this ephemeral port (53022) for this outgoing connection.
  • 142.251.32.110:443: The remote address and port. This is, of course, a Google server.
  • users:((“chrome”,pid=1234,fd=123)): The golden ticket. This tells you the process name (chrome), its PID (1234), and even the file descriptor (123) within that process that owns this socket. This is how you connect a mysterious network connection back to the culprit application.

Pitfalls and “GOTCHA!” Moments

  1. You Forgot -n: The biggest rookie mistake. Without -n, the tool will try to resolve every IP address to a hostname and every port number to a service name (e.g., 443 -> https). This triggers a DNS lookup for every single connection. On a busy machine, this will make the tool hang for minutes and potentially create a ton of DNS traffic, making the problem worse. Always use -n when troubleshooting.

  2. You Need sudo for Process Info: Running ss -p or netstat -p without sudo will show you process information only for your own user’s connections. To see everything (e.g., what Apache or Nginx is doing), you need to run it with sudo.

  3. The TIME-WAIT Parade: Don’t panic if you see a bunch of connections in TIME-WAIT state. This is perfectly normal. It’s part of the TCP protocol’s graceful connection termination. The socket is waiting for a period to ensure any stray packets from the old connection are expired. If you have a huge number of them, it usually points to an application making and breaking short-lived connections very rapidly, which is a separate performance anti-pattern.

So, while netstat is still useful and universally available, make ss your first instinct. It’s faster, more powerful, and gives you the deep, unfiltered truth about what your machine is saying to the world.