Cheat Sheet

netstat Commands

netstat is still the fastest way to find out what is holding a port on Windows, while Linux has replaced it with ss and often does not install it at all. This sheet covers the Windows commands, the ss equivalent of every common netstat flag, and the filters, states, and output columns that go with them.

Last updated September 11, 2026

What Is Using a Port

The most common reason either command gets run. Find the PID that owns the port, then name it.

PlatformCommandWhat it does
WindowsPID of whatever holds port 8080, last column
WindowsName the program behind PID 4312
WindowsExecutable name inline (elevated prompt, slower)
WindowsFree the port by killing its owner
LinuxListener on 8080 with process name and PID
LinuxSame answer without the filter syntax
LinuxJust the PIDs; add to kill them
macOSWhich process is on port 8080
macOSListener only, no name lookups

PowerShell does it in one step, no findstr and no second command:

Get-Process -Id (Get-NetTCPConnection -LocalPort 8080 -State Listen).OwningProcess

For open files, sockets, and deleted-file handles beyond ports, see the lsof cheat sheet.

Windows netstat

netstat is not deprecated on Windows. Run these in Command Prompt or PowerShell; is the Windows grep, and needs an elevated prompt.

CommandWhat it does
All connections and listeners, numeric, with PID
Filter to one port
Listeners only
Live connections only
Show the executable name inline (needs an admin prompt, slower)
TCP only (, also work)
Name the process behind PID 4312
Routing table
Interface byte and packet counters
Interface counters plus per-protocol statistics
Reprint every 5 seconds (Ctrl+C stops)
Kill the process holding a port

netstat to ss Mapping

netstat is deprecated on Linux; ss is the replacement and takes the same flag letters for the common cases. The last two rows moved to instead.

netstatss / ipWhat it shows
Listening TCP ports with the owning process
Listening UDP ports with the owning process
Both, one table
All sockets, listening and connected
Current TCP connections, numeric
Summary statistics by protocol
Routing table
Interfaces with packet and error counters

