Hibernate is a non-negotiable on my laptop. I often have some valuable state that I may not return to for days, and don't want to leave my laptop charging just for that convenience. Unlike sleep, which has a small ongoing power drain to maintain your state, hibernate works indefinitely without charging by dumping state to disk.
Unfortunately getting hibernate to work in Ubuntu can be a bit of a mission. It gets slightly better with every release, but I still yearn for the day where it works out of the box with nothing more than couple of selections in a cute UI.
The most reliable approach I've found over the years is to work from the bottom-up, ensuring the fundamental building blocks like s2disk
work before getting into the useful interfaces like systemctl
.
The s2disk
utility does exactly as it says in the name "suspend to disk"—suspends your current state by writing what's currently in RAM to disk. This requires a place to write the contents of RAM, and these days there's two options:
There's a lot of similarities between the two options, but swap files have become the default these days. They are almost always the best option as they offer all of the capabilities of a swap partition, but with much more flexibility. Want to change its location? Just move the file. Want to increase it's size? Just create a bigger file.
Creating a swap partition is a well-documented process by now, and I'd recommend using gparted
if you're having any troubles.
There's a number of good guides on using swap files—like on It's FOSS and the ArchWiki. The general gist is you want to create a file with the appropriate permissions:
ben@pc:~$ sudo fallocate -l 8G /swapfile
ben@pc:~$ sudo chmod 600 /swapfile
It's not essential, but given you're chewing up all that space on your SSD, you might as well use it for swapping while your computer is on. Swapping lets the kernel use this file as extra RAM when you start running out.
ben@pc:~$ sudo mkswap /swapfile
ben@pc:~$ echo '/swapfile none swap sw 0 0' | \
sudo tee -a /etc/fstab
Now you've got a place for s2disk
to store state. One important note is that this place must be larger than your RAM. Otherwise, unstable things may happen when suspending with more data in RAM than you can hold.
s2disk
Next, we want to use the s2disk
command to suspend our current state to disk. Using the command is simple, but it needs to be configured correctly before being run. Configuration is done in the /etc/uswsusp.conf
file which is really well documented:
ben@pc:~$ man uswsusp.conf
As a reference point, here is the contents of my working config:
/etc/uswsusp.conf# /etc/uswsusp.conf(5) -- Configuration file for s2disk/s2both
resume device = /dev/nvme0n1p9
compress = y
early writeout = y
image size = 3765881896
RSA key file = /etc/uswsusp.key
shutdown method = platform
resume offset = 34816
The two options you typically need to worry about are resume device
and resume offset
. Their use varies depending on if you have a swap partition or swap file:
swap partitions: resume device
is simply the device identifier of your swap partition, and resume offset
isn't needed
swap files: resume device
is the device identifier for the partition holding your swap file, and resume offset
is the swap file's byte offset from the start of the partition. Sounds complicated, but there's a simple command to get you that number:
ben@pc:~$ sudo swap-offset /swapfile
resume offset = 34816
At this point you should be able to test by simply running s2disk
:
ben@pc:~$ sudo s2disk
When you wake your computer you'll probably return to a fresh login with your state lost. There's one last step to getting resume working.
Suspending to disk is half the picture, with the second half being waking from disk. This is managed by the kernel, which also has to be told where our state is stored on disk.
Mercifully, the parameters are the same as what we had to configure above for s2disk
. Simply edit your GRUB_CMDLINE_LINUX_DEFAULT
to include the following variables:
/etc/default/grub...
GRUB_CMDLINE_LINUX_DEFAULT="resume=UUID=/dev/nvme0n1p9 resume_offset=34816 ..."
...
Lastly, ensure everything is rebuilt properly (I ran into issues until I forced the rebuild of initramfs
):
ben@pc:~$ sudo update-grub
ben@pc:~$ sudo update-initramfs -u -k all
At this point you should be able to run s2disk
, and turn your computer back on with the existing state restored.
The command you should be using to hibernate, systemctl hibernate
, is simply a wrapper around s2disk
. If s2disk
works, it should work. I saw a lot of posts recommending changes to the hibernate service, but they all seemed to making unnecessary changes that can only do harm to the hibernate pipeline.
If you're still encountering issues, there's a lot of useful guides and answers around from people that have also had to dig deep into getting this working. Just be careful with copy-pasting commands without context, as they often set you further back from a working state if they aren't applicable to your situation. Here's some of the most useful resources I stumbled upon:
Hopefully this has got hibernate working for you. Be sure to let me know if there's any helpful tips I haven't covered that you found along the way.
Note: Now that you've got hibernate working, want to add it into GNOME? I've got another post here that goes through using your power button to hibernate
Let me know below if you liked this content, or found it valuable, using the buttons below.
Like this?
© Ben Talbot. All rights reserved.