Skip to content

Instantly share code, notes, and snippets.

@enmyj
Last active December 7, 2025 18:11
Show Gist options
  • Select an option

  • Save enmyj/4f7314e6597153be16c1692eda4cbd18 to your computer and use it in GitHub Desktop.

Select an option

Save enmyj/4f7314e6597153be16c1692eda4cbd18 to your computer and use it in GitHub Desktop.
suspend-then-hibernate

Suspend-Then-Hibernate Setup for Framework Laptop (CachyOS)

This guide configures suspend-then-hibernate on CachyOS with btrfs, GRUB, and zram. The system will suspend to RAM when you close the lid, then automatically hibernate to disk after 2 hours.

System specs: 32GB RAM, btrfs filesystem, GRUB bootloader, existing zram


Step 1: Create Swap File

Create a 38GB swap file for hibernation (RAM + sqrt(RAM)):

# Create swap directory if it doesn't exist
sudo mkdir -p /swap

# Create swap file on btrfs
sudo btrfs filesystem mkswapfile --size 38G /swap/swapfile

# If the above command doesn't work (older btrfs-progs), use this method:
sudo truncate -s 0 /swap/swapfile
sudo chattr +C /swap/swapfile
sudo fallocate -l 38G /swap/swapfile
sudo chmod 600 /swap/swapfile
sudo mkswap /swap/swapfile

Step 2: Enable Swap File

# Enable the swap file
sudo swapon /swap/swapfile

# Add to fstab for automatic mounting at boot
echo '/swap/swapfile none swap defaults 0 0' | sudo tee -a /etc/fstab

# Verify swap is active
swapon --show

Step 3: Get Resume Parameters

You need two values for GRUB configuration:

# Get the UUID of your root partition
sudo findmnt -no UUID -T /swap/swapfile

# Get the physical offset of the swap file
sudo btrfs inspect-internal map-swapfile -r /swap/swapfile

Write down both values - you'll need them in the next step.

Step 4: Configure GRUB

# Edit GRUB configuration
sudo vim /etc/default/grub

Find the line starting with GRUB_CMDLINE_LINUX_DEFAULT and add the resume parameters (replace with your actual UUID and offset):

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash resume=UUID=your-uuid-here resume_offset=your-offset-here"

Example:

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash resume=UUID=12345678-1234-1234-1234-123456789abc resume_offset=123456"

Regenerate GRUB configuration:

sudo grub-mkconfig -o /boot/grub/grub.cfg

Step 5: Configure initramfs

# Edit mkinitcpio configuration
sudo vim /etc/mkinitcpio.conf

Find the HOOKS line and add sd-resume before filesystems. Your HOOKS line should look like:

HOOKS=(base systemd autodetect microcode kms modconf block keyboard sd-vconsole plymouth sd-resume filesystems)

Regenerate initramfs:

sudo mkinitcpio -P

Step 6: Configure Sleep Delay

Create systemd sleep configuration to set the 2-hour delay:

sudo vim /etc/systemd/sleep.conf

Add these lines:

[Sleep]
HibernateDelaySec=2h

Step 7: Configure Lid Switch Behavior

# Edit logind configuration
sudo vim /etc/systemd/logind.conf

