/tmp Cleanup Best Practices - tmpfiles.d and systemd-tmpfiles

/tmp Cleanup Best Practices - tmpfiles.d and systemd-tmpfiles

What You'll Learn

  • How /tmp, /var/tmp, and /run are managed by systemd
  • How to write tmpfiles.d rules for custom cleanup
  • How to run systemd-tmpfiles manually and on a schedule

Quick Summary

  • Automatic /tmp cleanup is handled by systemd-tmpfiles-clean.timer
  • Custom rules go in /etc/tmpfiles.d/*.conf
  • Rule format: type path mode uid gid age argument

Prerequisites

  • OS: Ubuntu or any systemd-based Linux
  • Root or sudo access required

Why Does /tmp Need Cleanup?

/tmp is where applications write temporary files. On most Ubuntu systems it is a tmpfs in RAM — wiped on reboot. Long-running servers, however, accumulate temp files between reboots, which can exhaust disk space and cause stale PID or socket file references.

  • Typical uses: intermediate files from compression, session data, socket files
  • Ubuntu default: /tmp is mounted as tmpfs, so it is cleared on reboot
  • /var/tmp: persists across reboots by design — requires explicit management
$ mount | grep /tmp
tmpfs on /tmp type tmpfs (rw,nosuid,nodev)

If /tmp is tmpfs, files vanish on reboot. If it is disk-backed, cleanup is even more critical. Check usage with df -h /tmp.

What Is systemd-tmpfiles?

systemd-tmpfiles is the declarative tool for managing temporary directories — creating them on boot, setting permissions, and deleting stale files on a schedule.

Three operation modes:

Mode Flag Action
Create --create Create files/dirs per rules
Clean --clean Delete entries older than their age threshold
Remove --remove Delete everything matching the rules
$ sudo systemd-tmpfiles --create
$ sudo systemd-tmpfiles --clean
$ sudo systemd-tmpfiles --remove

Two systemd units run these automatically:

  • systemd-tmpfiles-setup.service — runs --create at boot
  • systemd-tmpfiles-clean.timer — runs --clean periodically (default: 15 min after boot, then daily)

How to Write tmpfiles.d Rules

Drop config files in /etc/tmpfiles.d/. System defaults live in /usr/lib/tmpfiles.d/ — never edit those directly, since package updates overwrite them.

Format

type path mode uid gid age argument
Field Description Example
type Operation type d, f, x, e
path Target path /tmp/myapp
mode Permissions (octal) 0755
uid/gid Owner (- = keep current) root / -
age Delete threshold for --clean 7d, 1h, - (never)
argument Initial content for files -

Common Types

Type Meaning
d Create directory if missing; --clean removes aged files inside
D Like d, but --remove also deletes directory contents
f Create file if missing
f+ Create or truncate file
x Exclude from --clean and --remove
e Set permissions on an existing entry
z Set permissions and SELinux labels

How to Run Periodic Cleanup

Check the cleanup timer:

$ systemctl status systemd-tmpfiles-clean.timer
● systemd-tmpfiles-clean.timer - Daily Cleanup of Temporary Directories
     Loaded: loaded (/lib/systemd/system/systemd-tmpfiles-clean.timer; static)
     Active: active (waiting) since Mon 2024-01-01 00:00:00 UTC; 3h ago
    Trigger: Tue 2024-01-02 00:15:30 UTC; 20h left

Trigger an immediate cleanup:

$ sudo systemctl start systemd-tmpfiles-clean

--clean only acts on entries where the age field is set. An entry with age - is never deleted automatically.

Practical Examples

Example 1: Per-app temp directory with auto-cleanup

# /etc/tmpfiles.d/myapp.conf
d /tmp/myapp 0750 myapp myapp 1d

Creates /tmp/myapp owned by myapp:myapp with mode 0750, and deletes files inside that are older than 1 day.

Example 2: Clean app logs in /var/tmp after 7 days

# /etc/tmpfiles.d/clean-var-tmp.conf
d /var/tmp/app-logs 0755 root root 7d

Example 3: Create /run directory at boot with no auto-delete

# /etc/tmpfiles.d/myapp-run.conf
d /run/myapp 0755 myapp myapp -

Age - means: create at boot, never auto-delete.

Example 4: Exclude a path from cleanup

# /etc/tmpfiles.d/exclude.conf
x /tmp/persistent-cache

--clean skips /tmp/persistent-cache regardless of age.

Apply and verify rules immediately

# Apply create rules now
$ sudo systemd-tmpfiles --create /etc/tmpfiles.d/myapp.conf

# Dry run: preview what --clean would delete
$ sudo systemd-tmpfiles --clean --dry-run /etc/tmpfiles.d/myapp.conf

Always use --dry-run before running --clean on a new rule. It shows what would be deleted without making any changes.

Common Issues

Files are not being deleted

Check that the age field is not -. Also note that --clean uses atime (last access time) as the threshold, not mtime.

$ stat /tmp/myfile | grep Access

If the filesystem is mounted with noatime, atime is never updated, so files may appear older than they are. Use touch -a /tmp/myfile to update atime manually when testing.

Rules not taking effect

Validate the config directly:

$ sudo systemd-tmpfiles --create /etc/tmpfiles.d/myapp.conf

Check the journal for errors:

$ journalctl -u systemd-tmpfiles-setup

Override a system rule in /usr/lib/tmpfiles.d/

Drop a file with the same name in /etc/tmpfiles.d/ — it takes priority. Load order: /etc > /run > /usr/lib.

# View the system rule
$ cat /usr/lib/tmpfiles.d/tmp.conf

# Create your override and edit it
$ sudo cp /usr/lib/tmpfiles.d/tmp.conf /etc/tmpfiles.d/tmp.conf

What not to do

  • Edit files under /usr/lib/tmpfiles.d/ directly — package updates will overwrite them
  • Use type D on a critical directory without an age limit — --remove will delete all contents

Next Reading