Error request rate limited



Error: 429 Too Many Requests — You’ve been rate limited

Your application is running smoothly. Tests have passed. Suddenly you start to see 429 error responses from an API. As the name implies, you have made too many requests and your application has been rate limited. The 429 (Too Many Requests) error is an HTTP status code that often occurs when you’ve hit a request limitation of an API.

While rate limiting may seem like a bad thing when you encounter it, this restriction is a protective feature of most consumable APIs. Rate limits prevent services from intentional abuse, as well as accidental abuse that may occur when developers are testing applications. If you’ve ever poured water into a funnel too quickly, you’ve seen it start to back up and eventually overflow. Rate limiting aims to prevent this by stopping the flow of requests before a problem arises.

So what can you, as a developer consuming APIs, do about it? To start, let’s look at what causes the error and how to find the rate limit details for an API.

Rate limit thresholds and how are they triggered

Depending on the type of application you are building, there are a variety of instances where you may run into rate limiting. Bots, and any application that consistently polls an API, are the most likely to run into the error. Applications that directly let users interact with the third-party API are also at higher risk of hitting limits. To learn more about an APIs rate limit threshold, it’s best to check the documentation for the API you are using.

Normally, rate limits are defined by requests over a period of time. For example, GitHub’s v3 REST API has a limit of 5000 requests per hour per authenticated user for authenticated requests. For unauthenticated requests, the limit is 60 requests per hour. These types of limits can either be API-wide, or unique for an endpoint or resource. The Discord API, for example, has unique limits for each endpoint and account. As a result you should avoid hard-coding limits directly into your application.

Another thing to keep in mind is that these time-based limits might be set based on the time of the first request, or may have a fixed timeframe, such as the start of a day.

While many services will publish their limits like in the GitHub example above, others may include limits as a property on responses, or even as a header that only displays when a limit is hit.

Understanding a 429 error response

You’ve seen the error code, but there’s often more information available when your request fails. REST APIs will often include a message describing the problem along with a set of X-RateLimit-* headers with information about the limits. Some APIs, like GitHub’s, will include this on successful requests as well. Each API will have their own specific headers, but a few common rate limit related headers are:

  • X-RateLimit-Limit : The amount of requests that can be made (across a time-frame).
  • X-RateLimit-Remaining : The remaining number of requests that can be made (across a time-frame).
  • X-RateLimit-Reset : A timestamp of when the limit will be reset.

GraphQL APIs will either return an error when a limit is hit, like Yelp’s GraphQL API, or may instead offer a means to check the current usage. GitHub’s v4 Graph API does this by allowing users to query the rateLimit object.

These pre-emptive approaches allows you to perform checks before a limit is hit, rather than only reacting to the error.

How to fix the “Too Many Requests” error

If the API provides you with headers or error objects that include reset information, you can use this to wait the appropriate amount of time before retrying. Take the resetAt — currentTime and use that to wait before making another request. You can even bring this functionality into a circuit breaker, or use a solution like Bearer to retry on certain conditions.

Читайте также:  Exception javax naming noinitialcontextexception cannot instantiate class

If there is no programatic way of knowing how long to wait before trying, you can use the “back-off” approach where your code performs a series of retries with increasing delays between each retry.

How to truly avoid 429 errors

These are fine approaches, but what if you are providing an API that is hitting rate limits on other APIs? In this case, you’ll want to throttle incoming calls to your API in order to prevent rate limits from causing problems. Throttling is a technique that limits code execution. In this case, requests are limited and “dropped” or fulfilled with cached data. This way your app intervenes before the third-party service ever reaches the limit. This approach can also be useful for restricting usage of costly APIs. You can even implement your own rate limiting with more conservative thresholds that will stop your app from ever hitting the limits of the third-party API.

In order to make more informed decisions, it is a good idea to monitor your third-party API usage. Using a tool like Bearer, you can even set rules to notify you when usage reaches a certain point and react to them programmatically.

With all this in mind, your app should be more resilient against the “Too Many Requests” error. Check the Bearer Blog for more articles on building resilient applications and connect with us @BearerSH to tell us how you respond to 429 errors.

If you liked this post, feel free to share this infographic with your team:

Источник

How can we help you today?

Support Portal Categories

