tmpfs Temporary Filesystems Guide
A free Linux device drivers course lesson on RAM-backed storage for volatile embedded data
Not every file your system creates deserves to survive a reboot, and on flash-backed embedded storage, every avoidable write is a write that did not wear out a flash cell. This lesson in our free Linux device drivers course covers tmpfs — the RAM-backed filesystem that keeps short-lived, high-churn files off permanent storage entirely — and shows exactly how production builds like Buildroot and the Yocto Project use it to protect flash endurance.
Keywords covered in this lesson
What You Will Learn
- Why RAM-based filesystems exist and how they differ from a regular RAM disk
- How to mount and size-limit tmpfs on the latest stable kernel
- How Buildroot and the Yocto Project route volatile directories through tmpfs
- How to write a small kernel module that exercises tmpfs directly
- When tmpfs is the wrong tool, and what the safer alternatives are
Prerequisites
This lesson assumes the flash filesystem background from earlier in this free Linux device drivers course — in particular, why frequent small writes are expensive on flash media, covered in the F2FS and squashfs lessons.
Why tmpfs Exists
Plenty of files on a running Linux system have no reason to exist after the next reboot: PID files, lock files, sockets, caches, and — on many embedded devices — rotating log files that get regenerated from scratch at every boot anyway. Writing these to your root filesystem accomplishes nothing except consuming flash write cycles and slowing the system down with unnecessary I/O.
tmpfs solves this by backing a filesystem entirely with the kernel’s page cache and swap, rather than any block device. Files written to a tmpfs mount live in RAM (and can be pushed to swap under memory pressure, if swap is configured) and vanish the moment the filesystem is unmounted or the system reboots.
tmpfs Versus A RAM Disk
It is worth being precise here because the two are often confused. An old-style RAM disk (/dev/ram0) pre-allocates a fixed block of memory and then has an ordinary filesystem (like ext2) formatted onto it — the memory is reserved up front whether you use it or not. tmpfs is fundamentally different: it grows and shrinks dynamically as files are created and deleted, and unused tmpfs pages can be reclaimed by the kernel’s normal memory management just like any other page cache, making it far more memory-efficient for workloads where usage varies over time.
Mounting And Sizing tmpfs
Because there is no backing device, tmpfs takes a placeholder string instead of a device path when mounted. The default maximum size is half of physical RAM, which on a memory-constrained embedded board can be dangerously large — an unbounded log write loop could theoretically consume half your device’s RAM before anything else notices. Always cap it explicitly with the size mount option.
# mount tmpfs with an explicit 4 MiB cap
mount -t tmpfs -o size=4m tmp_files /tmp
# check current usage
df -h /tmp
# size can also be given as a percentage of RAM
mount -t tmpfs -o size=10% tmp_files /var/log
Two more mount options matter for embedded systems: nr_inodes caps the number of files tmpfs will allow regardless of their total size (protecting against an attacker or bug creating millions of zero-byte files to exhaust kernel memory), and mode/uid/gid set the ownership of the mount root the way you would for any filesystem.
mount -t tmpfs -o size=4m,nr_inodes=1024,mode=1777 tmp_files /tmp
How Buildroot And Yocto Use tmpfs
Both major embedded build systems route the classic set of volatile directories through tmpfs so that a read-only root filesystem (see the next lesson) still has somewhere to put runtime state. Buildroot’s default init scripts create tmpfs mounts and then symlink the traditionally writable directories onto them:
/var/cache -> /tmp
/var/lock -> /tmp
/var/log -> /tmp
/var/run -> /tmp
/var/spool -> /tmp
/var/tmp -> /tmp
The Yocto Project takes a slightly different structural approach, mounting a dedicated /run and /var/volatile as tmpfs and pointing the same set of directories at those mounts instead of collapsing everything into a single /tmp:
/tmp -> /var/tmp
/var/lock -> /run/lock
/var/log -> /var/volatile/log
/var/run -> /run
/var/tmp -> /var/volatile/tmp
Either pattern accomplishes the same goal: applications keep writing to the paths they expect (/var/log/messages, /var/run/myapp.pid), while none of those writes ever touch flash.
A Small Demo: Exercising tmpfs From A Kernel Module
Here is an original, minimal driver, ep_tmpfs_scratch, that creates a private tmpfs mount on module load, writes a status blob into it on every read of a sysfs attribute, and tears the mount down cleanly on unload — useful when a driver needs scratch storage that must never survive a reboot (for example, a staging buffer for firmware downloads in progress).
// ep_tmpfs_scratch.c - creates a private tmpfs mount for driver scratch data
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs_context.h>
#include <linux/mount.h>
#include <linux/namei.h>
static struct vfsmount *ep_mnt;
static int __init ep_tmpfs_scratch_init(void)
{
ep_mnt = kern_mount(&shmem_fs_type);
if (IS_ERR(ep_mnt)) {
pr_err("ep_tmpfs_scratch: failed to mount tmpfs, err=%ld\n",
PTR_ERR(ep_mnt));
return PTR_ERR(ep_mnt);
}
pr_info("ep_tmpfs_scratch: private tmpfs scratch area ready\n");
return 0;
}
static void __exit ep_tmpfs_scratch_exit(void)
{
if (!IS_ERR_OR_NULL(ep_mnt))
kern_unmount(ep_mnt);
pr_info("ep_tmpfs_scratch: scratch area torn down, memory reclaimed\n");
}
module_init(ep_tmpfs_scratch_init);
module_exit(ep_tmpfs_scratch_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("EmbeddedPathashala demo: private in-kernel tmpfs scratch mount");
$ insmod ep_tmpfs_scratch.ko
$ dmesg | tail -1
[ 4.102331] ep_tmpfs_scratch: private tmpfs scratch area ready
$ rmmod ep_tmpfs_scratch
$ dmesg | tail -1
[ 12.559981] ep_tmpfs_scratch: scratch area torn down, memory reclaimed
Real-World Use Cases
| Directory | Why tmpfs fits |
|---|---|
| /tmp | Short-lived application scratch files, sockets, lock files |
| /var/log | High write-frequency logs that would otherwise wear out flash quickly |
| /var/run or /run | PID files and runtime state that is meaningless after a reboot anyway |
| Firmware download staging buffer | Large temporary data during an OTA update that should never be written to flash if the update is cancelled |
Common Mistakes And Troubleshooting
- Mounting tmpfs without a size cap. The default half-of-RAM ceiling is far too generous for most embedded boards; always pass
size=explicitly. - Putting genuinely persistent data on tmpfs. Configuration files, calibration data, and anything that must survive a power cycle belongs on real storage, not tmpfs — this mistake is easy to make when copying someone else’s init script without reading it.
- Forgetting that tmpfs content counts against total system RAM. On a 128 MB board, an unbounded log directory really can starve your application of memory; monitor tmpfs usage the same way you monitor heap usage.
- Assuming tmpfs persists across a kernel panic and automatic reboot. It does not — any data you need after a crash must already be on non-volatile storage.
Best Practices
- Always set an explicit
sizeand, where the risk of runaway file creation exists, annr_inodeslimit. - Follow the Buildroot or Yocto symlink pattern rather than inventing your own — it is well tested and keeps application expectations about standard paths intact.
- Periodically flush anything genuinely important out of tmpfs to real storage (or a remote log collector) rather than treating tmpfs logs as a permanent record.
Performance And Security Considerations
tmpfs access is effectively as fast as memory access, since there is no block I/O involved at all — this is why build systems also use tmpfs-backed directories to speed up compilation on capable hardware. On the security side, remember that tmpfs content can be swapped out to a real swap device if one is configured, so sensitive short-lived data (such as decrypted firmware images) is not automatically safe from ending up on non-volatile storage; disable swap or use mlock-style protections if that matters for your threat model.
Summary And Key Takeaways
- tmpfs is a dynamically-sized, RAM-backed filesystem, distinct from a fixed-size classic RAM disk.
- It keeps volatile, high-churn files off flash storage entirely, directly protecting flash endurance.
- Always mount it with an explicit
sizecap — the kernel default of half of RAM is too permissive for most embedded targets. - Buildroot and the Yocto Project both symlink the standard volatile directories (
/tmp,/var/log,/var/run, and friends) onto tmpfs mounts, just with slightly different directory layouts.
Conclusion
tmpfs is one of the simplest tools covered in this free Linux device drivers course, but it quietly does a huge amount of work protecting flash-based embedded systems from unnecessary wear. Combined with the read-only root filesystem techniques in the next lesson, tmpfs is what makes it possible for a device to log heavily, run applications that expect a writable /tmp, and still ship with a root filesystem that never needs to be written to at all in normal operation.
FAQ
Does tmpfs survive a reboot?
No. All tmpfs content is stored in RAM and is lost on unmount, power loss, or reboot.
What is the default maximum size of a tmpfs mount?
Half of the system’s physical RAM, unless overridden with the size mount option — which should always be set explicitly on embedded boards.
Is tmpfs the same as a RAM disk?
No. A RAM disk pre-allocates a fixed block of memory formatted with an ordinary filesystem, while tmpfs dynamically grows and shrinks and participates in normal kernel page reclaim.
Can tmpfs data end up on a swap device?
Yes, if swap is configured on the system, tmpfs pages can be swapped out under memory pressure, which matters if you are storing sensitive short-lived data.
Why do Buildroot and Yocto both use tmpfs for /var/log?
Log files are written frequently and have no long-term value on most embedded devices, so keeping them in RAM avoids unnecessary flash wear while still giving applications a normal-looking /var/log path.
Continue the free Linux device drivers course
Next up: making the entire root filesystem read-only for maximum reliability.
Next Lesson Course Index
2 Comments