At first, hibernate did not work at all. This thread pointed me in the right direction. I had to:

  1. Set up a separate swap partition with enough space to hold the entire physical RAM
  2. Disable SecureBoot (the Ubuntu installer advises you to do this, but I was lazy)
  3. Update GRUB configuration to read the recovery image from the swap partition

Once hibernation was working, the next step was to get suspend-to-hibernate to work. The idea is that the following happens:

  1. You close the laptop lid
  2. The system automatically goes into suspend. This is a low-power mode that drains the battery slower than regular operation, but allows fast recovery.
  3. After some time passes (e.g. 1 hour), the system automatically goes into hibernation. This mode does not drain the battery over time, so it’s ideal for laptops.
  4. You open the laptop lib
  5. The system thaws, and after 30s or so you go back to work

If you re-open the lid before the required time elapses, the system unsuspends, and you go back to work almost immediately. With this approach, you get the best of both worlds:

  • Fast recovery (if the suspended time has been short)
  • Longer battery life

Making this work is more difficult than it sounds. Adding a new service looked promising, but it did not work:

Failed to hibernate system via logind: There's already a shutdown or sleep operation in progress

This thread addressed the issue, but did not work for me.

Interestingly, it looks like the new systemd version 239 supports suspend-then-hibernate out of the box, but it’ll be a while before it arrives in Ubuntu. I’m running an LTS version, so it’s likely that it’ll never arrive until I upgrade distros.

In the end, I gave up on hibernate-then-suspend. For the time being, I’ve set up the notebook to always hibernate on lid close. Waiting 30s for it to thaw each time I open the lid is a PITA… we’ll see how long I can tolerate it.