Find and uncomment (remove #) these lines, or add them if they don't exist:

HandleLidSwitch=suspend-then-hibernate
HandleLidSwitchExternalPower=suspend-then-hibernate

Step 8: Apply Changes

# Restart logind service
sudo systemctl restart systemd-logind

# Reboot to apply all changes
sudo reboot

Step 9: Test Your Setup

After rebooting, verify everything works:

# Verify resume parameters are loaded
cat /proc/cmdline | grep resume

# Check swap is active
swapon --show

# Test hibernation manually
sudo systemctl hibernate

After confirming hibernation works, test suspend-then-hibernate:

sudo systemctl suspend-then-hibernate

Finally, test by closing your laptop lid and leaving it for 2+ hours.


Troubleshooting

Check system logs

journalctl -b -u systemd-suspend-then-hibernate
journalctl -b | grep -i hibernate

Verify resume parameters

cat /proc/cmdline

Should show resume=UUID=... and resume_offset=...

Check swap priority

cat /proc/swaps

Your zram and swap file should both be listed.


Notes

  • zram compatibility: Your existing zram will continue working. The kernel uses zram for regular swapping and the swap file specifically for hibernation.
  • Battery drain: During the first 2 hours, the system uses suspend-to-RAM (very low power). After 2 hours, it hibernates to disk (zero power).
  • Wake behavior: Opening the lid before 2 hours wakes instantly from RAM. After 2 hours, it resumes from disk (slightly slower but still quick).

Reverting Changes

If you need to undo this setup:

# Disable swap file
sudo swapoff /swap/swapfile

# Remove from fstab
sudo vim /etc/fstab  # Delete the /swap/swapfile line

# Remove swap file
sudo rm /swap/swapfile

# Restore logind settings
sudo vim /etc/systemd/logind.conf  # Change back to suspend

# Remove sleep configuration
sudo rm /etc/systemd/sleep.conf

# Remove resume from GRUB
sudo vim /etc/default/grub  # Remove resume parameters
sudo grub-mkconfig -o /boot/grub/grub.cfg

# Remove sd-resume hook
sudo vim /etc/mkinitcpio.conf  # Remove sd-resume
sudo mkinitcpio -P

# Reboot
sudo reboot

Suspend-Then-Hibernate Setup for Fedora 42

This guide configures suspend-then-hibernate on Fedora 42 with btrfs, GRUB, dracut, and zram. The system will suspend to RAM when you close the lid, then automatically hibernate to disk after 2 hours.

System specs: 32GB RAM, btrfs filesystem, GRUB bootloader, dracut initramfs, existing zram


Step 1: Create Swap File

Create a 38GB swap file for hibernation (RAM + sqrt(RAM)):

# Create swap subvolume
sudo btrfs subvolume create /var/swap

# Create swap file on btrfs
sudo btrfs filesystem mkswapfile --size 38G --uuid clear /var/swap/swapfile

# If the above command doesn't work (older btrfs-progs), use this method:
sudo truncate -s 0 /var/swap/swapfile
sudo chattr +C /var/swap/swapfile
sudo fallocate -l 38G /var/swap/swapfile
sudo chmod 600 /var/swap/swapfile
sudo mkswap /var/swap/swapfile

Step 2: Enable the Swap File

# Enable swap
sudo swapon /var/swap/swapfile

# Add to fstab for automatic mounting at boot
echo '/var/swap/swapfile none swap defaults 0 0' | sudo tee -a /etc/fstab

# Verify swap is active
swapon --show

Step 3: Configure SELinux (Fedora-specific)

Fedora uses SELinux, which needs to know about the swap file:

# Set correct SELinux context for swap file
sudo semanage fcontext --add --type swapfile_t /var/swap/swapfile
sudo restorecon -RF /var/swap

Step 4: Get Resume Parameters

You need two values for GRUB configuration:

# Get the UUID of your root partition
sudo findmnt -no UUID -T /var/swap/swapfile

# Get the physical offset of the swap file
sudo btrfs inspect-internal map-swapfile -r /var/swap/swapfile

Write down both values - you'll need them in the next step.

Step 5: Configure GRUB

Fedora uses grubby to manage kernel parameters. Add resume parameters (replace with your actual UUID and offset):

# Add resume parameters to all kernels
sudo grubby --args="resume=UUID=your-uuid-here resume_offset=your-offset-here" --update-kernel=ALL

# Verify the parameters were added
sudo grubby --info=ALL | grep args

Example:

sudo grubby --args="resume=UUID=12345678-1234-1234-1234-123456789abc resume_offset=123456" --update-kernel=ALL

Step 6: Configure Dracut (initramfs)

Add the resume module to dracut:

# Create dracut configuration for resume
echo 'add_dracutmodules+=" resume "' | sudo tee /etc/dracut.conf.d/resume.conf

Regenerate initramfs for all kernels:

sudo dracut --regenerate-all --force

Step 7: Configure Sleep Delay

Create systemd sleep configuration to set the 2-hour delay:

sudo vim /etc/systemd/sleep.conf

Add these lines:

[Sleep]
HibernateDelaySec=2h

Step 8: Configure Lid Switch Behavior

# Edit logind configuration
sudo vim /etc/systemd/logind.conf

Find and uncomment (remove #) these lines, or add them if they don't exist:

HandleLidSwitch=suspend-then-hibernate
HandleLidSwitchExternalPower=suspend-then-hibernate

Step 9: Apply Changes

# Restart logind service
sudo systemctl restart systemd-logind

# Reboot to apply all changes
sudo reboot

Step 10: Test Your Setup

After rebooting, verify everything works:

# Verify resume parameters are loaded
cat /proc/cmdline | grep resume

# Check swap is active
swapon --show

# Verify dracut has resume module
sudo lsinitrd -m | grep resume

# Test hibernation manually
sudo systemctl hibernate

After confirming hibernation works, test suspend-then-hibernate:

sudo systemctl suspend-then-hibernate

Finally, test by closing your laptop lid and leaving it for 2+ hours.


Troubleshooting

Check system logs

journalctl -b -u systemd-suspend-then-hibernate
journalctl -b | grep -i hibernate

Verify resume parameters

cat /proc/cmdline

Should show resume=UUID=... and resume_offset=...

Check swap priority

cat /proc/swaps

Your zram and swap file should both be listed.

SELinux issues

If hibernate fails with "Access denied", check SELinux:

sudo ausearch -m avc -ts recent
sudo audit2allow -a

Verify dracut module

sudo lsinitrd -m | grep resume

Should show resume in the module list.


Notes

  • zram compatibility: Your existing zram will continue working. The kernel uses zram for regular swapping and the swap file specifically for hibernation.
  • Battery drain: During the first 2 hours, the system uses suspend-to-RAM (very low power). After 2 hours, it hibernates to disk (zero power).
  • Wake behavior: Opening the lid before 2 hours wakes instantly from RAM. After 2 hours, it resumes from disk (slightly slower but still quick).
  • Secure Boot: Hibernation works with Secure Boot on modern Fedora versions that support hibernation resume verification.

Reverting Changes

If you need to undo this setup:

# Disable swap file
sudo swapoff /var/swap/swapfile

# Remove from fstab
sudo vim /etc/fstab  # Delete the /var/swap/swapfile line

# Remove swap file and subvolume
sudo rm /var/swap/swapfile
sudo btrfs subvolume delete /var/swap

# Restore logind settings
sudo vim /etc/systemd/logind.conf  # Change back to suspend

# Remove sleep configuration
sudo rm /etc/systemd/sleep.conf

# Remove resume from GRUB
sudo grubby --remove-args="resume resume_offset" --update-kernel=ALL

# Remove dracut resume module
sudo rm /etc/dracut.conf.d/resume.conf
sudo dracut --regenerate-all --force

# Reboot
sudo reboot
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment