If you have ever created a custom directory inside /var/run only to find it gone after a reboot, you are not alone. This is one of the most common surprises for Linux administrators. This guide explains why it happens and how to make your directories persist across reboots using systemd-tmpfiles.

Why /var/run Is Volatile

The /var/run directory (and its modern equivalent /run) is mounted as a tmpfs filesystem — a RAM-based filesystem that exists only in memory. Ubuntu allocates a portion of your RAM (typically around 10%) for this mount.

You can verify this with:

df -h /run
# Output:
# Filesystem      Size  Used Avail Use% Mounted on
# tmpfs           1.6G  1.2M  1.6G   1% /run

mount | grep tmpfs | grep run
# Output:
# tmpfs on /run type tmpfs (rw,nosuid,nodev,noexec,relatime,size=1632548k,mode=755)

Applications use /var/run to store:

  • PID files — process IDs for running daemons (e.g., /run/nginx.pid)
  • Socket files — Unix domain sockets for inter-process communication (e.g., /run/php/php-fpm.sock)
  • Lock files — to prevent multiple instances of a process
  • Runtime state — temporary data needed only while the system is running

Because this data is in RAM, access is extremely fast — but everything is lost on reboot.

Note: On modern Ubuntu (15.04+), /var/run is a symlink to /run. They are the same location.

ls -la /var/run
# Output:
# lrwxrwxrwx 1 root root 4 ... /var/run -> /run

The Solution: systemd-tmpfiles

The systemd-tmpfiles service is responsible for creating, deleting, and cleaning up volatile and temporary files and directories at boot. It reads configuration files from three locations (in order of priority):

  1. /etc/tmpfiles.d/ — Local administrator overrides (highest priority)
  2. /run/tmpfiles.d/ — Runtime configuration
  3. /usr/lib/tmpfiles.d/ — Package-provided defaults (lowest priority)

Step 1: Create a Configuration File

Create a .conf file in /etc/tmpfiles.d/:

sudo nano /etc/tmpfiles.d/myapp.conf

Step 2: Add the Directory Definition

The configuration format is:

# Type  Path          Mode  User    Group   Age  Argument
d       /run/myapp    0755  myuser  mygroup -    -

Each field means:

FieldDescriptionExample
Typed = create directoryd
PathFull path to create/run/myapp
ModePermissions (octal)0755
UserOwner userwww-data
GroupOwner groupwww-data
AgeAuto-cleanup after this age (- = never)10d or -
ArgumentAdditional arguments (usually -)-

Step 3: Apply Immediately (Without Rebooting)

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

Step 4: Verify

ls -la /run/myapp
# Output:
# drwxr-xr-x 2 myuser mygroup 40 ... /run/myapp

Practical Examples

Nginx PID Directory

# /etc/tmpfiles.d/nginx.conf
d /run/nginx 0755 www-data www-data -

PHP-FPM Socket Directory

# /etc/tmpfiles.d/php-fpm.conf
d /run/php 0755 www-data www-data -

Custom Application with Multiple Subdirectories

# /etc/tmpfiles.d/myapp.conf
d /run/myapp       0755 appuser appgroup -
d /run/myapp/pids  0755 appuser appgroup -
d /run/myapp/sock  0750 appuser appgroup -

Directory with Automatic Cleanup (remove files older than 30 days)

# /etc/tmpfiles.d/myapp-tmp.conf
D /run/myapp/tmp 0755 appuser appgroup 30d

Note the uppercase D — this cleans up the directory contents based on the age parameter.

Other tmpfiles.d Types

Beyond directories, tmpfiles.d can manage other resources:

# Create an empty file
f /run/myapp/status 0644 appuser appgroup -

# Create a symlink
L /run/myapp/current - - - - /opt/myapp/latest

# Write content to a file
f+ /run/myapp/config 0644 appuser appgroup - "key=value"

The Legacy Approach (Pre-systemd)

On very old Ubuntu systems (before 15.04) that do not use systemd, the equivalent mechanism was modifying /etc/rc.local or creating init scripts:

# /etc/rc.local (legacy — do NOT use on systemd systems)
mkdir -p /var/run/myapp
chown myuser:mygroup /var/run/myapp
chmod 0755 /var/run/myapp

Warning: Do not use /etc/rc.local on modern Ubuntu. Use tmpfiles.d instead — it is the proper systemd mechanism and integrates correctly with the boot process.

Troubleshooting

Directory Not Created After Reboot

  1. Verify the config file syntax:
sudo systemd-tmpfiles --create --dry-run /etc/tmpfiles.d/myapp.conf
  1. Check for syntax errors in the journal:
journalctl -u systemd-tmpfiles-setup.service

Permission Denied

Make sure the user and group specified in the config file exist:

id myuser
getent group mygroup

Viewing Current tmpfiles Configuration

List all active tmpfiles rules:

systemd-tmpfiles --cat-config

Or check what a specific package configured:

cat /usr/lib/tmpfiles.d/nginx.conf

Summary

Directories in /var/run (or /run) disappear on reboot because they live on a tmpfs RAM disk. To create persistent directories that are automatically recreated at boot:

  1. Create a file in /etc/tmpfiles.d/yourapp.conf
  2. Define your directories with the d type, specifying path, permissions, and ownership
  3. Apply with sudo systemd-tmpfiles --create

This is the standard systemd mechanism used by all major packages (Nginx, PHP-FPM, MySQL, etc.) to manage their runtime directories.