Cheat Sheet

lsof Examples

lsof lists open files, and on Linux a socket, a directory and a mount point are all files, so it answers both 'what is using port 8080' and 'what is keeping this filesystem busy'. This sheet covers the filters worth remembering and how to read the columns that come back.

Last updated September 11, 2026

Ports

The question is almost always "what is holding port 8080". takes a port on its own or with a protocol in front of it.

CommandWhat it does
Every process using port 8080, listening or connected
TCP only ( for UDP)
The server on that port, not the clients talking to it
Just the PID, ready to pipe into another command
A range of ports
Every listening TCP port on the machine
Port 8080, but only what user deploy owns

Free the port, then confirm it is free:

sudo lsof -i :8080                   # who has it
kill $(sudo lsof -ti :8080)          # ask them to stop
kill -9 $(sudo lsof -ti :8080)       # make them stop

Without you see only your own processes, so a port held by root reads as free. For a plain list of listeners, is faster; see the netstat and ss sheet.

Files and Mounts

The other everyday job: something will not unmount, or a file will not delete.

CommandWhat it does
Which processes have this exact file open
Every open file on that filesystem, when the path is a mount point
Everything open under a directory, walking the whole tree
Same, but one level down only and much faster
Treat the path as a plain file, not as a filesystem
Who is using a block device
Files open on NFS mounts
The same answer from fuser, which can also kill with

lsof reads a path as a filesystem when it matches a mount point from , and as a single file otherwise. That is why lists hundreds of rows and lists one.

Processes and Users

CommandWhat it does
Files open by any command starting with nginx
Exact command name, written as a regex
Everything except sshd (a leading negates)
Everything PID 1234 has open
Several PIDs at once
Every PID of a process by name
Files open by one user
Everything except root's files
How many files a process has open, to compare with
The working directory of every process
Only stdin, stdout and stderr

Deleted Files

The classic case: says the disk is full, says it is not. A process is holding a file that no longer has a name, and the space comes back only when the descriptor closes.

CommandWhat it does
Open files with no directory entry left, the ones eating the space
Same, limited to one filesystem
The grep version, works on any lsof build
What one process is still holding
sudo lsof +L1                    # find the holder: note its PID and FD
sudo systemctl restart rsyslog   # cleanest fix, restart the owner
: > /proc/1234/fd/7              # or empty the file in place, no restart

Deleting a log file that a service is writing to is what causes this. Truncate with or hand it to logrotate instead.

Network Connections

CommandWhat it does
Every open network file on the machine
The same, without DNS and service name lookups
IPv4 only ( for IPv6)
Live TCP connections, nothing that is merely listening
Connections to or from one host
One host and port together
Only what node has on the network
UNIX domain sockets, the socket files under
Repeat the listing every 5 seconds

lsof names the process behind a connection; tcpdump shows what that connection is sending.

Output Columns

Half of using lsof is reading what it printed.

COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
nginx    1234  root    6u  IPv4  28134      0t0    TCP *:80 (LISTEN)
nginx    1234  root   11w   REG  253,0   184320 264781 /var/log/nginx/access.log
sshd      902  root    3u  IPv6  21883      0t0    TCP 10.0.0.5:22->10.0.0.9:51544 (ESTABLISHED)
ColumnWhat it holds
Program name, cut to nine characters unless you pass
Process ID, the column prints on its own
The user the process runs as
Descriptor number and mode, or a keyword (see below)
file, directory, device or terminal, pipe, / socket, socket file
Device major and minor numbers, or the kernel address of a socket
File size in bytes, or the read/write offset written as and a number
Inode number for a file; for a socket it is the protocol, or
The path, or for a connection

FD is the column people misread. It is either a number with a mode letter or one of these keywords:

FD valueMeaning
, , Descriptor number plus mode: read, write, read and write
A trailing or is a lock held on the file
The process's current working directory
Its root directory, which differs after a chroot
Program text: the executable being run
A memory-mapped file, nearly always a shared library
A mapped file that has since been deleted
lsof could not read , usually a permission problem

