Azure temp disk as swap with systemd recreation
Setting up reboot-resilient swap on an Azure VM after resizing to a SKU with a local NVMe temp disk to prevent future OOMs
Azure VMs with a d suffix SKU (e.g. D4pds_v5) include a local NVMe temp disk that auto-mounts at /mnt via cloud-inits /dev/disk/cloud/azure_resource-part1 symlink. It is wiped on every deallocation/maintenance event but is the right substrate for swap (2000+ MB/s, sub-millisecond latency, no extra cost). The reboot-resilient pattern: do not put the swap entry in /etc/fstab (the temp disk path is unstable), instead create a oneshot systemd service with After=local-fs.target and ConditionPathExists=/mnt + ConditionPathExists=!/mnt/swapfile that runs fallocate, mkswap, swapon on each boot. This survives both VM reboots and Azure-side maintenance events. Two surprises worth noting: (1) Ubuntu cloud-init Azure images do NOT use tmpfs for /tmp by default — /tmp is on the OS disk ext4 root, so a memory-pressure diagnosis that blames tmpfs filling RAM is wrong on these images; (2) Azure VM resize across SKU families (B-series to D-series) requires explicit az vm deallocate first, but the data disks remount correctly via UUID in /etc/fstab through the family change — container data is preserved intact.
When prepping a homelab VM to absorb memory-bursty workloads (Whisper transcription, LLM inference, large builds), prefer a SKU with built-in temp disk over a SKU without — the +$5-10/mo gets you a free swap substrate. Use the systemd-oneshot-on-boot pattern for the swap file (not fstab) because temp disk gets wiped on dealloc. And before assuming /tmp is RAM-backed, check df -T /tmp on the actual image — Azure Ubuntu has it on disk, not tmpfs.