Setting up Hibernate on Linux #

My Framework 13 laptop has an issue where the battery drains very quickly, even when sleeping.

This seems to be a known issue with Framework laptops. Since I often just use my work computer during the weekdays, the laptop is dead before I can use it again.

Reviewing sleep states available #

In Linux, there are specific levels of sleep states that can be used:

  • freeze (S0ix)
  • standby (S1): rarely used in modern systems.
  • mem (S3): hardware is powered off except ram.
  • disk (S4): hibernate. system state is moved to disk.

Checking power states available #

First I checked what was available with:

cat /sys/power/state
# freeze mem

So freeze and mem are available.

Configuring hibernate with LUKS #

I like to use LUKS (Linux Unified Key Setup) to encrypt my drives. To do so with hibernate, the following workflow is required:

  1. use the bootloader to loader the initramfs
  2. have the initramfs decrypt the LVM volume that contains the main partition as well as swap.
  3. the initramfs detects that the swap partition is available and restores the system state from it, if a hibernate image is found.

Configuring the partitions #

The final partition structure will look something like:

  • /dev/nvme0n1p1 (EFI / bootloader)
  • /dev/nvme0n1p2 Linux filesystem partition: an unencrypted boot partition that contains the OS needed to perform the decryption of the encrypted drive.
  • /dev/nvme0n1p3 Linux filesystem partition: the encrypted disk partition.
    • /dev/mapper/dm-crypt-0
      • /dev/mapper/ubuntu–vg-ubuntu–lv: the actual OS.
      • /dev/mapper/swap: the swap space that the partition will hibernate to.

Steps #

NOTE: these were with my install of ubuntu 25.10. YMMV.

Resize the partition and make a swap partition #

  1. use a live USB so I can modify the partition
  2. open the luks partition: sudo cryptsetup open ${partition} ${lvm-volume-name}
  3. reduce the size: sudo lvreduce -r -L -128G /dev/mapper/${root-lvm-partition}
  4. create the volume: sudo lvcreate -L 128G -n swap ${lvm-volume-name}
  5. format as swap: sudo mkswap /dev/mapper/${swap-lvm-partition}

Make the partition swap #

This ensures the swap partition is available on boot to suspend to.

When back into the OS:

  1. sudo swapon /dev/mapper/${swap-partition-name}
  2. Update /etc/fstab to mount the swap on boot:
/dev/mapper/{swap-partition-name} none swap sw 0 0

set the swap partition as a hibernate partition #

This tells the kernel where to look for the hibernate image when resuming.

  1. modify GRUB_CMDLINE_LINUX_DEFAULT in /etc/grub/config with:
resume=/dev/mapper/{swap-partition-name}
  1. run sudo update-grub

enable hibernate in the linux kernel image #

This is required for the initramfs to know how to restore from the hibernate image.

  1. create file /etc/initramfs-tools/conf.d/resume with:
RESUME=/dev/mapper/{swap-partition-name}
  1. run sudo update-initramfs -u -k all

disable secure boot #

The last step is to disable secure boot in the BIOS.

Theoretically there is a way to sign the hibernated image with a TPM (trusted partner module) or a MOK (machine-only-key), but I didn’t want to have to re-encrypt my volume.

Conclusion #

Success! After the above, I can now hibernate my laptop.

Even with my 64GB of RAM, the hibernate / restore has been pretty quick so far: roughly 20 seconds at most to come back up from a full hibernate. Good solution for laptops I use once in 24 hours.