I would like to use the hybrid suspend method instead of suspend when closing the lid or selecting "Suspend" from the menu.

I can imagine to change the pm-suspend script to do so automatically, but there might be a more maintainable / easier way.

up vote 44 down vote accepted

Indirect hybrid sleep

This is the older method: first suspend and then wake up to hibernate after a delay (15 minutes by default). Use this with a Linux kernel before 3.6, or if you like that it does not use any power after 15 minutes any more.

Add the file /etc/pm/config.d/00-use-suspend-hybrid:

# Always use suspend_hybrid instead of suspend
if [ "$METHOD" = "suspend" ]; then
# The delay after which hibernation gets triggered (default: 900 seconds, 15 minutes):

You might want to make sure that the hybrid method is supported on your system via the following code. If it says "0" it should work:

sudo pm-is-supported --suspend-hybrid && echo $?

Real hybrid suspending with Linux 3.6+

If you have a Linux 3.6 kernel, you can use the following, which will suspend to both disk and RAM from the beginning.

Add the file /etc/pm/config.d/00-use-suspend-hybrid:

# WORKAROUND: always set the default hibernate mode first (normal mode)
# (not required if you have the patch mentioned by Rohan below (http://askubuntu.com/a/344879/169))

# Always use hibernate instead of suspend, but with "suspend to both"
if [ "$METHOD" = "suspend" ]; then

# Make sure to use the kernel's method, in case uswsusp is installed etc.

This will always write the image to disk and then suspend to RAM, having the benefits that resuming will always be fast (as long as the battery does not run out) and that the machine will not wake up for a short time (after PM_HIBERNATE_DELAY) to hibernate for real.