The letters mean: TCP, UDP, listening only, numeric (skip DNS, always worth it), process info (needs for other users' processes), all.

Listening Ports

CommandWhat it does
Every listening TCP port and who owns it
Is something on port 80
Same, filtered by ss itself
TCP and UDP listeners together
Listening sockets without process info (no sudo needed)
Which port is sshd actually on

If a port shows a listener bound to , it only accepts local connections; or means all interfaces. To test a port from the outside instead, use the SSH port checker.

Established Connections

CommandWhat it does
All current TCP connections
Only live connections
Live connections with the owning process
Outbound HTTPS connections
Connections to one host
How many sockets in TIME_WAIT

Recipes:

# Who is connected to my web server right now, by IP:
ss -tn state established '( sport = :443 or sport = :80 )'

# Count connections by state (spot SYN floods and CLOSE_WAIT leaks):
ss -tan | awk 'NR>1 {print $1}' | sort | uniq -c | sort -rn

# Count established connections per client IP:
ss -tn state established | awk 'NR>1 {split($5,a,":"); print a[1]}' | sort | uniq -c | sort -rn

Connection States

The State column is the TCP state machine. UDP rows have no state, which is why they look empty.

StateWhat it meansWhen it matters
Server socket waiting for clientsMissing means nothing is bound to that port
Handshake done, data can flowOne row per live connection
You asked to connect, nothing answeredFirewall dropping packets, or wrong host
Handshake half-finished on your sideThousands of these is a SYN flood
You closed it, kernel holds it ~60sNormal in bulk; only hurts clients out of ports
Peer closed, your app never didPiles up only because of a bug in your program
You closed, peer never finished closingUsually the peer crashed or was firewalled off
Waiting for the final ack before releaseTransient; stuck ones mean a dead peer
CommandWhat it does
Totals by state and protocol, one screen
Every leaked socket, with the local port
Count TIME_WAIT sockets on Windows
Connection attempts nothing is answering on Windows

ss Filters

ss filters sockets itself, no grep needed. Quote the expression, and put spaces around the parentheses and operators.

CommandWhat it does
Filter by state (, , , also work)
By destination port
By source (local) port
Either port
Connections to a subnet
Port comparisons work too
Kill matching connections (kernel support required)

Routing Table and Stats

The parts of netstat that ss does not cover, and their modern forms.

CommandWhat it does
Routing table (); the line is your gateway
Which route and interface a destination would use
Interfaces with RX/TX and error counters ()
Socket totals by state and protocol ( is more detailed)
Full per-protocol counters: retransmits, resets, ICMP (needs net-tools)

macOS netstat

macOS ships a BSD netstat with different flags, and no for processes ( selects a protocol instead). Use for the process view.

CommandWhat it does
Listening ports
TCP sockets ( for UDP)
Which process is on port 8080
Every listener with its process
Routing table

netstat Flags

Two combinations cover most of it: on Linux, on Windows. The same letter often means something different on each.

FlagLinux netstatWindows netstat
All sockets, listening and connectedSame
Numeric, skip DNS and service namesSame
/ TCP only / UDP onlyNot available; use or
Listening sockets onlyNot available; pipe to
Show PID and process nameSelects a protocol instead; gives the PID
Show connection timersShow the owning PID
Not availableShow the owning executable (elevated only)
Routing tableRouting table
Extended output: user and inodeEthernet statistics
Interface tableNot available; is the closest
Per-protocol statisticsSame
Repeat every secondUse a trailing number:

Reading the Output

Both tools print the same columns, in the same order, on every platform.

ColumnWhat it means
, , ; a row bound to usually serves IPv4 too
Bytes received that the program has not read; steady non-zero means it is falling behind
Bytes sent but not acknowledged; on a row it is the accept backlog
Your side. or is every interface, is local only
The other end. on a listening row just means nobody is connected
TCP state; blank for UDP, which has none
Owner, needs . Windows shows a bare PID unless you use

Install netstat

Only worth doing when a script insists on it; is already installed everywhere.

CommandDistro
Debian, Ubuntu (apt cheat sheet)
Fedora, RHEL, Rocky, Alma
RHEL 7 and older
Arch
openSUSE
Alpine, and most slim containers

If says it cannot locate the package, run first; the package list in a fresh container image is usually empty.

Gotchas

  • on a modern distro is expected: the default answer is , and brings netstat back if a script insists on it.
  • Without , the column is blank for processes owned by other users, including every system service. No error, just missing names.
  • Always add . Without it both tools resolve every address and port name, which is slow and turns into mid-scan.
  • ss filter expressions are picky about spacing: works, does not.
  • A service bound to will look fine in but be unreachable from outside. Check the Local Address column, not just the port.
  • On Windows, PID 4 is the kernel. parks ports there for IIS, WinRM, and WSL, so will not help; stop the service that registered the URL instead.
  • A Windows port that refuses binds while shows nothing is usually inside a reserved range. lists them, and Hyper-V grabs large blocks on every boot.
  • Neither tool can look at another machine. Run it over SSH, or scan from outside with nmap.
  • Connections you see in ss can still be invisible to clients if the firewall drops packets first. When listeners look right but connections fail, capture with tcpdump and check iptables.

netstat & ss FAQ

How do I find which process is using a port?

On Windows, netstat -ano | findstr :8080 puts the PID in the last column, then tasklist | findstr 4312 names the program. Run it from an elevated prompt, or netstat -anob refuses with "The requested operation requires elevation" and prints "Could not obtain ownership information" for processes you do not own. On Linux, sudo ss -tlnp 'sport = :8080' shows the listener and its PID, and without sudo the process column is simply blank, with no error. On macOS, netstat cannot show processes at all, so use sudo lsof -i :8080. If Windows reports PID 4, the kernel holds the port through http.sys or a driver, and the fix is stopping the service behind it rather than killing the PID.

Is netstat deprecated?

On Linux, yes. It ships in net-tools, which has had no real maintenance since 2011, and Debian, Ubuntu, RHEL, and Arch stopped installing it by default. The replacements are ss for sockets, ip route for the routing table, and ip -s link for interface counters. On Windows netstat is not deprecated, ships with every version, and netstat -ano is still the normal way to find what holds a port; Get-NetTCPConnection in PowerShell is an addition, not a replacement. macOS still ships the BSD netstat, which never had the Linux flags in the first place.

What does TIME_WAIT mean in netstat output?

The side that closed the connection first holds the socket for twice the maximum segment lifetime, roughly 60 seconds on both Linux and Windows, so stray packets from the old connection cannot land in a new one reusing the same ports. Hundreds or thousands of TIME_WAIT rows on a busy server are normal and clear by themselves. It only becomes a real problem when a client machine runs out of ephemeral ports, and the answer there is connection reuse or keepalive, not net.ipv4.tcp_tw_recycle, which Linux removed in 4.12. CLOSE_WAIT is the state worth alerting on: it means your own program never closed a socket the other end closed already.

Why is netstat so slow?

By default it resolves every address to a hostname and every port number to a service name, so a single DNS timeout stalls the whole listing. Add n (netstat -an, ss -tn) and it returns straight away. On Windows, -b is slow for a different reason: it walks the loaded modules of every process to name the executable, so netstat -ano plus tasklist is much quicker. ss beats netstat even with -n, because it asks the kernel over netlink instead of parsing /proc/net/tcp line by line, which shows on hosts with thousands of sockets.

Can I run netstat on a remote machine?

No. netstat and ss read the local kernel's socket tables and have no remote mode. To see another machine's sockets, run the command over SSH: ssh user@host 'ss -tlnp'. To find out what is reachable from outside instead, scan from your side with nmap or test a single port with the SSH port checker. That answers a different question, and usually the more useful one when the listener looks correct locally but clients still cannot connect.

Related cheat sheets