{"id":2177,"date":"2026-04-11T09:39:24","date_gmt":"2026-04-11T06:39:24","guid":{"rendered":"https:\/\/computingforgeeks.com\/?p=2177"},"modified":"2026-04-11T09:40:08","modified_gmt":"2026-04-11T06:40:08","slug":"mount-tmp-separate","status":"publish","type":"post","link":"https:\/\/computingforgeeks.com\/mount-tmp-separate\/","title":{"rendered":"Configure \/tmp on a Separate Partition or tmpfs on Linux"},"content":{"rendered":"\n<p>Putting <code>\/tmp<\/code> on its own filesystem isolates temporary files from the root volume and lets you mount it with options the rest of the system shouldn&#8217;t have. The classic recipe uses a dedicated disk partition. The modern recipe uses a tmpfs (RAM-backed) mount managed by systemd. Both are valid, and each is the right choice in a different situation. This guide walks through both on Ubuntu 24.04 LTS (following an <a href=\"https:\/\/computingforgeeks.com\/upgrade-ubuntu-22-04-to-24-04\/\" target=\"_blank\" rel=\"noreferrer noopener\">in-place upgrade from 22.04<\/a>) and Debian 13.<\/p>\n\n\n\n<p>The operational benefits are the same either way: crashes, runaway processes, or hostile code dumping data into <code>\/tmp<\/code> can never fill the root filesystem, the mount carries <code>nosuid<\/code>, <code>nodev<\/code>, and <code>noexec<\/code> so attackers can&#8217;t stage executables there, and the directory is cleared on every boot without you needing to write a cleanup script.<\/p>\n\n\n\n<p><em>Verified: <strong>April 2026<\/strong> on Ubuntu 24.04.4 LTS with kernel 6.8.0-101-generic using systemd&#8217;s <code>tmp.mount<\/code> unit<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Approach 1: Mount \/tmp as tmpfs (recommended for most servers)<\/h2>\n\n\n\n<p>tmpfs stores everything under <code>\/tmp<\/code> in RAM, falling back to swap if pressure forces it. It&#8217;s fast, it clears itself on every boot automatically, and there&#8217;s no disk partition to plan. The only cost is that files in <code>\/tmp<\/code> now compete for RAM with everything else.<\/p>\n\n\n\n<p>Ubuntu 24.04 does not enable <code>tmp.mount<\/code> by default. Check whether a unit exists:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>findmnt \/tmp\nsystemctl cat tmp.mount 2>&amp;1 | head -5<\/code><\/pre>\n\n\n\n<p>On a stock 24.04 cloud image you&#8217;ll see that <code>\/tmp<\/code> is not a separate mount and there&#8217;s no unit file yet:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>No files found for tmp.mount.<\/code><\/pre>\n\n\n\n<p>Drop a unit file into <code>\/etc\/systemd\/system\/tmp.mount<\/code> and enable it. The unit below mirrors the one shipped on systems that do enable it by default, sized to use up to half the physical memory:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>sudo vi \/etc\/systemd\/system\/tmp.mount<\/code><\/pre>\n\n\n\n<p>Paste in the full unit:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>[Unit]\nDescription=Temporary Directory (\/tmp)\nDocumentation=man:hier(7) man:tmpfs(5)\nConditionPathIsSymbolicLink=!\/tmp\nDefaultDependencies=no\nConflicts=umount.target\nBefore=local-fs.target umount.target\nAfter=swap.target\n\n[Mount]\nWhat=tmpfs\nWhere=\/tmp\nType=tmpfs\nOptions=mode=1777,strictatime,nosuid,nodev,size=50%,nr_inodes=1m\n\n[Install]\nWantedBy=local-fs.target<\/code><\/pre>\n\n\n\n<p>Reload systemd and enable the mount. The unit activates immediately and persists across reboots:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>sudo systemctl daemon-reload\nsudo systemctl enable --now tmp.mount<\/code><\/pre>\n\n\n\n<p>Confirm the mount is active and check the options:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>findmnt \/tmp\ndf -hT \/tmp<\/code><\/pre>\n\n\n\n<p>The output reports the filesystem type as tmpfs and the size is capped at half the machine&#8217;s RAM:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>TARGET SOURCE FSTYPE OPTIONS\n\/tmp   tmpfs  tmpfs  rw,nosuid,nodev,size=1007612k,nr_inodes=1048576,inode64\nFilesystem     Type   Size  Used Avail Use% Mounted on\ntmpfs          tmpfs  984M     0  984M   0% \/tmp<\/code><\/pre>\n\n\n\n<p><code>nosuid<\/code> stops set-UID binaries from running with their owner&#8217;s privileges, <code>nodev<\/code> blocks device node creation, and <code>size=50%<\/code> caps the mount at half the physical RAM. On a 2 GB VM that&#8217;s about 984 MB, as shown above. The remaining half of RAM stays available for applications even if <code>\/tmp<\/code> fills up.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">When to use a real disk partition instead<\/h2>\n\n\n\n<p>tmpfs is the right default for almost every server. Pick a real partition instead when:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>You run software that writes genuinely large temporary files (ImageMagick, FFmpeg, Spark local-dir, Hadoop scratch space). tmpfs sizes up to RAM so a 40 GB temp file is not going to fit.<\/li>\n<li>RAM is precious on the host and you don&#8217;t want temp files competing with applications.<\/li>\n<li>You need persistent <code>\/tmp<\/code> across reboots (rare but not unheard of for some batch pipelines).<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Approach 2: Use a dedicated disk partition<\/h2>\n\n\n\n<p>Create a partition (or LV) for <code>\/tmp<\/code>, format it, and mount it with the hardening options. Assume <code>\/dev\/sdb1<\/code> is the new partition of 5-10 GB:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>sudo mkfs.ext4 -L tmp \/dev\/sdb1<\/code><\/pre>\n\n\n\n<p>Move the current contents of <code>\/tmp<\/code> out of the way and mount the new partition:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>sudo systemctl isolate rescue.target\nsudo mv \/tmp \/tmp.old\nsudo mkdir \/tmp\nsudo chmod 1777 \/tmp\nsudo mount -o defaults,nosuid,nodev,noexec \/dev\/sdb1 \/tmp<\/code><\/pre>\n\n\n\n<p>The <code>1777<\/code> mode sets the sticky bit so users can only delete their own files in <code>\/tmp<\/code>, even though the directory is world-writable. This is the same behaviour you want for a shared temporary area.<\/p>\n\n\n\n<p>Make the mount persistent by adding it to <code>\/etc\/fstab<\/code>. Use the <code>LABEL=<\/code> syntax so the mount survives device renames:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>LABEL=tmp  \/tmp  ext4  defaults,nosuid,nodev,noexec  0  2<\/code><\/pre>\n\n\n\n<p>Reboot and confirm the mount comes back cleanly:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>sudo reboot\n# after reconnecting\nfindmnt \/tmp\ndf -hT \/tmp<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">A note on noexec<\/h2>\n\n\n\n<p>Adding <code>noexec<\/code> to <code>\/tmp<\/code> is a common hardening move, but it breaks software that uses <code>\/tmp<\/code> for genuine execution. The notable example is <code>dnf<\/code> and <code>apt<\/code> triggers that run scriptlets from scratch directories, and some Python virtualenv tools that build native extensions in temp directories. If package operations start failing after you enable <code>noexec<\/code>, take it off and leave just <code>nosuid<\/code> and <code>nodev<\/code>, which cover the most common privilege-escalation vectors without breaking package managers.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Cleaning up the old \/tmp contents<\/h2>\n\n\n\n<p>If you moved the old <code>\/tmp<\/code> to <code>\/tmp.old<\/code> during the disk-partition flow, remember to delete it once you&#8217;ve confirmed the new mount is working:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>sudo rm -rf \/tmp.old<\/code><\/pre>\n\n\n\n<p>There&#8217;s nothing in <code>\/tmp<\/code> that should survive a reboot anyway, so deleting it is safe. The systemd <code>systemd-tmpfiles-clean.timer<\/code> takes care of ongoing cleanup of old files per the rules in <code>\/usr\/lib\/tmpfiles.d\/tmp.conf<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Verifying it works<\/h2>\n\n\n\n<p>The final check is to make sure <code>nosuid<\/code> is actually enforced. Drop a setuid binary into <code>\/tmp<\/code> and try to run it:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>cp \/usr\/bin\/passwd \/tmp\/passwd-test\nls -la \/tmp\/passwd-test\n\/tmp\/passwd-test --help<\/code><\/pre>\n\n\n\n<p>The binary copy keeps its setuid bit in the listing but <code>\/tmp<\/code>&#8216;s <code>nosuid<\/code> option means the kernel strips it at execution time. Running the copy no longer gains root privileges even though the mode bit is still there. Remove the test file when you&#8217;re done.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wrap up<\/h2>\n\n\n\n<p>Separating <code>\/tmp<\/code> from <code>\/<\/code> is a 10-minute job that makes your server meaningfully more resilient to both accidental fill-ups and hostile exploit attempts. For more hardening see our <a href=\"https:\/\/computingforgeeks.com\/top-rocky-linux-10-post-installation-tips-and-tricks\/\" target=\"_blank\" rel=\"noreferrer noopener\">Rocky Linux 10 post-install tips<\/a> which pairs well with SELinux enforcing, our <a href=\"https:\/\/computingforgeeks.com\/protect-grub-password-linux\/\" target=\"_blank\" rel=\"noreferrer noopener\">GRUB password guide<\/a> for the boot-time side, and the <a href=\"https:\/\/computingforgeeks.com\/systemctl-commands-linux\/\" target=\"_blank\" rel=\"noreferrer noopener\">systemctl reference<\/a> for managing the new <code>tmp.mount<\/code> unit. If you&#8217;re planning a larger layout with <code>\/var<\/code>, <code>\/home<\/code>, and <code>\/srv<\/code> on their own filesystems, consider <a href=\"https:\/\/computingforgeeks.com\/btrfs-linux\/\" target=\"_blank\" rel=\"noreferrer noopener\">BtrFS with subvolumes<\/a> instead of classic partitions.<\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>Putting \/tmp on its own filesystem isolates temporary files from the root volume and lets you mount it with options the rest of the system shouldn&#8217;t have. The classic recipe uses a dedicated disk partition. The modern recipe uses a tmpfs (RAM-backed) mount managed by systemd. Both are valid, and each is the right choice &#8230; <a title=\"Configure \/tmp on a Separate Partition or tmpfs on Linux\" class=\"read-more\" href=\"https:\/\/computingforgeeks.com\/mount-tmp-separate\/\" aria-label=\"Read more about Configure \/tmp on a Separate Partition or tmpfs on Linux\">Read more<\/a><\/p>\n","protected":false},"author":3,"featured_media":165713,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26,299,50,35910,75,81],"tags":[384,37979,386,387,385,176],"cfg_series":[],"class_list":["post-2177","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-debian","category-how-to","category-linux-tutorials","category-rocky-linux","category-security","category-ubuntu","tag-tmp","tag-tmp-on-a-separate-partition","tag-dd","tag-fallocate","tag-tmpfs","tag-xfs"],"_links":{"self":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/2177","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/comments?post=2177"}],"version-history":[{"count":2,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/2177\/revisions"}],"predecessor-version":[{"id":165734,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/2177\/revisions\/165734"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/media\/165713"}],"wp:attachment":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/media?parent=2177"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/categories?post=2177"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/tags?post=2177"},{"taxonomy":"cfg_series","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/cfg_series?post=2177"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}