How to Resolve Rate Limited Requests (429 Too Many Requests)

Modified on: Thu, 29 Dec, 2022 at 9:03 AM

To protect your Hypernode from all kinds of attacks, bots, brute forces, and scriptkiddies causing downtime, we’ve implemented several layers of rate limiting.

Most of these rate-limit methods only apply to bots. Still, to avoid FPM worker depletion, we implemented a rate-limiting mechanism per IP to prevent one single IP from exhausting the available FPM workers.

This article will explain the differences between the different rate-limiting methods and show you how to find which rate-limiting method applies and, if needed, how to override them.

TABLE OF CONTENTS

Rate Limiting Methods

On Hypernode we currently differentiate between two rate limiting methods and thus so-called zones:

  • Rate limiting based on User Agents and requests per second (zone bots )
  • Rate limiting based on requests per IP address (zone zoneperip )

Both methods are implemented using this module

Determining the Applied Rate Limiting Method

You can quickly determine which method of Rate Limiting was the cause of the request being 429’d since each time any of the rate-limiting methods are hit, a message with be logged in the Nginx error log.

To do so you first look up the request in the access logs, which can be done using the hypernode-parse-nginx-logs (pnl) command: pnl —today —fields time,status,remote_addr,request —filter status=429

Copy the IP address from the output generated by this command and look up the corresponding log entry in the aforementioned Nginx error log with cat /var/log/nginx/error.log | grep «1.2.3.4»

These entries look as follows:

A log entry where rate limit is applied to user-agents and requests per second (based on the bots zone):

A log entry where the rate limit is applied per IP address (based on the zoneperip zone):

Note: Per IP rate limiting only applies to requests handled by PHP and not to the static content.

Rate Limiting for Bots and Crawlers

Every day, your webshop is visited by many different bots and crawlers. While some, like Google, are important, many only have a negative impact on your site, especially if they don’t follow your robots.txt. To protect your Hypernode against negative performance impacts by misbehaving bots, it utilizes an advanced rate-limiting mechanism. This slows down the hit rate for unimportant bots, leaving more performance for the bots you do care about and, more importantly, your actual visitors.

Читайте также:  Ошибка навигатор open registry error

Rejecting 429 Too Many Requests

Since our goal is not to block bots but to rate limit them nicely, we must be careful with how we reject them. As such, the best way to reject them is with the 429 Too Many Requests message. This tells the visiting bot that the site is currently unavailable, but the server is there. This is a temporary state so that they can retry at a later time. This does not negatively influence the ranking in any search engine, as the site is there when the bot connects at a later time.

How to Configure the Bot Rate Limiter

Some bots are default exempt from rate limitings, like Google, Bing, and several monitoring systems. These bots never get rate limited since they usually abide by the robots.txt. However, some bots don’t follow the instructions given in robots.txt or are used by abusive crawlers. These bots will be rate limited at one request per second. Any requests over this limit will then return a 429 error. If you want, you can override the system-wide configuration on who gets blocked and who does not. To get started, place the following in a config file called /data/web/nginx/http.ratelimit :

Note: do not remove the heartbeat entry! As this will break the monitoring of your Hypernode

As you can see, this sorts all visitors into two groups:

  • On the first (whitelist) line, you find the keywords that are exempt from the rate liming, like: ‘google’, ‘bing’, ‘heartbeat’, or ‘monitis.com’
  • On the second (blacklist) line, you will find the keyword for generic and abusive bots and crawlers, which will always be rate limited, like crawler, spider, bot

The keywords are separated by | characters since it is a regular expression.

Whitelisting Additional User Agents

To extend the whitelist, first determine what user agent you wish to add. Use the access log files to see what bots get blocked and which user agent identification it uses. Say the bot we want to add has the User Agent SpecialSnowflakeCrawler 3.1.4 . Which contains the word ‘crawler’, so it matches the second regular expression and is labeled as a bot. Since the whitelist line overrules the blacklist line, the best way to allow this bot is to add their user agent to the whitelist instead of removing ‘crawler’ from the blacklist:

Instead of adding the complete User Agent to the regex, it’s often better to limit it to just an identifying keyword, as shown above. The reason behind this is that the string is evaluated as a Regular Expression, which means that extra care needs to be taken when adding anything other than alphanumeric characters.

