Ben Talbot home
aboutprojectspostsresearch

Getting hibernate to work in Ubuntu 18.04+

23 January 2021
Ben Talbot

Hibernate is something I find invaluable 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 as it dumps your 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.

 Creating a place for your suspended state

The s2disk utility does exactly as it says in the name—suspends your current state by writing what's currently in your RAM to disk. For this to work, you have to have a place where your RAM contents can be written. These days there's two types of places on disk for storing this data:

  • a swap partition, or
  • a swap file.

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.

 Suspending state to disk with 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 go to wake your computer up you'll probably return to a fresh login with your state lost. There's one last step to getting resume working.

 Waking up with your state intact

Suspending to disk is half of the picture, with the second half being waking from disk. This is managed by the kernel, which we have to also have to tell about 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 the 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 from 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, found it valuable, or have any comments.

Like this?

Loading ...
Loading ...

© Ben Talbot. All rights reserved.