Systems troubleshooting guide8 min read

Why deleted files still use disk space on Linux

When df says a filesystem is full but du cannot find the bytes, an open deleted file is a prime suspect. Confirm the descriptor, identify its owner, and release it through the application.

Reviewed by the Terminaster editorial team · Updated

What you will take away

  • Deleting a pathname removes a directory entry; an open file can remain allocated until its last reference is closed.
  • A large gap between df and du can point to open deleted files, but reserved blocks, mount boundaries, and snapshots can cause similar symptoms.
  • Use lsof +L1 or Linux /proc/PID/fd to identify the holding process and descriptor.
  • Prefer a graceful application restart or supported log-reopen mechanism over truncating a live descriptor.

Understand why df and du can disagree

df asks the filesystem for allocated and available block counts. du walks reachable pathnames and adds the blocks associated with files it can see. A deleted file has no reachable pathname for du to visit, while df continues counting its allocated blocks.

Open deleted files are not the only explanation. Files hidden beneath a mount point, filesystem snapshots, reserved blocks, permissions, sparse-file accounting, and checking different filesystem boundaries can also produce differences. First confirm that df and du refer to the same mounted filesystem.

Compare one filesystem without crossing mounts

target=/var
findmnt --target "$target"
df -h "$target"
sudo du -xhd1 "$target" 2>/dev/null | sort -h

Find the process holding a deleted file open

On Linux, lsof +L1 selects open files whose link count is below one, which usually means deleted regular files. Look at the process name, PID, descriptor, file size, and mount before deciding what to do. Some output may require elevated permission.

You can confirm one result through /proc/PID/fd. A descriptor symlink ending in “(deleted)” identifies the open unlinked object, fdinfo supplies position and flags, and stat can distinguish logical length from allocated blocks. Do not rely on lsof’s SIZE/OFF column alone: sparse files and filesystem accounting can make logical size very different from allocated space.

  • Record the command and PID so you can find the owning service or container.
  • Check whether the descriptor is still growing and whether it belongs to a log, database, temporary file, or executable.
  • Confirm the file is on the full filesystem; a deleted file elsewhere is unrelated.
  • If evidence may be needed, arrange collection before restarting the process.

Locate and confirm deleted descriptors

sudo lsof +L1

pid=1234
fd=17
sudo ls -l "/proc/$pid/fd" | grep -F '(deleted)'
sudo stat -Lc 'logical=%s bytes; allocated=%b blocks of %B bytes' \
  "/proc/$pid/fd/$fd"
sudo cat "/proc/$pid/fdinfo/$fd"

Release the descriptor through its owner

The safest remedy is application-specific: ask the process to reopen logs, rotate them using its supported mechanism, stop the responsible job, or restart the service gracefully. Once the last descriptor closes, the filesystem can reclaim the blocks automatically.

Writing to or truncating /proc/PID/fd/N can alter the live file object and interfere with the process’s file offset, buffering, or data guarantees. It is an emergency technique with application-specific risk, not a routine cleanup command. Likewise, killing a database merely to free space can create a larger incident.

  1. 1Identify the filesystem, process, descriptor, and approximate retained size.
  2. 2Check the application’s documented log-reopen, rotation, shutdown, or restart procedure.
  3. 3Preserve evidence or recover needed contents before closing the final reference.
  4. 4Release the descriptor through the supported procedure.
  5. 5Verify that df reports reclaimed space and that the service resumes normally.

Prevent log rotation from unlinking a live writer

A common cause is external rotation that renames or deletes a log while the application keeps writing through its original descriptor. Configure rotation to signal the application to reopen its log, or use the application’s native rotation support.

Copy-and-truncate rotation keeps the pathname but has race and data-loss tradeoffs, so it is not a universally safer substitute. Test the selected method under real write volume, monitor filesystem free space, and alert on open deleted files that continue growing.

Verify after a controlled reopen or restart

sudo lsof +L1

df -h /var
# Then confirm the service is healthy with its normal status and checks.

Common questions

Frequently asked questions

Why does rm not immediately free space for an open file?

rm normally unlinks a pathname. If a process still holds the file open, the kernel preserves the inode and data blocks until the final open reference closes.

Can I recover a deleted file through /proc?

On Linux, a readable /proc/PID/fd/N entry may provide access while the descriptor remains open. Recovery is permission- and application-dependent, and the file may still be changing, so copy it to another filesystem only with adequate capacity and an incident-safe plan.

Does every df and du mismatch mean an open deleted file?

No. Mount boundaries, snapshots, reserved blocks, hidden mounted-over files, permissions, and accounting details can also differ. Use lsof or /proc to confirm an open deleted file on the affected filesystem.

Keep learning

Sources and next steps