Known Rate Limited Plugins and Service Provider

There are a couple of plugins and service providers that tend to hit the blacklisted keyword in the http.ratelimit snippet and, therefore, may need to be excluded individually. Below we have listed them and their User Agents for your convenience

  • Adyen — Jakarta Commons-HttpClient/3.0.1
  • Adyen — Apache-HttpClient/4.4.1 (Java/1.8.0_74)
  • Adyen — Adyen HttpClient 1.0
  • MailPlus — Jersey/2.23.1
  • Mollie — Mollie.nl HTTP client/1.0
  • Screaming — Screaming Frog SEO Spider

Besides the above-known plugins that will hit the blacklisted keyword, http.ratelimit we know that Picqer will also hit the rate limiter because of being blocked by «zoneperip«. Please find here the IP addresses of Picqer. You can exclude those IP addressess from hitting the rate limiter if you follow the instructions.

Читайте также:  What validation error will this code produce

Rate Limiting per IP Address

To prevent a single IP from using all the FPM workers available simultaneously, leaving no workers available for other visitors, we implemented a per IP rate limit mechanism. This mechanism sets a maximum amount of PHP-FPM workers that can be used by one IP to 20. This way, one single IP address cannot deplete all the available FPM workers, leaving other visitors with an error page or a non-responding site.

Please note: if Hypernode Managed Vhosts is enabled, only add the http.conn_ratelimit file in the Nginx root. Don’t add it to the specific vhost as well, as these files will cancel each other out.

Exclude IP Addresses from the per IP Rate Limiting

In some cases, it might be necessary to exclude specific IP addresses from the per IP rate limiting. If you wish to exclude an IP address, you can do so by creating a config file called /data/web/nginx/http.conn_ratelimit with the following content:

In this example, we have excluded the IP address 1.2.3.4 by setting an empty value in the form of » .

In addition to whitelisting one single IP address, it is also possible to whitelist a whole range of IP addresses. You can do this by using the so-called CIDR notation (e.g., 10.0.0.0/24 to whitelist all IP addresses within the range 10.0.0.0 to 10.0.0.255). In that case, you can use the following snippet in /data/web/nginx/http.conn_ratelimit instead:

Disable per IP Rate Limiting

When your shop performance is very poor, it’s possible all your FPM workers are busy just serving regular traffic. Handling a request takes so much time that all workers are continuously depleted by a small number of visitors. We highly recommend optimizing your shop for speed and a temporary upgrade to a bigger plan if this situation arises. Disabling the rate limit will not fix this problem but only change the error message from a Too many requests error to a timeout error.

For debugging purposes, however, it could be helpful to disable the per-IP connection limit for all IP’s. With the following snippet in /data/web/nginx/http.conn_ratelimit , it is possible to altogether disable IP based rate limiting:

Warning: Only use this setting for debugging purposed! Using this setting on production Hypernodes is highly discouraged, as your shop can be easily taken offline by a single IP using slow and/or flood attacks.

Exclude Specific URLs from the per IP Rate Limiting Mechanism

To exclude specific URLs from being rate-limited you can create a file /data/web/nginx/before_redir.ratelimit_exclude with the following content (this could also be done in a http.* file):

In the example above, the URLs */rest/V1/example-call/* and /elasticsearch.php are the ones that have to be excluded. You can now use the $ratelimit_request variable in the file /data/web/nginx/http.conn_ratelimit (see the example below) to exclude these URLs from the rate limiter and make sure that bots and crawlers will still be rate limited based on their User Agent.

How to Serve a Custom Static Error Page to Rate Limited IP Addresses

If you would like to, you may serve a custom error page to IP addresses that are rate limited. Simply create a static HTML file in /data/web/public with any content that you wish to show to these rate-limited IP addresses. Furthermore, you need to create an Nginx configuration file called /data/web/nginx/server.custom_429 as well. The content of this file should be as follows:

This snippet will serve a custom static file called ratelimited.html to IP addresses that are using too many PHP workers.

Warning: Only use a static (HTML) page, as creating a PHP script to render an error will be rate-limited as well, causing an endless loop.

Источник

Оцените статью
toolgir.ru
Adblock
detector