Throttling coming to Outlook API and Microsoft Graph

Update 12/4/17: Updated the post with the current limits.

On April 21, we will be enabling throttling on the Outlook REST APIs (accessed via or, and on the Outlook-related endpoints of the Microsoft Graph (accessed via We wanted to give developers some advanced warning to make sure you were prepared!

What's the limit?

The limit is 10000 requests per 10-minute period, per user (or group), per app ID. This means that your app can make at most 10000 requests to a single user's mailbox in a 10-minute period. 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 or, 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.

Note: Only the Outlook REST API endpoints return these rate limit tracking headers. The Microsoft Graph endpoint does not return these headers.

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 the allowed number of requests, 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 (37)

  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.

          1. Simon says:

            Well, the limits seem to be in place now (at least we’re hitting them) and you haven’t updated this post.

            What are the new arbitrary limits we’re supposed to work to?

          2. Sorry for the confusion here and the lack of update. The limit is 10K requests every 10 minutes per app per user. That means for your application ID, you would be allowed to make 10k requests to a single user’s mailbox every 10 minutes. If you’re accessing multiple user’s mailboxes, then you get 10k/10min for each one of those. I’m working with engineering to get all the details ironed out so I can update the post.

  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: “” and “<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


    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?

  11. Sergiu says:

    Will this restriction apply to service accounts (application accounts that have been granted permission to read the entire exchange data)? Our application is using such an account to query the calendars of hundreds (even thousands) of meeting rooms. How will the limit be calculated? Will we be allowed to perform 60 API calls no matter whose mailbox/calendar we’re accessing? Or will we be able to make 60 API calls for each mailbox/calendar? (I would expect the latter)

    1. Yes it will apply to those applications as well, but remember the restrictions are per mailbox, so you would get the quota for each mailbox, it wouldn’t be shared.

      1. Simon says:

        Meaning that doing data discovery on a server will always take as long as the largest mailbox with no way to speed up processing with additional resources.

        Doesn’t matter how large or small the company is, if one person has a million items in their mailbox (and that’s not as high as the published limit of 1M messages per mailbox _folder_), it’s going to take 10+ days of riding the limit just to read the messages, let alone any attachments, etc…

        I’m not sure who came up with this rate limiting implementation, but I think they’re quite a long way out of their depth.

        I’m assuming you don’t just throw stuff like this at an intern then walk away? Someone professing to be a competent engineer actually signed off on this?

  12. Adam Webb says:

    We are currently developing against the Microsoft Graph API and being throttled (429 responses), but we do not see any of the documented “retry” headers in either the successful or throttled responses. Is this expected?

    1. Adam Webb says:

      Obviously, as a result, we can determine how to react to the throttling, apart from backing off for an arbitrary period of time.

      1. What API are you accessing when you get the 429?

        1. Adam Webb says:

          Thanks for the quick reply, Jason.

          Below are the details:

          URI :{userId}/Messages/{messageId}

          Response Headers Returned : Transfer-Encoding=chunked,request-id=9965ccce-08a5-4873-9603-a5abea554cda,client-request-id=9965ccce-08a5-4873-9603-a5abea554cda,x-ms-ags-diagnostic={“ServerInfo”:{“DataCenter”:”West US”,”Slice”:”SliceA”,”ScaleUnit”:”000″,”Host”:”AGSFE_IN_9″,”ADSiteName”:”WST”}},Duration=106.2997,Cache-Control=private,Date=Fri, 04 Aug 2017 04:37:07 GMT,

        2. Adam Webb says:

          Hi Jason,

          Any insight into the missing headers?


  13. Dotan says:

    Is there anything similar for management api?

  14. Hi Jason,

    Too good article on rate limits and throttling.

    I was trying to get the throttle error on Graph API’s, so that I can implement the handler for the same.
    I was hitting 50k requests parallel. Using the console application with six different console application instances.
    So I was hitting almost 50k X 6 = 3 lac request at a time using waitAll, though I was not able to get the single failed request.
    Could you please assist me on this.

    I was using{UserID})/mailFolders({FolderID})?$select=displayName

    Find out my code snippet,

    string accessToken = “bla bla accessToken”;
    Uri usersURI = new Uri(“‘bla bla userid ‘)/mailFolders(‘bla bla mail folder’)?$select=displayName”);

    List TaskList = new List();

    Stopwatch watch = new Stopwatch();
    for (int i = 1; i < 50000; i++)
    IRequest request = new Request(usersURI).Authorization(accessToken).Method(HttpMethod.Get);
    request.ContentType = "application/json";

    //var response = await handler.ExecuteAsync(request);
    //Console.WriteLine($”Iteration #{i} : Status Code : {response.StatusCode}”);
    //if (response.StatusCode != System.Net.HttpStatusCode.OK)
    // Console.WriteLine($”ContentString #{i} : {response.ContentString}”);

    request.Timeout = TimeSpan.FromHours(1);
    Task cloudFolder = handler.ExecuteAsync(request);

    if (TaskList.Any(t => t.IsFaulted) || TaskList.Any(t => t.IsCanceled))
    Console.WriteLine($”Requests canceled count :{ TaskList.Count(t => t.IsCanceled) }”);
    Console.WriteLine($”Requests faulted count :{ TaskList.Count(t => t.IsFaulted) }”);

    Console.WriteLine($”Time Elapsed : {watch.Elapsed.TotalSeconds}”);


    1. Per the update to the article, we’re not currently enforcing a limit.

  15. Mitchell says:

    Where can I find the limits for the other O365 apps (OneDrive, SharePoint etc.)?

  16. Vinay says:

    Does $top work with delta queries? I was trying to increase the number of items being returned using $top when performing delta queries, but $top does not seem to have any effect.

    Can you please let us know technical details to increase items per page when using delta queries? Thanks.

Skip to main content