1

We are using Outlook REST API for an app which has most of the functions of a modern web client, those include quite a lot of ops on conversations like loading the conversations in a folder, moving and deleting conversations, etc.

I did come across this question when I was researching our options Best way to achieve Conversation view for mail folder using Outlook REST API

It seems like there is no development on the possible "conversations" endpoint, so at the moment we have to do quite a lot of requests to allow the users to work with conversations. For example to delete a conversation we need to get the conversations messages via a filter on ConversationId, (which might be quite a few) and then make a request to /delete endpoint for each message. We do use batch requests as recommended but I am not sure if they actually make it better or worst. We keep getting the "503 : ErrorMailboxStoreUnavailable - MapiExceptionRpcServerTooBusy:" error for some of out Office365 users.

It is hard to say exactly why the error occurs since there is very little information on how to determine how your app is performing and what the limits are in the first place.

I definitely don't think we hit the REST API limits described here: (10000 requests per 10-minute period, per user)

https://blogs.msdn.microsoft.com/exchangedev/2017/04/07/throttling-coming-to-outlook-api-and-microsoft-graph/

I also checked the Rate-Limit-Limit and Rate-Limit-Remaining headers and they look fine.

However, there seems to be some problem with simultaneous requests, and I suspect the might be related to the limits described here:

https://msdn.microsoft.com/en-us/library/office/jj945066(v=exchg.150).aspx

I am not an expert in Exchange so it is really difficult for me to identify the problem. Also, I couldn't find information about the relationship between the rest API limits and the Exchange limits. For example, is it possible for 2 batch requests of 20 requests each to break this limit: EWSMaxConcurrency (27 for excel online according to the document)

Looking at our logs, my first guess was that those conversation related requests are just too greedy.

Are there any guidelines we could follow to solve this situation?

I am going to paste the error here in case it helps. Thanks!

503. {"error":{"code":"ErrorMailboxStoreUnavailable","message":"The mailbox database is temporarily unavailable., MapiExceptionRpcServerTooBusy: Unable to get properties on object. (hr=0x80004005, ec=2419)
Diagnostic context:
    ......
    Lid: 64625   StoreEc: 0x97F     
    Lid: 52788  
    Lid: 55847   EMSMDBPOOL.EcPoolSessionDoRpc called [length=117]
    Lid: 43559   EMSMDBPOOL.EcPoolSessionDoRpc returned [ec=0x97F][length=522][latency=1015]
    Lid: 32881   StoreEc: 0x97F     
    Lid: 50035  
    Lid: 64625   StoreEc: 0x97F     
    Lid: 52788  
    Lid: 55847   EMSMDBPOOL.EcPoolSessionDoRpc called [length=117]
    Lid: 43559   EMSMDBPOOL.EcPoolSessionDoRpc returned [ec=0x97F][length=522][latency=1000]
    Lid: 32881   StoreEc: 0x97F     
    Lid: 50035  
    Lid: 64625   StoreEc: 0x97F     
    Lid: 52788  
    Lid: 55847   EMSMDBPOOL.EcPoolSessionDoRpc called [length=117]
    Lid: 43559   EMSMDBPOOL.EcPoolSessionDoRpc returned [ec=0x97F][length=522][latency=1015]
    Lid: 32881   StoreEc: 0x97F     
    Lid: 50035  
    Lid: 64625   StoreEc: 0x97F     
    Lid: 52788  
    Lid: 55847   EMSMDBPOOL.EcPoolSessionDoRpc called [length=117]
    Lid: 43559   EMSMDBPOOL.EcPoolSessionDoRpc returned [ec=0x97F][length=522][latency=1015]
    Lid: 32881   StoreEc: 0x97F     
    Lid: 50035  
    Lid: 64625   StoreEc: 0x97F     
    Lid: 63028  
    Lid: 52176   ClientVersion: 15.20.527.7
    Lid: 50032   ServerVersion: 15.20.527.6000
    Lid: 50128  
    Lid: 1494    ---- Remote Context Beg ----
    Lid: 48506   StoreEc: 0x80040401
    Lid: 32796   StoreEc: 0x80040401
    Lid: 43632   StoreEc: 0x80040401
    Lid: 61692   StoreEc: 0x80040401
    Lid: 34356   StoreEc: 0x97F     
    Lid: 1750    ---- Remote Context End ----
    Lid: 1494    ---- Remote Context Beg ----
    Lid: 48506   StoreEc: 0x80040401
    Lid: 32796   StoreEc: 0x80040401
    Lid: 43632   StoreEc: 0x80040401
    Lid: 61692   StoreEc: 0x80040401
    Lid: 34356   StoreEc: 0x97F     
    Lid: 1750    ---- Remote Context End ----
    Lid: 50288  
    Lid: 23354   StoreEc: 0x973     
    Lid: 35180  
    Lid: 25913  
    Lid: 21817   ROP Failure: 0x973     
    Lid: 20385  
    Lid: 28577   StoreEc: 0x973     
    Lid: 32001  
    Lid: 29953   StoreEc: 0x973     
    Lid: 32768  
    Lid: 33024   StoreEc: 0x973     "}
  • Thanks to @Steve Peschka for the response. I believe something like this is in place but I struggle to predict what will consume more "units of service resource". For example, is it better to make one search request with filtering on a few parameters and sorting, which might be a little heavier on the database or two consecuent simpler requests - like single field search + resource request? Should we take into account the complexity of the search at all? – Yordana Dekova Mar 03 '18 at 11:25

1 Answers1

0

Not sure how much this will help, but FWIW. I asked a similar question one time with respect to batching operations and its impact on throttling, and got this answer back from one of the PMs that work in that area:

Whether it is a batch API call or a single API call, we decide to throttle or not throttle based on resources it consumes of our service, and not on # of calls. So, we don’t penalize an app for batching API requests. For example, if 5 API calls take 20 units of our service resources, and you make a batch call with the 5 APIs, we would treat it the same i.e. 20 units of service resource. In this example, I am ignoring the difference between the overhead of processing the batch request, and processing 5 individual requests. In reality, the batch request will be a little cheaper than 5 individual requests.

Steve Peschka
  • 1,015
  • 11
  • 25