lsof -nP -iTCP:3000 -sTCP:LISTENShow the process listening on TCP port 3000.
When to use it
Use lsof when a port is “already in use”, when you want to see what an app is connected to, or when a disk won't eject because a file is open. Without sudo it shows your own processes; with sudo it shows everyone's, including root daemons.
Steps
Find what listens on a port
-n and -P skip name and port lookups, which makes lsof much faster and shows raw numbers.lsof -nP -iTCP:5000 -sTCP:LISTENList all network sockets
-i alone lists every internet socket. Add 4 or 6 to filter by IP version, or TCP/UDP.lsof -nP -iTCP -sTCP:ESTABLISHEDSee one app's connections
-c filters by command name; -a ANDs the conditions together.lsof -nP -a -i -c SafariFind who holds a file or volume
Give a path to see which processes have it open, for example when a drive won't eject.lsof /Volumes/BackupInclude other users' processes
Root-owned daemons need sudo.sudo lsof -nP -iUDP:53
Output explained
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ControlCe 499 jane 10u IPv4 0x62c8… 0t0 TCP *:5000 (LISTEN)
ControlCe 499 jane 11u IPv6 0xa80f… 0t0 TCP *:5000 (LISTEN)
rapportd 478 jane 4u IPv6 0xaed8… 0t0 TCP [fe80:e::5f:daca:262:290f]:55046->[fe80:e::44a:8f3:2321:3fbe]:65067 (ESTABLISHED)
- COMMAND is the process name, truncated to 9 characters (ControlCe = ControlCenter).
- PID is the process ID, which you pass to
kill. - FD is the file descriptor number;
umeans open for reading and writing. - TYPE IPv4 or IPv6.
- NAME is the socket:
*:5000 (LISTEN)listens on all interfaces;local->remote (ESTABLISHED)is a connection.
The example is real: on macOS 15, ControlCenter listens on 5000 and 7000 for AirPlay Receiver.
Options and variations
| Flag | Meaning | Example |
|---|---|---|
| -i[46][TCP|UDP][@host][:port] | Internet sockets, optionally filtered | lsof -i4TCP:443 |
| -sTCP:STATE | Filter TCP sockets by state (LISTEN, ESTABLISHED) | lsof -iTCP -sTCP:LISTEN |
| -n / -P | Don't resolve host names / port names | lsof -nP -i |
| -p PID | Only this process | lsof -p 499 |
| -c NAME | Processes whose name starts with NAME | lsof -c node |
| -a | AND the following conditions (default is OR) | lsof -a -c node -i |
| -t | Print PIDs only, for scripting | lsof -tiTCP:3000 |
Common errors
| Error | Cause | Fix |
|---|---|---|
| No output | Nothing matches, or the process belongs to another user | Retry with sudo; check the port number. |
| Very slow output | lsof is resolving names for every connection | Always add -nP. |
| lsof: WARNING: can't stat() … file system | A mounted volume (often a network share) isn't responding | Harmless; add -b or ignore. |
Do it in the app
LightAtom's Ports view is a live, sortable version of sudo lsof -iTCP -sTCP:LISTEN: every open port, the process, its user and whether it's reachable from the network, with no sudo needed.
Frequently asked questions
How do I find which process is using a port on a Mac?
Run lsof -nP -iTCP:PORT -sTCP:LISTEN. The PID column tells you which process to stop. Add sudo if the process belongs to root or another user.
What does lsof -i do?
It lists internet sockets: listening ports and connections, with the process that owns each. Add -nP to skip slow name lookups.
Why does lsof need sudo?
Without sudo it can only inspect your own processes. System daemons run as root or service accounts, so you need sudo to see their sockets.
Is netstat better than lsof on a Mac?
netstat -an lists sockets but not which process owns them on macOS. lsof shows the process, which is usually what you need.