Optimizing Exchange ActiveSync clients for Exchange Online
Discover some of the new functionality that Exchange Online adds to Exchange ActiveSync.
Applies to: Exchange Online
If you're reading this article with any interest, then hopefully you're already aware of the Exchange ActiveSync protocol documentation, which is part of the Microsoft Exchange Server protocol documentation. Those documents contain the information you need to implement an Exchange ActiveSync client that will work with any server that implements Exchange ActiveSync. What those documents cannot tell you is the added features above and beyond the protocol requirements each server implementation brings to the table.
In this article we'll examine some of the added features in Exchange Online. While implementing support for these features in your Exchange ActiveSync client isn't required for conformance with the open specifications, it will provide your users with a smoother experience when connected to a mailbox on Exchange Online.
Exchange Online has implemented Exchange ActiveSync throttling to manage and maintain optimal performance of the Exchange Online environment in Office 365. What does this mean for you, the implementer?
What is throttling?
In the scope of this document, "throttling" is the term we use to describe a reactive measure taken by Exchange Online when the actions of a particular device are approaching a point that could cause problems for the service. In order to protect the overall health of the service, Exchange Online will block that device by effectively denying access for a brief period of time. However, if your implementation isn't aware of this feature, you may end up retrying your requests, possibly prolonging the block.
At this point you may be wondering what actions taken by a device will result in throttling? Unfortunately, there isn't a straightforward answer to that question. The decision to throttle is based on a number of factors, many of which are constantly in flux. For example, the current load on the server is a major factor. It is possible that an implementation may be doing nothing wrong and still gets throttled due to current server conditions. Because of this, we will focus on how to gracefully react to throttling, rather than examining what happened to get you there.
Determining that the device has been throttled
Exchange ActiveSync commands are sent to the server via HTTP POST. For more information, see [MS-ASHTTP] ActiveSync HTTP Protocol Specification. Successful commands will get an HTTP POST response back from the server with an HTTP status of 200. However, if a device is throttled by Exchange Online, the HTTP status code in the response will be 503 Service Unavailable, as defined in RFC 2616. Of course, HTTP servers can return a 503 status code for other reasons. So, how can we tell that a particular 503 response is because of Exchange ActiveSync throttling? Throttled 503 responses will include a header in the HTTP response called X-MS-ASThrottle.
Reacting to being throttled
Let's say you've received a 503 response from Exchange Online, and you've checked for the presence of the X-MS-ASThrottle header. How do you proceed? Do you need to do things differently if you've been throttled vs. a non-throttled 503 response? The answer depends largely on how you already react to 503 responses. RFC 2616 tells us that a 503 implies a temporary condition, so it makes sense that clients would have some sort of retry strategy in place for dealing with 503 responses. A client may even have multiple retry strategies to handle user-originated requests and background requests differently.
Whatever your retry strategy may be, it is important to remember that while all 503 conditions should be temporary, the exact time frame for a "temporary" condition is up in the air. It could be anywhere from milliseconds to hours. In some cases the server may be able to provide a "hint" in the form of a Retry-After header, but this isn't guaranteed, and the value of that header by no means constitutes a guarantee that the 503 condition will be resolved by that time. Knowing that we have no hard numbers to work with, we have to settle for adopting a strategy that meets the design goals of our clients while minimizing the potential for wasting resources (data transmission, battery life, and so on) sending requests that won't go through.
In a sense, retrying in a throttling scenario is a bit more straightforward. A Retry-After header may be present, and can serve as a minimum delay time, but it is important to remember that conditions can change rapidly, and the value of the Retry-After header isn't a guarantee. While you still don't have a hard number, you can make a couple assumptions. First, immediate retries (and in fact, any requests) aren't going to go through. Second, the order of magnitude is most likely going to be minutes rather than seconds. These assumptions can help shape your retry strategy.
Let's look at an example. Consider an Exchange ActiveSync client that adopts the following strategy for handling 503 responses:
User-originated requests (for example, the user clicks a "Sync Now" button in the client): Retry immediately twice. If the 503 persists, notify the user that the service is temporarily unavailable.
Background requests (for example, the client defaults to sending a Sync request every 15 minutes): Retry 5 times, with the delay between retries growing with each subsequent attempt. Retry 1 delays 1 millisecond, retry 2 delays 500 milliseconds, retry 3 delays 1 second, retry 4 delays 10 seconds, and retry 5 delays 1 minute.
After receiving a 503 response with the X-MS-ASThrottle header present, the client uses the following modified strategy:
User-originated requests: No retry. Notify the user that the service is unavailable.
Background requests: Retry after a delay of 1 minute. If the retry results in another 503 response, don't retry again until the next regular sync window.
This example strategy is for illustrative purposes only. It is not intended to illustrate the most optimal strategy or a recommended best practice.
Exchange Online implements two HTTP headers that provide a warning that the user's password is nearing expiration. Exchange ActiveSync clients can use these headers to provide advance warning to the user so they can update their password prior to expiration.
The following headers are optional headers that can be present in any Exchange ActiveSync response. The presence of one of these headers does not require the presence of the other.
The value of this header is an integer that indicates the number of days remaining until the password expires. A value of 0 indicates that there are less than 24 hours left before the password expires.
The value of this header is a URL for a self-service web site that allows the user to update their password.
Exchange Online defines two new HTTP status codes that provide more specific reasons for request failures caused by authentication issues. However, these status codes are not returned in Exchange ActiveSync responses, they are only returned in Autodiscover responses. We recommend that Exchange ActiveSync clients that receive repeated back-to-back 401 Unauthorized responses send an Autodiscover request and check for the HTTP status codes in the following table.
The user's account is blocked. The client should stop sending requests to the server and should prompt the user to contact their administrator.
The user's password is expired. The client should stop sending requests to the server and should prompt the user to update their password. If the X-MS-Credential-Service-Url header is present in the response, the client should direct the user to the URL contained in the header.
We hope that this information has helped to explain the added functionality that Exchange Online brings to the Exchange ActiveSync protocols. For more information, see the Additional Resources section.