The drawback is that the process takes longer (because it always hibernates to disk), and that your battery might run out in the long run (e.g. after 12 hours).

  • 2
    one small note, instead of 'sudo pm-is-supported --suspend-hybrid && echo $?', use 'sudo pm-is-supported --suspend-hybrid ; echo $?' as the return value of pm-is-supported is 0 for is supported, and 1 for is not. – James Caccese Aug 3 '12 at 17:50
  • 1
    @JamesCaccese: In shellscript world, 0 means "true" and anything else means "false". Your scriptlet would work, but the original poster's scriptlet would work as intended as well, printing a '0' on supported and nothing on unsupported. If you want something that will always say supported or unsupported, try 'sudo pm-is-supported --suspend-hybrid && echo "supported" || echo "unsupported"' – zanfur Oct 28 '12 at 4:01
  • @zanfur - While I like your subsequent supplied solution for printing both states (and nothing for whatever unexpected reason pm-is-supported doesn't execute as expected, that would do unknown things to the error state), I appreciate James Caccese's mention of that caveat, for the aforementioned reason. – user66001 Jun 8 '13 at 13:16
  • If you're using 16.04 see this answer below. – kapad Jun 11 '16 at 21:52
  • The only missing piece for me was resume argument in /etc/default/grub.conf. Also as nvidia user I had to set nomodeset. So resulting grub entry in my case is: GRUB_CMDLINE_LINUX_DEFAULT="nomodeset resume=UUID=uuidofswappartition". Don't forget grub-update. And also some modules has to be unloaded so created file /etc/pm/config.d/00-unload_modules with line SUSPEND_MODULES="ath5k r8169" and just to make sure I also renamed 00-use-suspend-hybrid to 10-use-suspend-hybrid – mauron85 Oct 7 '16 at 11:16
up vote 27 down vote

Ubuntu 16.04 and above

The solution by blueyed for Real hybrid suspending with Linux 3.6+ did not work for me. I suspect this is because Ubuntu 16.04 uses systemd and does not use the file /etc/pm/config.d/00-use-suspend-hybrid.

First, test if hibernate and hybrid-sleep works using systemd

Open a terminal by pressing Ctrl+Alt+T and enter:

sudo systemctl hibernate

This should get your computer to hibernate. To try hybrid-sleep, enter:

sudo systemctl hybrid-sleep

If it works make it permanent.

  • The following works when I close the lid.

Open the file /etc/systemd/logind.conf using your preferred editor. You will need to invoke your administrative power by sudo, gksudo or pkexec to edit this file.

Find the two lines:


Note, These lines are commented out with # in front of them. The suspend is the default action. Remove the # and change suspend to hybrid-sleep in these two lines so that they look like this:


Save the file. Log out and log back in.


  • Other than suspend or hybrid-sleep there is a third option, hibernate.
  • My laptop does not have a physical sleep button. So I could not test it.
  • Clicking on the Suspend from the cog menu puts the computer to normal suspend not hybrid-sleep.

Source: https://superuser.com/questions/719447/how-to-use-systemd-hybrid-sleep-instead-of-suspend-under-gnome-in-linux

I hope this helps

  • 2
    This answer needs more upvotes. Fixed issues for me in 16.04. Thanks. – kapad Jun 11 '16 at 21:51
  • You are welcome. Now that I have moved from 14.04 to 16.04, I am finding the new systemd way of doing things, slowly over time. – user68186 Jun 12 '16 at 4:12
  • 1
    Also works with Ubuntu GNOME 16.04.1 – HarlemSquirrel Jan 30 '17 at 17:46

In 12.04 I noticed that when hibernation is triggered (using PM_HIBERNATE_DELAY=XX), the resume/thaw the shell scripts do not unset the grub recordfail variable. Therefore grub does not autoboot.

Timeout is set to -1 and it awaits user selection. I am guessing this requires some editing of scripts in /etc/pm/sleep.d/10_grub-common. Am a novice so I haven't dabbled to figure out the exact change unfortunately.

  • 1
    Would be worth a bug report probably and/or testing if it works in 12.10+. – blueyed Nov 16 '12 at 17:21
  • I see the same problem in 12.10 – MDCore Dec 16 '12 at 10:09

This question comes up frequently enough in Google that I think it's worth bumping. The method described here is (imo) not hybrid suspend. It is "hibernate after X minutes in suspend". True hybrid suspend writes your RAM out to disk and then goes in low-power state (sleep mode). While it takes longer, the resume is instant while the machine has battery left, otherwise resumes form hard disk. This behaviour is what most people know as hybrid sleep, and used by default in the newer Windows and Mac laptops.

Here's how to enable the real hybrid suspend:

  • Follow the first part of the top answer. This overrides "suspend" call to do a "hybrid_suspend" in pm-utils.
    % cat /etc/pm/config.d/00-use-suspend-hybrid
    # Always use suspend_hybrid instead of suspend
    if [ "$METHOD" = "suspend" ]; then
  • Make a backup of /usr/lib/pm-utils/pm-functions
  • Get the patch from here: https://bugs.freedesktop.org/attachment.cgi?id=68712
    • This patch enables hybrid suspend if available (i.e. on kernels 3.6+)
  • Either apply it using 'patch -p0' or manually merge it if that fails

This method works for me on my Sony Vaio SVS.

PS: Reproducing the patch here in case the file is deleted in the future:

diff --git a/pm/pm-functions.in b/pm/pm-functions.in
--- a/pm/pm-functions.in
+++ b/pm/pm-functions.in
@@ -316,8 +316,28 @@ if [ -z "$HIBERNATE_MODULE" ] && \
        [ -n "${HIBERNATE_MODE}" ] && \
        grep -qw "${HIBERNATE_MODE}" /sys/power/disk && \
+       HIBERNATE_MODE_SAVE=$(cat /sys/power/disk) && \
        echo -n "${HIBERNATE_MODE}" > /sys/power/disk
        echo -n "disk" > /sys/power/state
+       RET=$?
+       echo -n "$HIBERNATE_MODE_SAVE" > /sys/power/disk
+       return "$RET"
+   }
+# for kernels that support suspend to both (i.e. hybrid suspend)
+# since kernel 3.6
+if [ -z "$SUSPEND_HYBRID_MODULE" ] && \
+   [ -f /sys/power/disk ] && \
+   grep -q disk /sys/power/state && \
+   grep -q suspend /sys/power/disk; then
+   do_suspend_hybrid()
+   {
+       HIBERNATE_MODE="suspend"
+       do_hibernate


  • 1
    You are right about hybrid-suspend. I have recently changed my snippet myself. You can get (quite) the same result by using METHOD=hibernate and HIBERNATE_MODE=suspend. I am setting HIBERNATE_MODE=platform at the top of the file, instead of saving and restoring the previous version (what the patch does). I will update my answer above. – blueyed Oct 8 '13 at 23:56
  • That looks great, thanks for the edit, @blueyed – Rohan Dhruva Oct 18 '13 at 1:30

There's another solution without adding any file in config.d, just using wakealarm in /sys/class/rtc/rtc0. Make use obsolete code in pm-functions (/usr/lib/pm-utils) after the comments #since the kernel does not directly support ... , ('cos the current kernel (after 3.6 something) does directly support). Revert that code and put in do_suspend() part instead of do_suspend_hybrid(), and use the patch for pm-functions ('til they fix it).

Obsolete code (suspend then hibernate when suspend_hybrid is called):

# since the kernel does not directly support hybrid sleep, we do
# something else -- suspend and schedule an alarm to go into
# hibernate if we have slept long enough.
# Only do this if we do not need to do any special video hackery on resume
# from hibernate, though.
if [ -z "$SUSPEND_HYBRID_MODULE" -a -w "$PM_RTC/wakealarm" ] && \
    check_suspend && check_hibernate && ! is_set $HIBERNATE_RESUME_POST_VIDEO; \
    do_suspend_hybrid() {
    WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
    echo >"$PM_RTC/wakealarm"
    echo $WAKETIME > "$PM_RTC/wakealarm"
    if do_suspend; then
        NOW=$(cat "$PM_RTC/since_epoch")
        if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ]; then
        log "Woken by RTC alarm, hibernating."
        # if hibernate fails for any reason, go back to suspend.
        do_hibernate || do_suspend
        echo > "$PM_RTC/wakealarm"
        # if we cannot suspend, just try to hibernate.

Recommended. Even easier to use uswsusp while the same time maximize the benefit of s2both i.e. s2both when suspend. Put the reverted code in do_suspend() part of uswsusp module (/usr/lib/pm-utils/module.d).

Reverted code (suspend_hybrid when suspend is called):

        WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
        echo >"$PM_RTC/wakealarm"
        echo $WAKETIME > "$PM_RTC/wakealarm"
        if do_suspend_hybrid; then
            NOW=$(cat "$PM_RTC/since_epoch")
            if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ];             then
            log "Woken by RTC alarm, hibernating."
            # if hibernate fails for any reason, go back to suspend_hybrid.
            do_hibernate || do_suspend_hybrid
            echo > "$PM_RTC/wakealarm"
            # when do_suspend is being called, convert to suspend_hybrid.

