Getting hibernate to work in Ubuntu 18.04+

Last updated
23 January 2021
Ben Talbot

A hibernating laptop allows you to control when it wakes and sleeps

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.

Creating a place for your suspended state

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:

  • 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 wake your computer 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 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.

Where to from here

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?

Loading donation link...

© Ben Talbot. All rights reserved.