| Tested on | RHEL 10.2 (Coughlan) |
|---|---|
| Package | systemd-257-23.el10_2.2.x86_64 |
| Applies to | RHEL, Rocky Linux, AlmaLinux, CentOS Stream, and other systemd-based distributions |
| Privilege | sudo or root for mount, /etc/fstab, and logind drop-ins |
| Scope | Change size limits on tmpfs mounts that matter for daily admin work: /dev/shm, /run, and per-user /run/user/$UID via RuntimeDirectorySize. Covers live remount and persistent /etc/fstab entries. Does not cover resizing disk-backed filesystems or cgroup v2 under /sys/fs/cgroup (cgroup2 on current RHEL, not tmpfs). |
| Related guides | df and du Check mounted filesystem type Mount a filesystem with a systemd mount unit List processes in Linux Linux check disk space |
tmpfs is a memory-backed filesystem that uses virtual memory. Its contents normally sit in RAM while they are in use, and pages may move to swap when swapping is enabled. The size= mount option is a maximum limit, not RAM reserved up front.
Applications such as databases may use /dev/shm for POSIX shared memory, while systemd keeps early-boot state under /run. You change those limits with /etc/fstab and mount -o remount, or with a systemd-logind drop-in for per-user /run/user/<uid> trees.
Quick answer: resize /dev/shm now or after reboot
To resize an existing tmpfs such as /dev/shm immediately:
sudo mount -o remount,size=2G /dev/shmVerify the new ceiling:
df -h /dev/shmFor a persistent /dev/shm limit, add size= to /etc/fstab:
tmpfs /dev/shm tmpfs defaults,nosuid,nodev,size=2G 0 0Check findmnt -no OPTIONS /dev/shm first and preserve any security-related mount options your system already uses (for example seclabel on SELinux hosts).
Then apply it without rebooting:
sudo mount -o remount /dev/shmsize= is a maximum limit, not memory Linux reserves immediately. tmpfs grows with the files you store there and may use swap when swapping is enabled.
/run/user/$UID is different: systemd-logind creates those mounts at login, so use RuntimeDirectorySize= instead of /etc/fstab.
What tmpfs size= and df Size actually mean
The Size column in df is the maximum capacity of that tmpfs, not the amount of RAM currently allocated to it. Used is closer to the data stored on the filesystem right now. tmpfs grows and shrinks with its contents rather than allocating the full configured limit at mount time.
Does reducing tmpfs size free RAM?
Usually not by itself. size=4G means the filesystem may grow up to 4 GB; it does not reserve 4 GB immediately. If df shows only a few megabytes under Used, shrinking the limit mainly reduces how much the tmpfs is allowed to consume later—it does not return three gigabytes of RAM just because you lowered Size from 4G to 1G.
List tmpfs mounts on the system
First check which paths are actually mounted as tmpfs and what limits they currently use. On a quiet system, df -hT filtered to tmpfs is enough; for mount options (including size=), use findmnt as in the mounted filesystem type guide.
List tmpfs filesystems and their reported sizes:
df -hT -t tmpfsSample output:
Filesystem Type Size Used Avail Use% Mounted on
tmpfs tmpfs 4.2G 84K 4.2G 1% /dev/shm
tmpfs tmpfs 1.7G 1.5M 1.7G 1% /run
tmpfs tmpfs 1.0M 0 1.0M 0% /run/credentials/systemd-journald.service
tmpfs tmpfs 858M 60K 858M 1% /run/user/1017
tmpfs tmpfs 858M 60K 858M 1% /run/user/1014
tmpfs tmpfs 858M 60K 858M 1% /run/user/1000
tmpfs tmpfs 858M 60K 858M 1% /run/user/1016For this guide, focus on /dev/shm and /run. The /run/user/... entries are managed differently and are covered later.
Inspect the mount point, filesystem type, and options for the paths you plan to change:
findmnt -T /dev/shmTARGET SOURCE FSTYPE OPTIONS
/dev/shm tmpfs tmpfs rw,nosuid,nodev,seclabel,inode64Check /run the same way so you can see the explicit size= the boot environment already applied:
findmnt -T /runTARGET SOURCE FSTYPE OPTIONS
/run tmpfs tmpfs rw,nosuid,nodev,seclabel,size=1755536k,nr_inodes=819200,mode=755,inode64On RHEL 10, /dev/shm had no explicit size= in mount options until I set one, so it defaulted to half of RAM (about 4.2G on this 8.4G host). /run already carried size=1755536k in the options string.
/etc/fstab on this system had no tmpfs lines before testing, yet df still listed /dev/shm and /run. systemd and the kernel mount them early; fstab is how you persist a custom size= across reboots.
Old RHEL 7-era examples sometimes show /sys/fs/cgroup as tmpfs. On current RHEL it is normally cgroup2, so tmpfs size= instructions do not apply:
findmnt -T /sys/fs/cgroupTARGET SOURCE FSTYPE OPTIONS
/sys/fs/cgroup cgroup2 cgroup2 rw,nosuid,nodev,noexec,relatime,seclabel,nsdelegate,memory_recursiveprotResize /dev/shm
Applications can use /dev/shm for POSIX shared memory through functions such as shm_open(). The tmpfs size= option accepts suffixes such as G, M, and % (see man tmpfs).
Make the limit persistent in /etc/fstab
Before you add an fstab entry, read the options your host already uses:
findmnt -no OPTIONS /dev/shmrw,nosuid,nodev,seclabel,inode64Preserve security-related options such as nosuid and nodev when you add size=. systemd treats /dev/shm as an API filesystem; fstab can override its mount parameters, and stripping options your workloads expect can break applications.
Back up fstab, then edit it:
sudo cp /etc/fstab /etc/fstab.bakExample line that keeps the options from this host and sets a 1G ceiling (match your findmnt output if it differs):
tmpfs /dev/shm tmpfs defaults,nosuid,nodev,size=1G 0 0After you save fstab, ask the kernel to mount everything listed there. mount -a does not catch every possible boot-time problem, but it can surface many malformed or unusable fstab entries before you reboot:
sudo mount -aApply the new size without rebooting
After fstab reflects the target size, remount in place:
sudo mount -o remount /dev/shmConfirm the reported size:
df -h /dev/shmFilesystem Size Used Avail Use% Mounted on
tmpfs 1.0G 84K 1.0G 1% /dev/shmYou can also set the size for a one-off test without fstab:
sudo mount -o remount,size=1G /dev/shmTo restore the default half-RAM ceiling for the current boot only:
sudo mount -o remount,size=50% /dev/shmIf you previously added size=1G to /etc/fstab, remove that custom size or change it to size=50% as well; otherwise the persistent setting returns at the next boot.
After the percentage-based remount, df should report about half of RAM again:
df -h /dev/shmFilesystem Size Used Avail Use% Mounted on
tmpfs 4.2G 84K 4.2G 1% /dev/shmremount only succeeds when usage fits under the new limit. If remount fails, stop workloads using the mount, unmount if your environment allows it, then mount again with the desired size=.
Resize /run
/var/run is a symlink to /run. /run holds runtime state for the operating system and services, including sockets, PID files, locks, and systemd-managed state. Unlike /dev/shm, resizing /run can affect core services, so do not choose an arbitrary smaller value just to save memory.
Persist size= in /etc/fstab
When no line exists yet, add one only after you understand the impact on your workload. Read the options your host already uses:
findmnt -no OPTIONS /runrw,nosuid,nodev,seclabel,size=1755536k,nr_inodes=819200,mode=755,inode64Example fstab line based on those options and a 900M ceiling (lab host only—preserve your own findmnt output and do not copy 900M as a recommended production size):
tmpfs /run tmpfs defaults,nosuid,nodev,mode=755,size=900M 0 0Back up fstab, add the line, run sudo mount -a, then sudo mount -o remount /run so the running mount matches fstab without rebooting.
Remount and verify (lab demonstration only)
The 900M value below is only a lab demonstration, not a recommended production size.
sudo mount -o remount,size=900M /runThe cap should show up immediately in df:
df -h /runFilesystem Size Used Avail Use% Mounted on
tmpfs 900M 1.5M 899M 1% /runReturn /run to the prior limit from mount options (this host used about 1.7G):
sudo mount -o remount,size=1755536k /runConfirm /run returned to the earlier size:
df -h /runFilesystem Size Used Avail Use% Mounted on
tmpfs 1.7G 1.5M 1.7G 1% /runIf you added a custom size= line to /etc/fstab for /run, remove or update that line when you want the previous persistent limit back.
Resize /run/user/$UID with systemd-logind
When a user logs in through a systemd/PAM-managed session, systemd-logind creates that user's runtime directory, usually /run/user/<UID>, and exposes it as $XDG_RUNTIME_DIR. This tree is separate from the main /run filesystem and has its own limit.
/run/user/<UID> mounts are created by systemd-logind rather than from static fstab entries. RuntimeDirectorySize= sets the runtime-directory limit for user sessions generally; it is not a per-UID setting.
Factory defaults on this host were still commented in the vendor file:
systemd-analyze cat-config systemd/logind.conf | grep -E '^#?RuntimeDirectory'#RuntimeDirectorySize=10%
#RuntimeDirectoryInodesMax=That default means about ten percent of physical RAM per user runtime directory, which matched the roughly 858M cap on existing sessions for 8.4G RAM.
Create a drop-in rather than editing /usr/lib/systemd/logind.conf directly:
sudo mkdir -p /etc/systemd/logind.conf.d# /etc/systemd/logind.conf.d/50-runtime-size.conf
[Login]
RuntimeDirectorySize=128MRestarting systemd-logind reloads the setting, but logind manages login sessions. Make this change from a session you can recover if necessary; a reboot is the simpler option when interrupting session management over SSH or on a graphical desktop is undesirable.
sudo systemctl restart systemd-logindExisting /run/user/<uid> mounts keep their old size until that user starts a fresh login session. New sessions pick up the drop-in limit.
I verified the new limit by logging in over SSH as a dedicated test user (first session after the drop-in was applied). On that host, 128M appeared as size=131072k in mount options:
echo "$XDG_RUNTIME_DIR"/run/user/1026Mount options should include size=131072k (128M with IEC sizing):
findmnt "$XDG_RUNTIME_DIR"TARGET SOURCE FSTYPE OPTIONS
/run/user/1026 tmpfs tmpfs rw,nosuid,nodev,relatime,seclabel,size=131072k,nr_inodes=219441,mode=700,uid=1026,gid=1027,inode64df should report the same 128M ceiling:
df -h "$XDG_RUNTIME_DIR"Filesystem Size Used Avail Use% Mounted on
tmpfs 128M 60K 128M 1% /run/user/1026On your own account, run the same three commands after a full logout and login:
echo "$XDG_RUNTIME_DIR"Look for size= in the options line for your new limit:
findmnt "$XDG_RUNTIME_DIR"The Size column should match the value you set in logind:
df -h "$XDG_RUNTIME_DIR"Remove the drop-in when you are finished testing so new sessions return to the distribution default.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
mount -o remount fails when shrinking |
Data or inode usage above the new size= |
Free space on the tmpfs, stop consumers, or unmount and remount with a larger limit |
| fstab change ignored after reboot | Wrong mount point, typo, or duplicate conflicting line | Run findmnt and grep tmpfs /etc/fstab; keep one authoritative line per mount point |
/run/user size unchanged after logind edit |
Active session still using the old tmpfs | Log the user out completely, or reboot; confirm with findmnt "$XDG_RUNTIME_DIR" |
Application still sees old /dev/shm size |
Remount not run after fstab edit | sudo mount -o remount /dev/shm and re-check with df -h /dev/shm |
df still lists /sys/fs/cgroup as tmpfs on old notes |
cgroup v1 layout on very old systems | On RHEL 8+, expect cgroup2; do not apply tmpfs size= there |
Summary
For /dev/shm and similar tmpfs mounts, use mount -o remount,size=... for an immediate change and /etc/fstab when the limit must survive reboot. Preserve existing mount options from findmnt when you edit fstab, validate with sudo mount -a, and remember that remounting to size=50% only affects the running mount until you align fstab.
/run/user/$UID is different because systemd-logind creates it at login; change that limit with RuntimeDirectorySize= in a logind drop-in, restart logind when you are ready, and start a new session before you expect the smaller or larger cap in findmnt.
Remember that tmpfs Size in df is only a ceiling. Reducing a 4 GB tmpfs to 1 GB does not free 3 GB unless that space was actually in use. Per-user runtime limits behaved that way on the lab host: after RuntimeDirectorySize=128M, a fresh SSH login showed a 128M tmpfs at /run/user/1026.
References
- tmpfs(5) — mount options including
size=andnr_inodes - logind.conf(5) —
RuntimeDirectorySizeandRuntimeDirectoryInodesMax - Red Hat: How to work with /dev/shm
- Red Hat: Purpose of /run/user tmpfs
Frequently Asked Questions
What is the default size of /dev/shm on RHEL?
When no size= appears in mount options, tmpfs on /dev/shm typically defaults to half of physical RAM. On the 8.4G lab host that produced about 4.2G until a size=1G remount or fstab entry was applied.
Can I set tmpfs size as a percentage of RAM?
Yes. The tmpfs size= option accepts values such as size=50% or size=10%, using IEC byte suffixes for absolute sizes. Percentages are relative to physical memory on the host.
Do I need an /etc/fstab entry for every tmpfs in df?
No. Many tmpfs mounts are created by systemd or at login. Use fstab (or a systemd mount unit) when you need a persistent custom limit on paths such as /dev/shm or /run. Per-user /run/user/$UID limits come from logind, not fstab.
Is a full reboot required after changing RuntimeDirectorySize?
Not always. Restarting systemd-logind loads the new setting, but each user must end their session and log in again before their personal /run/user/$UID tmpfs is recreated with the new limit.