Output Flags

FlagWhat it does
PIDs only, no header and no columns, made for
Skip DNS lookups, show numeric addresses
Skip service name lookups, show port numbers
Print full command names instead of nine characters
Machine-readable output, one field per line with a leading letter
Only the PID, command and name fields, for scripts
Suppress the noise from fuse and gvfs mounts
Avoid kernel calls that can block, for when a network mount is hung
Show numeric UIDs instead of usernames (fixes )
Repeat every 5 seconds until Ctrl+C
, Usage summary; version and build details

together is worth making a habit. It removes both lookups and turns a command that takes seconds into one that returns straight away.

Combining Filters

Filters of different kinds OR together by default, which catches almost everyone out. turns the whole line into AND.

CommandWhat you get
Everything deploy has open, plus everyone's network files
Only deploy's network connections
Only the network files of PID 1234
nginx processes running as www-data, nothing else
Listening TCP sockets that root does not own
What deploy has open under
nginx or php-fpm: filters of the same kind always OR, even with

applies to the entire command line. There is no way to AND one pair of options while leaving another pair as OR; run two commands instead.

Gotchas

  • Without , lsof quietly shows only your own processes. An empty result is not proof that a port or file is free.
  • lsof is not installed on minimal Debian, Ubuntu and RHEL images. or .
  • matches listeners and connections to that port. Add when you want the server alone.
  • There is no JSON output. is the parseable format: one field per line, each prefixed by a letter, and keeps it to PID, command and name.
  • lines are normal on machines with fuse or gvfs mounts. hides them and the results are unaffected.
  • Inside a container, lsof sees that container's namespace only. Run it on the host to find who really owns a port.
  • On macOS, is the way to map a port to a process, because netstat there cannot show process names at all.

lsof FAQ

How do I find and kill the process using a port?

sudo lsof -i :8080 names it, and sudo lsof -ti :8080 prints the PID on its own, so kill -9 $(sudo lsof -ti :8080) clears the port in one line. Run it with sudo: without it you only see your own processes, and a port held by root or www-data looks free. Add -sTCP:LISTEN if you want the server and not every client connected to it. A multi-worker server has several PIDs on the same port, -t prints them all, and kill takes the whole list.

What do the FD and TYPE columns in lsof output mean?

FD is the file descriptor: a number plus a mode letter, where r is read, w is write and u is both, with a trailing W or R when the process holds a lock. Some rows show a keyword instead of a number: cwd is the working directory, rtd the root directory, txt the executable itself, mem a memory-mapped library, DEL a mapped file that has been deleted. TYPE says what kind of file it is: REG a regular file, DIR a directory, CHR a terminal or device, FIFO a pipe, IPv4 and IPv6 sockets, unix a socket file.

Why does lsof return nothing?

Usually permissions. lsof only shows files owned by processes you can see, so without sudo a port held by another user comes back empty rather than with an error. Run sudo lsof -i :8080. Other causes: the port really is free, so the connection attempt would be refused; you searched a path instead of a mount point, which matches only that exact file; or you are inside a container, where lsof sees the container's namespace and not the host. If the shell says command not found instead, lsof is not installed.

Why is lsof so slow, or why does it hang?

By default lsof resolves every IP to a hostname and every port number to a service name, and it stats every mounted filesystem. Add -n and -P to skip both lookups and the same command usually returns instantly. If it freezes rather than crawls, a network mount is the cause: a hung NFS server blocks the stat call forever, and -b tells lsof to skip the calls that can block. +D on a large tree is slow for a different reason, it walks every directory below the path.

df says the disk is full but du does not, how do I find the file?

A process still has a deleted file open, so the space is not released until it closes. sudo lsof +L1 lists open files with no directory entry left, and the SIZE column shows how much each is holding. The usual culprit is a log file someone removed instead of truncating while the service kept writing to it. Restart the owning service to release the space, or on Linux empty the file in place without a restart: : > /proc/PID/fd/7, using the PID and FD number from the lsof row.

Related cheat sheets