Android's K-9 Mail battery life and Dovecot's Push-IMAP

What is Push-IMAP, and why is it useful?

In the world of mobile phones, battery life is a concern. You want to be able maximize the battery life on your mobile phone, while still getting instant notifications of new e-mail. This is where Push-IMAP (aka. IMAP PUSH, P-IMAP) comes into play, an extension based on an RFC which combines with IMAP IDLE. You no longer need to poll the IMAP server if you are using this feature, as you always have an open connection.

What's the problem?

I am using K-9 Mail on my Android phone, and would like to make use of the IMAP PUSH feature but I found it consumes far too much battery. In Dovecot 1.2 when you initiate IMAP IDLE via your IMAP client (eg. K-9 Mail) Dovecot sends a message every 2 minutes stating "OK Still here", this causes the mobile data connection to have to wake up and consumes excessive amounts of battery. There is no way to configure this behavior in Dovecot 1.2 except by a source edit.

The solution

You will need to upgrade your Dovecot installation to 2.0 (if you aren't running 2.0 already,) which is slightly out of the scope of this blog entry. I found the upgrade rather painless by following the Upgrading Dovecot v1.2 to v2.0 guide on the Dovecot Wiki.

Dovecot 2.0 supports a configuration option called imap_idle_notify_interval which enables you to specify the interval between "OK Still here" messages. K-9 mail by default refreshes IDLE connections every 24 minutes, but of course Dovecot wakes up the client much more frequently than that. We are going to fix this behavoir.

The configuration of Dovecot 2.0 is slightly different than Dovecot 1.2, composing of multiple files. If you are using Linux your Dovecot configuration is most likely contained under /etc/dovecot, and on FreeBSD it is contained under /usr/local/etc. You will want to edit the conf.d/20-imap.conf file under the respective directory based on your host operating system.

You will see a stanza similar to the one outlined below, and you will want to uncomment the imap_idle_notify_interval line and replace 2 mins with 29 mins.

protocol imap {
 # How long to wait between "OK Still here" notifications when client is
 # IDLEing.
 #imap_idle_notify_interval = 2 mins
}

When you have completed this step, you will want to restart Dovecot. This can be accomplished on Linux with /etc/init.d/dovecot restart, or /usr/local/etc/rc.d/dovecot restart on FreeBSD.

My results

By switching the Dovecot server to send the "OK Still here" notification to every 24 minutes instead of 2 minutes the mobile client is woken up much more infrequently, either when you receive a new e-mail or every 29 minutes respectively. This has greatly improved the battery life on my HTC Desire Z with K-9 Mail, and hopefully it will help out with your device issues and being able to instantly receive new e-mail notifications!

An update, RFC style

Clint Pachl e-mailed me to inform me that IMAP4 IDLE RFC (rfc2177) specifics that the client should issue a IDLE command every 29 minutes. I have updated the guide to reflect this change.

Because the K-9 default "Refresh IDLE connection" is 24 minutes, that gives a buffer of 5 minutes if the IMAP server timeout is set to 29 minutes. The RFC and K-9 default times, 29 and 24 respectively, don't seem like a coincidence. I think the RFC may have been an influence on the K-9 devs when choosing a default IDLE refresh.

Consequently, setting Dovecot's imap_idle_notify_interval to 29 minutes seems most appropriate considering K-9's default. This gives K-9 ample time to respond in case of short outages or passing between cell towers (<5min window). However, beyond that window, the server can then shut down the connection.

Setting both the server and the client to the same timeout/refresh may cause some cross-talk.

2 Comments.

  1. Brilliant tip. I already had dovecot2 and switched to Nexus S recently. I'll observe how it works out with battery life. Have you tried setting it to more than 24 min? 36, 48, etc?