lsof

On this page 7

lsof, short for “list open files”, is a command-line utility that reports which processes have which files open on a Linux or other Unix-like system. Because Linux treats regular files, directories, devices, pipes and network sockets as file descriptors, lsof answers a wide range of monitoring questions: which program holds a log file, which process listens on port 443, or why a disk stays full after a large file was deleted.

In Linux monitoring, lsof complements resource-oriented tools such as top, htop, iostat and vmstat. Those tools show how much CPU, memory or I/O is used; lsof shows exactly what each process is touching at a given moment.

How lsof finds open files

On Linux, lsof gathers its data mainly from the /proc filesystem. For each process it reads the symbolic links in /proc/PID/fd, the memory mappings in /proc/PID/maps, and the working and root directories, then resolves socket details from tables such as /proc/net/tcp. The result is a point-in-time snapshot, not a continuous trace.

Visibility depends on privileges. An ordinary user sees full details only for their own processes, while root sees every process on the host. Inside containers, lsof sees only the processes of the container’s PID namespace, which often explains why an expected process is missing from the output.

Reading lsof output columns

Each output line describes one open file of one process. The columns are compact, and two of them, FD and TYPE, carry most of the diagnostic value. The table explains the default columns.

ColumnMeaningExample value
COMMANDFirst characters of the process namenginx
PIDProcess identifier1423
USEROwner of the processwww-data
FDDescriptor number or special role4u, cwd, txt, mem
TYPEKind of fileREG, DIR, IPv4, unix, FIFO
DEVICEDevice numbers of the file system8,1
SIZE/OFFFile size or current offset1048576
NODEInode number or protocol262147, TCP
NAMEPath, address pair or socket state*:443 (LISTEN)
Default lsof output columns

In the FD column, a number is a real file descriptor and the following letter shows the access mode: r for read, w for write and u for read and write. Special values describe other relationships: cwd is the current directory, txt the program binary, mem a memory-mapped file such as a shared library, and DEL a mapping of a deleted file. A NAME ending in “(deleted)” marks a file removed from the directory tree that is still held open.

Essential lsof options and filters

Without options, lsof prints every open file on the system, often tens of thousands of lines. Filters narrow the output, and by default multiple filters are combined with OR; adding -a combines them with AND. The table lists the most useful selections.

CommandWhat it showsTypical question
lsof -i :8080Processes using port 8080What blocks this port
lsof -iTCP -sTCP:LISTEN -nPAll listening TCP socketsWhich services accept connections
lsof -p 1423Open files of one processWhat is this process doing
lsof -u postgresFiles opened by one userWhat does this account touch
lsof /var/log/app.logProcesses holding one fileWho writes this log
lsof +D /mnt/dataOpen files under a directory treeWhy unmount fails
lsof +L1Open files with zero linksWhere deleted space is held
Frequently used lsof selections

Two habits make lsof much faster and clearer: -n skips DNS lookups and -P shows port numbers instead of service names. For scripts, -t prints only PIDs, and -F produces a field-based output format that is easier to parse than the aligned columns.

lsof compared with ss, fuser, strace and /proc

Several tools overlap with lsof, and choosing the right one saves time. lsof is the broadest inventory tool, while its neighbors are faster or more specialized for a single question.

ToolStrengthWhen to prefer it
lsofAll file types with process contextGeneral inventory and diagnosis
ssVery fast socket listingLarge numbers of network connections
fuserPIDs using a file or mount, can signal themQuick checks before unmounting
straceLive system calls as they happenSeeing when files are opened
/proc/PID/fdRaw descriptor links, no extra toolMinimal systems and containers
Tools that overlap with lsof

The key distinction is snapshot versus timeline: lsof and ss show the current state, while strace shows the sequence of opens, reads and closes over time. For a short-lived process that opens and closes a file within milliseconds, lsof will usually miss the event entirely.

Pitfalls when using lsof

  • Running without root hides other users’ processes and makes a busy port look free.
  • Network file systems can make lsof hang; a stale NFS mount may block it for minutes, and the -b option avoids some blocking kernel calls.
  • Recursive +D on large trees is slow because lsof must stat every file; lsof /mountpoint is faster when the target is a whole mount.
  • Counting lines is not counting descriptors: memory mappings and threads add rows, so ls /proc/PID/fd | wc -l gives the true descriptor count for limit checks.
  • Containers and namespaces hide processes, so lsof should run in the namespace that owns the process.

lsof is also an excellent tool for spotting file descriptor leaks. If the number of open sockets or files of a long-running service grows steadily over hours, the service is likely failing to close resources and will eventually hit its “Too many open files” limit.

A non-technical view

Imagine a library where every book, desk and phone line is recorded on a sign-out sheet. lsof reads that sheet for the computer. It tells an administrator who currently has what: which program is holding a document, which one is answering calls on a certain line, and which one refuses to give something back.

That is useful whenever something seems stuck. If a disk cannot be removed or a program cannot start because “the address is in use”, lsof names the program responsible, so the problem can be solved precisely instead of by restarting everything.

A concrete example

An administrator notices that the root file system of a Linux web server reports 95 percent usage in `df`, while du over the whole disk adds up to only 60 percent. A colleague had deleted a 12 GB debug log the day before, yet the space never came back.

Running lsof +L1 shows the application server still holding /var/log/app/debug.log (deleted) with a size of about 12 GB. Because the process keeps the descriptor open, the kernel cannot free the blocks. Instead of restarting the service at peak time, the administrator truncates the file through its descriptor with : > /proc/2210/fd/7, and usage drops to 60 percent immediately. The team then configures log rotation to signal the service to reopen its logs.