In some cases Search and Navigation will relay 429(Too Many Requests) exceptions. This occurs when the QPS limit of an index is exceeded. The purpose is to prevent too many requests on the search backend which would adversely affect search availability.
See the below answers to frequently asked questions on 429 exceptions.
To prevent an excessive number of requests to the search backend. Doing this helps prevent load issues which increases the odds of future requests completing.
How can 429 errors be prevented?
One way to prevent 429 errors is proper Find caching.
If 429s occur during indexing, the batch size can be increased.
Even when caching is implemented there can be issues as identified in this blog.
Caching should be verified using Fiddler.
If multiple searches can be combined into one, multisearch can be used.
What is the criteria for when a 429 exception is returned by Search and Navigation?
In the search backend there is a "window" variable. It is the duration during which the number of requests are counted and the average QPS is decided based off that window. Currently the window is 5 seconds at the time of this writing(3/13/2020) but is subject to change. The QPS limit is typically 50 for DxC customers but may vary and can be confirmed through a request to email@example.com.
Consider the following example.
So the average QPS for 5 seconds is 42.6 ((55+52+21+40+45)/5). On the 6th second we remove the 1st "bucket" so the value will be: 50.6 ((52+21+40+45+95)/5), exceeding a QPS limit of 50.
What types of requests are counted against the QPS limit?
All find requests including but not limited to the following.
Is the retry-after header used when the QPS limit is hit?
As of this time they are not.
How can I see what requests are producing the 429 errors?
If you have access to logs(Application Insights > logs) you can do this from the Azure portal. The following query will provide the top 5 requests which produced 429 errors. Replace usea01.find.episerver.net with the hostname in the service URL.
| project timestamp, operation_Id, name
| where resultCode == 429
| where target == 'usea01.find.episerver.net'
) on operation_Id
| summarize opCount = count() by name
| top 5 by opCount desc
If you do not have access, support should be able to provide the results from the query assuming the account is from DxP.