With uswsusp, we can see the progress of suspend/hibernate and the reverse process displayed in text, even we can abort it by pressing backspace. Without uswsusp, suspend/hibernate just appear-disappear annoyingly, especially when wakealarm is triggered and execute hibernate (s2disk in uswsusp). Set the period of sleep before hibernate in the usual place on pm-functions file.

# variables to handle hibernate after suspend support
PM_HIBERNATE_DELAY=900  # 15 minutes

Here's the uswsusp mod: (remember, this module is called from pm-functions so the inserted variables are the same)


# disable processing of 90chvt and 99video.
# s2ram and s2disk handle all this stuff internally.
    disablehook 99video "disabled by uswsusp"

# Since we disabled 99video, we need to take responsibility for proper
# quirk handling.  s2ram handles all common video quirks internally,
# so all we have to do is translate the HAL standard options to s2ram options.
    for opt in $PM_CMDLINE; do
        case "${opt##--quirk-}" in # just quirks, please
            dpms-on)       ;; # no-op
            dpms-suspend)      ;; # no-op
            radeon-off)        OPTS="$OPTS --radeontool" ;;
            reset-brightness)  ;; # no-op
            s3-bios)       ACPI_SLEEP=$(($ACPI_SLEEP + 1)) ;;
            s3-mode)       ACPI_SLEEP=$(($ACPI_SLEEP + 2)) ;;
            vbe-post)      OPTS="$OPTS --vbe_post" ;;
            vbemode-restore)   OPTS="$OPTS --vbe_mode" ;;
            vbestate-restore)  OPTS="$OPTS --vbe_save" ;;
            vga-mode-3)        ;; # no-op
            save-pci)          OPTS="$OPTS --pci_save" ;;
            none)          QUIRK_NONE="true" ;;
            *) continue ;;
    [ $ACPI_SLEEP -ne 0 ] && OPTS="$OPTS --acpi_sleep $ACPI_SLEEP"
    # if we were told to ignore quirks, do so.
    # This is arguably not the best way to do things, but...
    [ "$QUIRK_NONE" = "true" ] && OPTS=""

