1. Library
  2. Tools and Commands
  3. Network Analysis

Updated 10 hours ago

Your disk says it's full, but you just deleted a 2GB log file. Where did the space go?

A process is still holding that file open—like a hand gripping a book that's been removed from the shelf. The book is gone from the catalog, but the hand doesn't know it yet. Until that process releases its grip, the space can't be reclaimed.

lsof (list open files) shows you these invisible hands. And on Unix-like systems, where "everything is a file"—network sockets, devices, pipes, the works—lsof becomes X-ray vision into what your system is actually doing.

The Philosophy

When you run lsof without arguments, it lists every open file on the system. Thousands of entries. The raw truth of everything your operating system is touching at this moment.

The power comes from filtering that truth to answer specific questions:

  • What's using port 3000?
  • Why can't I unmount this drive?
  • What files does nginx have open?
  • Who's connected to my database?

Finding What's Using a Port

The question that brings most people to lsof: "Something's already using that port."

lsof -i :3000

This shows every process with a connection on port 3000—listening, established, anything.

To see only listeners:

lsof -i -sTCP:LISTEN

To check a specific port with a specific protocol:

lsof -i TCP:22
lsof -i UDP:53

Finding What's Blocking an Unmount

The filesystem won't unmount. Something has a file open. What?

lsof +D /mnt/external

The +D recursively searches the directory. Every process with any file open under that path appears.

For a single file:

lsof /var/log/syslog

Finding Where Your Disk Space Went

You deleted files, but df still shows the disk as full. Find the ghosts:

lsof | grep deleted

These are files that have been unlinked from the filesystem but are still held open by processes. The space won't be freed until those processes close the files or terminate.

Investigating a Process

See everything a specific process has open:

lsof -p 1234

Or by program name (matches any process starting with that string):

lsof -c nginx

Counting open files can reveal file descriptor leaks:

lsof -p 1234 | wc -l

Run this periodically. If the number grows without bound, something's leaking.

Network Connections

All network activity:

lsof -i

Just TCP:

lsof -i TCP

Just established connections:

lsof -i -sTCP:ESTABLISHED

Connections to a specific host:

lsof -i @192.168.1.100

Reading the Output

Typical lsof output:

COMMAND   PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nginx    1234   www    3u  IPv4  12345      0t0  TCP *:80 (LISTEN)
nginx    1234   www    4u  IPv4  12346      0t0  TCP 192.168.1.100:80->93.184.216.34:54321 (ESTABLISHED)

The columns that matter most:

FD (file descriptor): The number followed by a mode letter. 3u means file descriptor 3, open for read/write (u). Other modes: r for read, w for write. Special values like cwd (current working directory) and txt (program code) also appear here.

TYPE: What kind of file. REG is a regular file, DIR is a directory, IPv4/IPv6 are network sockets, unix is a Unix domain socket.

NAME: The file path, or for network connections, the local and remote addresses with connection state.

Combining Filters

By default, multiple options are OR'd together. Use -a for AND:

# Files opened by user AND nginx (both conditions must match)
lsof -u www-data -c nginx -a

# Listening TCP connections for nginx specifically
lsof -c nginx -i TCP -sTCP:LISTEN -a

Without -a, you get files matching either condition.

Faster Output

By default, lsof resolves hostnames and port names. This is slow. Skip it:

lsof -nP -i

-n skips hostname resolution. -P skips port name resolution (shows 443 instead of https).

Scripting

Get just the PIDs (for piping to kill or other commands):

lsof -t -i:3000

Check if a port is in use:

if lsof -Pi :3000 -sTCP:LISTEN -t >/dev/null; then
    echo "Port 3000 is in use"
else
    echo "Port 3000 is available"
fi

Kill whatever's using a port:

lsof -t -i:3000 | xargs kill

Watching in Real-Time

Monitor connections as they change:

watch -n 1 'lsof -i -nP'

Watch a specific file until it's closed:

lsof +r 1 /var/log/app.log

The +r 1 repeats every second until the file is no longer open.

What to Remember

lsof answers the question: "What has this open?" Whether "this" is a port, a file, a directory, or a filesystem.

  • lsof -i :PORT — what's using this port?
  • lsof +D /path — what's accessing this directory?
  • lsof -p PID — what does this process have open?
  • lsof | grep deleted — where did my disk space go?
  • Add -nP for speed, -t for just PIDs, -a to AND conditions together.

On a Unix system, when something invisible is holding onto something you need, lsof makes it visible.

Frequently Asked Questions About lsof

Was this page helpful?

😔
🤨
😃