Right, let’s talk about the two directories on your system that are designed to be forgotten: /tmp and /run. They’re the digital equivalent of a whiteboard—incredibly useful for scribbling down a thought, but you’d be horrified if that scribble became a permanent fixture on your wall. They hold data that only matters right now. The key difference between them is a question of ownership: is this temporary data for you, the user, or for the system and its services?

/tmp: The User’s Scratchpad

This is the one you’ve probably used. /tmp is a global free-for-all. Any user on the system can create files here. It’s the shared workshop table where anyone can dump a file they’re processing, a cache for a large download, or where your text editor stashes the unsaved buffer you’re working on.

The most important thing to know about /tmp is that its contents are not guaranteed to survive a reboot. In fact, on most modern distributions, they’re actively deleted every time you boot up. This is by design. It’s a cleanup mechanism for poorly behaved applications that forget to delete their own junk.

You can see this in action. Create a file and check its access time:

echo "I am fleeting" > /tmp/test_file.txt
ls -l /tmp/test_file.txt

Now reboot. Poof. It’s gone. This is why you should never use /tmp for anything of actual importance. I’ve seen more than one junior admin try to use it as a holding area for critical scripts. Don’t be that person.

There’s a classic pitfall here: security. Because it’s world-writable, /tmp is a favorite haunt for attackers. A common trick is to create a symlink in /tmp pointing to a critical file and hope that a script running as root will blindly write to it. To combat this, most modern systems use the sticky bit on /tmp.

ls -ld /tmp
# drwxrwxrwt 10 root root 4096 May 21 10:00 /tmp

See that t at the end of the permissions? That’s the sticky bit. It means that while anyone can create a file in /tmp, you can only delete a file if you own it. This prevents User A from deleting User B’s files—a simple but brilliant solution to a messy problem.

/run: The System’s Lockbox

Now, /run (which replaced the older /var/run) is a different beast. This is where the system and your running services keep their runtime information—the stuff that only exists while the system is alive. We’re talking about process IDs (.pid files), communication sockets, and state information for daemons.

Crucially, /run is not for users. It’s owned by root and, on a properly functioning system, you can’t write to it as a regular user. This data is strictly for the operating system’s internal bookkeeping.

The contents are created on boot and wiped on shutdown. It’s a tmpfs (a filesystem held entirely in RAM), which makes it blisteringly fast. This is perfect for its purpose: a service needs to create a socket to listen on, and it needs to do it now, not after waiting for a disk to spin up.

Let’s look at what’s in there:

ls -la /run

You’ll see a fascinating snapshot of your running system. Key items include:

  • /run/udev: Rules and data for device management.
  • /run/user/<uid>: Per-user runtime directories created by pam_systemd for things like your desktop’s D-Bus socket.
  • /run/docker.sock: The communication socket for the Docker daemon (if you have it running).
  • Dozens of .pid files: These tiny files contain nothing but the Process ID of a running service. It’s how the system knows how to stop a service gracefully (systemctl stop nginx looks in /run/nginx.pid to find the PID to send the TERM signal to).

Best Practices and The Gotchas

  1. Never Hardcode Paths: This is the golden rule. Your script should never assume /tmp/my_awesome_script.lock is available. Use mktemp to create a guaranteed-unique temporary file or directory. This avoids race conditions and name collisions.

    # Create a secure temporary file
    TEMP_FILE=$(mktemp /tmp/myscript.XXXXXX)
    echo "Safe and unique: $TEMP_FILE"
    
    # Create a secure temporary directory
    TEMP_DIR=$(mktemp -d /tmp/myscriptdir.XXXXXX)
    
  2. Clean Up After Yourself: Your mother doesn’t work here. If your application creates something in /tmp, it is your application’s responsibility to delete it when it’s done. Relying on the system’s boot-time cleanup is sloppy and can lead to filled-up filesystems if /tmp is on disk.

  3. For Services, Use /run (or its subdirectories): If you’re writing a daemon, its PID files and sockets belong in /run. The correct way to do this is to bundle a tmpfiles.d configuration snippet with your service. This tells the system to create the necessary directories with the correct permissions at boot time, before your service even starts.

    For example, if your daemon foobard needs a directory /run/foobard: Create a file /usr/lib/tmpfiles.d/foobard.conf:

    # Type Path        Mode UID  GID  Age Argument
    d     /run/foobard 0750 foobar foobar -
    

    Now, on boot, the system will create this directory for you, owned by the right user and group. Elegant.

The designers got this one mostly right. The split between user temp (/tmp) and system runtime (/run) is logical and solves real problems. The move to a RAM-based /run was a no-brainer for performance. The real questionable choice was letting the mess of /var/run and /var/lock exist for as long as it did. /run is a welcome dose of sanity. Use each directory for its intended purpose, and your system will be cleaner, faster, and a lot less weird.