# Since we disabled 99video, we also need to handle displaying
# help info for the quirks we handle.
    echo  # first echo makes it look nicer.
    echo "s2ram video quirk handler options:"
    echo "  --quirk-radeon-off"
    echo "  --quirk-s3-bios"
    echo "  --quirk-s3-mode"
    echo "  --quirk-vbe-post"
    echo "  --quirk-vbemode-restore"
    echo "  --quirk-vbestate-restore"
    echo "  --quirk-save-pci"
    echo "  --quirk-none"

# This idiom is used for all sleep methods.  Only declare the actual
# do_ method if:
# 1: some other sleep module has not already done so, and
# 2: this sleep method can actually work on this system.
# For suspend, if SUSPEND_MODULE is set then something else has already
# implemented do_suspend.  We could just check to see of do_suspend was
# already declared using command_exists, but using a dedicated environment
# variable makes it easier to debug when we have to know what sleep module
# ended up claiming ownership of a given sleep method.
if [ -z "$SUSPEND_MODULE" ] && command_exists s2ram && \
    ( grep -q mem /sys/power/state || \
        ( [ -c /dev/pmu ] && check_suspend_pmu; ); ); then
        WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
        echo >"$PM_RTC/wakealarm"
        echo $WAKETIME > "$PM_RTC/wakealarm"
        if do_suspend_hybrid; then
            NOW=$(cat "$PM_RTC/since_epoch")
            if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ];             then
            log "Woken by RTC alarm, hibernating."
            # if hibernate fails for any reason, go back to suspend_hybrid.
            do_hibernate || do_suspend_hybrid
            echo > "$PM_RTC/wakealarm"
            # when do_suspend is being called, convert to suspend_hybrid.

if [ -z "$HIBERNATE_MODULE" ] && \
    [ -f /sys/power/disk ] && \
    grep -q disk /sys/power/state && \
    [ -c /dev/snapshot ] &&
    command_exists s2disk; then

if [ -z "$SUSPEND_HYBRID_MODULE" ] && 
    grep -q mem /sys/power/state && \
    command_exists s2both && \
    check_hibernate; then
        s2both --force $OPTS 
    if [ "$METHOD" = "suspend_hybrid" ]; then
        add_before_hooks uswsusp_hooks
        add_module_help uswsusp_help

The answer by user68186 for Ubuntu 16.04 did not work for me. However, the solution here did.

First, ensure hibernation works. Then

Search for and install dconf Editor in Ubuntu Software. Then launch it and navigate to org -> gnome -> settings daemon -> plugins -> power.

Change the value of “lid-close-ac-action” and “lid-close-battery-action”.

In my power settings, these options show up as blank, but they work as intended.

Your Answer


By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.