Skip to content

Instantly share code, notes, and snippets.

@karanth
Last active December 4, 2023 10:44
Show Gist options
  • Save karanth/8403094 to your computer and use it in GitHub Desktop.
Save karanth/8403094 to your computer and use it in GitHub Desktop.
Notes on "Real"-time IMAP mail updates

IMAP is a popular mail access protocol. Mail clients traditionally work on a polling model, i.e., they request the server for new messages and updates at fixed intervals. These are not "Real"-time updates as server updates are brought down to the client only at the end of each interval. The average time taken for an email to be seen by the client is half the size of the polling interval and not immediate.

However, IMAP4 has the IDLE command to help clients get updates instantly in "real"-time. RFC 2177 refers to the IDLE command and can be found [here] (https://tools.ietf.org/html/rfc2177). Executing the command has the following pre-requisites,

  • A (TCP socket) network connection is open between the client and the server.
  • The client is authenticated with the server using LOGIN or AUTHENTICATE.
  • The client has issued a SELECT (read/write) or the EXAMINE (read-only) command on a particular mailbox.
  • The server lists IDLE as a supported capability when the CAPABILITY command is issued.

When the IDLE command is issued the server sends out a '+', as a request for continuation data. The only continuation data that is expected by the server is a DONE string that terminates the IDLE command. When the IDLE command is active, the server sends out untagged responses like EXPUNGE (message deleted) or EXISTS (message added) with the message ID indicating the "address" of the message. When a continuation response is sent by the client, no other command should be sent in the interim, till the server cancels the IDLE command.

The IDLE command can be implicitly logged out and terminated by the server after 30 minutes of inactivity. It is therefore advised for clients to reissue their IDLE command every half hour for continued updates. Any updates during that interval appear before the continuation request from the server.

Below is an example client - IMAP server interaction,

C: A1 CAPABILITY
S: * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH AUTH=XOAUTH2 AUTH=PLAIN AUTH=PLAIN-CLIENTTOKEN
S: A1 OK Thats all she wrote! sj10if20592874pac.132
C: A2 LOGIN test@example.com password
S: * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH
S: A2 OK test@example.com Test authenticated (Success)
C: A3 EXAMINE "[Gmail]/All Mail"
S: * FLAGS (\Answered \Flagged \Draft \Deleted \Seen)
S: * OK [PERMANENTFLAGS ()] Flags permitted.
S: * OK [UIDVALIDITY 1] UIDs valid.
S: * 3554 EXISTS
S: * 0 RECENT
S: * OK [UIDNEXT 15297] Predicted next UID.
S: * OK [HIGHESTMODSEQ 1110170]
S: A3 OK [READ-ONLY] [Gmail]/All Mail selected. (Success)    -- EXAMINE opens the mailbox as read-only.
C: A4 IDLE               -- IDLE command issued from client.
S: + idling              -- Continuation Request from server.
---- Time lapse -----
S: * 3555 EXISTS         -- Update pushed from server.
C: DONE                  -- Continuation response from client. 
S: A4 OK IDLE terminated (Success)
C: A5 NOOP
S: A5 OK Success
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment