Throttling coming to Outlook API and Microsoft Graph


Update 5/10/17: Based on feedback from our customers that the posted limit is too low for their apps, this is not currently being enforced. We’re working with them and gathering data to understand what would work for their apps. We’ll provide an update once we have more information.

On April 21, we will be enabling throttling on the Outlook REST APIs (accessed via https://outlook.office.com/api or https://outlook.office365.com/api), and on the Outlook-related endpoints of the Microsoft Graph (accessed via https://graph.microsoft.com). We wanted to give developers some advanced warning to make sure you were prepared!

What’s the limit?

The limit is 60 requests per minute, per user (or group), per app ID. This means that your app can make at most 60 requests to a single user’s mailbox in a minute. If your app is requesting data from multiple users simultaneously, requests to one user do not impact the limit for another user.

What APIs are subject to this limit?

Outlook APIs

All APIs accessed via https://outlook.office.com/api or https://outlook.office365.com/api, including:

Microsoft Graph

Only the Outlook-related APIs in the Microsoft Graph are subject to this limit. Microsoft Graph requests to non-Outlook resources (such as OneDrive files) would not count against this limit. The following resources (and their child resources) are subject to the limit:

Can I track my usage?

Each response from the API will contain specific headers that can help you track your current state in regards to the rate limit.

Header name Description
Rate-Limit-Limit The maximum number of requests that the app is permitted to make per minute for the current user or group
Rate-Limit-Remaining The number of requests remaining in the current rate limit window
Rate-Limit-Reset The time at which the current rate limit window resets in UTC time

What happens if my app exceeds the limit?

You’ll get a 429 response back from the server. The response will include a Retry-After header, which will specify the number of seconds your app must wait until it can make more requests for the particular user or group. It will also include a Rate-Limit-Reason header with a human-readable string that articulates the reason for the throttled request.

How do I avoid being throttled?

If your app is currently making more than 60 requests per minute per user or group, there may be some ways that you can reduce the number of requests without reducing the amount of data your app is accessing. Some general tips to reduce requests are:

  • Increasing page size: Using the $top parameter to increase the number of items returned per page when requesting a set of items. The default page size if the $top parameter is omitted is 10, which isn’t very efficient if you’re requesting a large number of items. You can increase this limit up to 1000.
  • Reduce number of GET for single items: As much as possible, get the data your app needs from lists (such as GET /me/messages) rather than requesting each individual entity (such as GET /me/messages/{message-id}). Using the $select parameter to request the fields your app needs can help you control what data is returned back in lists.

Call to action

Based on the usage rates we’ve seen to date, we believe that most apps out there will not exceed the limit. However, we encourage you to review your app and determine if you are likely to exceed the limits. If so, you should look at ways to reduce the number of requests or make sure you have error handling in place to handle 429 responses and retry in an appropriate amount of time.

We will be publishing more detailed documentation on these limits in the near future.

Comments (22)

  1. Yairrr says:

    Thanks for the update, it’s great to finally have the limits written down clearly with a way to know the status.
    How will it work alongside the current more vague limitations?
    I noticed there is some throttling already, except instead of returning a negative answer, i get the answer very slowly until my app decides it’s too slow to work with.
    This seems to be per user and it may or may not be a shared limitation with other APIs like EWS onedrive etc.
    Can you comment on that?

    1. I don’t know any specifics about it, this is the first I’m hearing of any such limit. I’ll see what I can find out.

      1. Ok, I chatted with our devs and from what you’re describing, that sounds like a shared limit with EWS that is currently in place. The new limiting mechanism described here will replace this scheme, so it should be more transparent and predictable.

        1. Yairrr says:

          Fantastic! thanks

  2. Garima says:

    Hi Jason, little bit off topic here but I am trying to find a sample where I can query outlook mail api in javascript using adal. I need to use this code in script editor web part of sharepoint. Could you point me to the right direction.

  3. Jørgen Solberg says:

    Thanks for the update! The limit of 60 for a group seems too restrictive. Is there any way you can reconsider that limit?

    1. I can pass your comments up to the folks in charge :). However I’d recommend posting this as a suggestion on UserVoice.

  4. Jenny says:

    Is it possible to increase these limits? 60 requests per minute is awfully little to work with. (e.g. lets mark multiple messages in a user’s mailbox as read. So if a user selects 10 messages, and marks alot of them as read. They will either hit the wall or get pretttty close to it.

    Is there an option to pay microsoft for an increased limit per user per minute?

    1. Thanks for the feedback. No, there’s no option to up the limit currently.

  5. Glen Scales says:

    How does this affect batch requests ? is the batch counted as one request or are the individual requests counted. Are all request affected ? eg if your copying or moving items your effectively limiting that to 60 items a minutes which isn’t going to be great if you have 1000’s of items that need to be moved or marking a large number of item Read etc.

    1. No, batch requests don’t get around it I’m told. If you send 20 requests in a batch, that counts as 20 requests.

      1. Glen Scales says:

        I’d encourage you to rethink that then it doesn’t really make sense to apply it across everything as all operations aren’t equal. I can see some utility in restricting 60 Gets a minute but for instance what’s the point to the batch interfaces. Eg this mean with a batch size of 20 you can’t make anymore then 3 requests a minute. Volume requests would be needed for a bunch of different valid enterprise functions like imports,moves,deletes,copies, hygiene, updates and data discovery. Throttling is needed for availability and reliability but at 60 requests a minute that restricts functionality.

        1. The limits didn’t go in place as planned. Engineering has heard the feedback and they are now collecting more telemetry to see what rate limits make sense. I’ll update the post shortly.

  6. Gary Tweddle says:

    Do we have any details on concurrent connection limits? Can I post 60 contacts to a user’s mailbox in parallel each minute or do I have to spread those 60 over the minute?

    1. Concurrent should be fine.

  7. Marco says:

    Hi Jason, is this new rate limit already active? When I make a request to the Outlook API / GraphAPI i don’t receive the new rate limit headers. I’m also able to make more than 60 requests per user/minute without a 429 response. I tried the following two requests: “https://outlook.office.com/api/v2.0/users//messages” and “https://graph.microsoft.com/v1.0/users/<USERNAME/messages"

    1. No it isn’t. Updating the post.

  8. Benson says:

    I’ve been getting a 429 Rate Limit Error for ‘Too many concurrent connections opened’.

    I’ve logged the response and have a few questions:

    1) An example header I get back is this:
    ‘rate-limit-limit’: ‘10000’,
    ‘rate-limit-remaining’: ‘9863’,
    ‘rate-limit-reset’: ‘2017-05-10T03:43:45.871Z’,

    How is it possible that rate-limit-limit is 10000? In other words if the API could actually service 10k requests in a minute, I wouldn’t have this concurrent connections rate limiting issue in the first place.

    2) There are no ‘Retry-After’ or ‘Rate-Limit-Reason’ headers in the response? I figured ‘Rate-Limit-Reason’ is just the response body.

    Also – if it matters – these are responses from GET /messages/{messageId}/attachments

    Thanks!

    1. Yeah the rate limits aren’t being enforced at the moment. I’m updating the post shortly.

  9. Mike Noordermeer says:

    Just to chime in here, for our application this would be an issue. We provision the user’s university timetable in their calendar, and that requires creating hundreds of calendar events. This is a one-time action (per year), but it does require a greater limit than 60 to give the user a good experience. I would much rather see a limit per app/minute, or a limit per user/5 minutes which is configurable (like Google has).

  10. Hitendra says:

    It is available only for Outlook web rite-now as it Outlook web only has requirement set 1.5 supported, any idea when it would be available for outlook desktop?

Skip to main content