Rate limiting
Rate limit your sites with highly-customizable rate limiting rules, which you can apply across your team’s sites in rulesets defined in the Netlify UI. You can also define rules in your site’s code for a specific deploy or site.
Rate limiting is a part of Netlify Advanced Web Security, which offers extra security features designed for enterprise and advanced security needs.
Note that rate limiting rules are evaluated after Firewall Traffic Rules and Web Application Firewall (WAF) rules. Learn more about rule precedence.
# Overview
As a Team Owner, you can create rate limiting rules in the following ways:
- in rulesets you create in the Netlify UI, which you can then apply to a site’s published or unpublished deploys
- in your site’s code for redirects, functions and edge functions
Here are some general guidelines that may help you decide how and when to set up these rules:
- Set up rate limiting rules in the Netlify UI to establish rules across all new and existing sites in your team quickly with a team policy and get more help setting up your rulesets. Track ruleset changes in your audit log.
- Set up programmatic rate limiting rules in your site’s code to test out rules for a single deploy before merging into your production branch and to track rate limiting rule changes in code. You can add rules in the code for redirects, serverless functions, or edge functions. Note that if a deploy has its own unique rate limiting rules committed in code, these will take precedence over other rate limiting rules created in the Netlify UI. Learn more about rule evaluation order.
Learn more about rate limiting rules set in the UI and programmatic rate limiting rules.
# Use cases
- Mitigate a DDoS attack. While Netlify offers automatic DDoS detection, rate limiting, and blocking to keep your site reliable, you can now preemptively customize rate limiting rules for your site and apply these rules to all sites in your team by default with a team policy. Note that Netlify’s automatic DDoS protection can activate before your own custom limits are triggered.
- Protect your backend. Protect your site’s backend by limiting traffic for all requests to your site instead of just requests from certain IP addresses. This helps your site avoid server crashes and slow response times.
- Prevent web scraping. Limit requests from a single IP address or user agent to preserve content integrity and prevent unauthorized access to sensitive information.
- Enforce fair API usage. Limit the number of API calls that a client can make within a 60 second period to prevent API abuse and keep the API available and high-performing for all.
- Reduce bot traffic. Prioritize requests from real site visitors by limiting requests from bots that can overwhelm the server. This is especially important during times of high traffic, such as for flash sales, promotions, or viral content.
- Optimize bandwidth usage. Limit requests that use up a lot of bandwidth, such as requests to access articles and media files, and requests related to data transfer.
- Target a malicious actor. Limit requests to your site based on the number of requests to a domain from a certain IP address.
# Examples
For more detailed examples of how to set up a rate limit rule for different use cases, check out our official Developer Hub guide on safeguarding your sites from abuse.
# Set rate limiting rules in UI
Define and manage rate limiting rules in the Netlify UI. To ensure that a ruleset is always applied to your team’s sites, you can set up a team policy in the UI that enforces a ruleset for all new and existing sites.
When you configure rate limit rules in the UI, you can specify what action should occur when a rate limit is triggered:
- Block: this action blocks requests with a standard 429 status code.
- Rewrite to path: this action rewrites the request path with a new relative path that you specify. For example, you can rewrite requests to your own customized rate limit error page with a relative path such as
/rate_limit_page.html
.
When a Team Owner creates, edits, deletes, or applies a rate limiting ruleset in the Netlify UI, these actions are logged in the Team audit log. Rate limit rules are read-only
for the Developer role.
# Rule conditions defined in the UI
Optimize your rate limiting rules for different use cases with different rule conditions, which define when a rate limit rule is triggered.
You can trigger a rate limit rule when values match or equal one or more of the following:
- Connection IP address
- Geolocation
- Request path
- Cookie
- HTTP header
Below are some rule condition triggers and examples of the values they accept in the UI.
Rule condition trigger | Supported value format | Examples |
---|---|---|
Connection IP | IP address of either the user accessing the site or the proxy set up to access the site in CIDR notation | 155.255.355.0/24 |
Geolocation | Text | Enter a country name, then select a country/subregion |
Path | Text or regex | /api/v1/.* For requests that proxy to an API |
Cookie | Text or regex | Set session_key to match .* value Will match requests with a session_key value, even if the value for that key is empty |
HTTP Header | Text or regex | Set Authorization Header to match a specific API token value Bearer ABUSIVE_TOKEN Can set up a rule that rate limits a specific API token |
# Published and unpublished deploys
Optimize your rate limiting rules for published or unpublished deploys.
A published deploy is the current live deploy at a site’s main URL. Once a different deploy becomes live at the site’s main URL, that deploy becomes the published deploy for that site.
An unpublished deploy can be a Deploy Preview, a branch deploy, or any other deploy not published at your site’s main URL, such as a new production deploy that has not published because you locked an older published deploy.
Learn more in our deploys docs.
# Limitations
The rate limiting feature includes these limits:
- Each ruleset must have at least 1 rule.
- 100 rules maximum per ruleset.
- A maximum of 2 rate limiting rulesets can be set per site — one for published deploys and one for unpublished deploys. You can apply the same ruleset to both or use two different ones.
# How request counts are calculated
By default, Netlify calculates requests globally instead of by region. To set a limit for a specific region, you can add rule conditions that specify the geolocation/subregion you want the rule to apply to.
You can specify how you’d like Netlify to count requests for each rule with our request aggregation options in the Netlify UI.
When calculating requests, there may be a window of time between when a client passes a limit and when Netlify starts enforcing the limit. This latency is minor and expected to be less than a second. Adding rules to your site won’t impact latency when serving assets.
Given all the variations in traffic patterns, we recommend you try different settings to find what works best for your site and site visitors. Some experimentation is especially helpful when considering how much you want to optimize a site’s rate limiting to enforce a hard limit versus a more approximate limit.
# Request aggregation options
When creating a rule in the Netlify UI, under Request aggregation, you can choose between two different ways to calculate requests:
Per domain (default): all site visitors are limited to a shared limit with a specified number of requests per 60 seconds. This option is good for protecting your backend no matter who is visiting your site.
Per domain and IP address: each site visitor is limited to a specified number of requests per 60 seconds. This option is good for targeting potential bad actors.
# Request calculation for rate limiting per domain
When you rate limit by domain, once the number of requests goes above the limit during specified time period, then we start banning the IPs with the highest rate.
For example, if you set a limit of 300 requests, once the site reaches that limit, we ban the IP address with the highest request rate. We then adjust the currently counted requests with the traffic we’ve just banned, so other lower rate IPs are not affected.
This means you may notice more than 300 requests for that time interval because, by banning those high rate IPs, there’s more request budget for other lower rate IPs. This continues until the request rate is under the defined limit.
So if one IP address is behind most of the traffic, then you may detect a seesaw (repeated up and down) traffic pattern in your web traffic monitoring tools.
When calculating the request count, Netlify assigns a weight to IP addresses based on the number of requests and how recently the requests were made. This allows Netlify to prioritize rate limiting IP addresses that are currently generating the largest amount of traffic until the desired limit is reached.
# Example request calculation for set of rules
To explain how we calculate requests, here’s an example of ruleset:
Rule 1: Protect homepage
- Rule triggered when requests match path
/index.html
- Limit: 10 requests per 60 seconds
- Action: Block and return 429 error
- Request aggregation: By domain (default)
Rule 2: Limit known API abusers
- Rule triggered when requests have the header
Authorization
that equalsBearer ABUSIVE-TOKEN
. - Limit: 5 requests per 60 seconds
- Action: Block and return 429 error
- Request aggregation: By domain (default)
If the example ruleset above is applied to your site and your site has requests to path /index.html
with an Authorization
header with the same Bearer ABUSIVE-TOKEN
value from rule 2, then we will count requests for both rules and start applying the first rule that has been triggered, by order of the definition you set in the UI.
- If there are 7 requests per 60 seconds, then rule 2 is applied since rule 1’s threshold hasn’t been crossed
- If there are 10 requests per 60 seconds, then rule 2 is applied, since rule 1’s threshold hasn’t been crossed (you need 11 requests to cross it)
- If there are 20 requests per 60 seconds, then rule 1 is applied, since rule 1’s threshold has been crossed and is defined first. Although, rule 2 is triggered as well with 20 requests, we only apply one action (block with a 429 status code) per request.
# Manage rulesets in the UI
Rate limiting rules are managed in rulesets, which can be edited and applied to sites. Any changes in a ruleset take effect on all sites where the ruleset applies.
Only Team Owners can create, edit, or delete a ruleset.
A site can have a maximum of two rulesets applied, one for published deploys and one for unpublished deploys.
Learn more in the next sections:
# Create a ruleset
To create a ruleset:
As a Team Owner, go to
.Select Create ruleset.
Enter your ruleset name and description.
Select Add a rule and follow the prompts. You can add up to 100 rules for a ruleset. When you add a rule, you can specify the following:
- Rule condition: defines when the rule is triggered. For an overview of your options, check out the rule conditions table.
- Limit: defines the number of requests allowed per 60 seconds.
- Request aggregation: defines how we calculate and apply the limit for your rule. Includes Per domain (default) (ideal to protect your site’s backend) or Per domain and IP address (ideal to target a potential bad actor).
- Action: defines what happens when the rate limit threshold is crossed. The action is applied for 60 seconds. Currently supports these actions:
- Block: this action blocks access to the site and returns a
429
status code. - Rewrite to path: this action rewrites the request path with a new relative path that you specify. For example, you can rewrite requests to your own customized rate limit error page with a relative path such as
/rate_limit_page.html
.
- Block: this action blocks access to the site and returns a
Confirm your rule by selecting Add rule.
Optionally, repeat steps 4 and 5 to add more rules to your ruleset as needed.
Save your ruleset.
Next, you can make your ruleset the team policy or apply it to an individual site.
# Edit a ruleset
To edit a ruleset:
As a Team Owner, go to
.From your Team rulesets, select the ruleset you want to edit.
Under your ruleset description, choose Edit ruleset.
Make your changes and save.
Your ruleset’s updates will take effect in all sites where the ruleset is applied.
# Delete a ruleset
To delete a ruleset:
As a Team Owner, go to
.From your Team rulesets, select the ruleset you want to delete.
Under your ruleset description, choose Delete ruleset.
The ruleset will no longer apply to your sites.
# Apply a ruleset to a site
Only Team Owners can apply a ruleset to a site from the Site Configuration page in the Netlify UI.
To apply a ruleset to a site:
For the desired site, go to
.Under Rulesets for [site name], select Manage rulesets.
Choose a ruleset option to apply to your site’s published deploys and/or unpublished deploys and select Save. If you already have a team policy ruleset configured, then you can override the team policy ruleset with a different ruleset.
# Configure a team policy ruleset in the UI
To rate limit your team’s sites with a default ruleset, configure a team policy for your site’s published deploys and/or unpublished deploys.
The team policy ruleset applies to all new and existing sites in your team. A Team Owner can override the team policy ruleset with a different ruleset for one site at a time.
A maximum of 2 rate limiting rulesets can be set per site — one for published deploys and one for unpublished deploys. You can apply the same ruleset to both or use two different ones.
As a Team Owner, to configure a team policy:
Go to
.Select Configure team policy.
Choose a ruleset option for published deploys and/or unpublished deploys, then save your changes.
# Set rate limiting rules in code
Set up programmatic rate limiting rules in your site code to do the following:
- supplement the rules you enforce through the Netlify UI
- manage your rules in code using version control
- test out some rules for a single deploy before these rules apply across your site for multiple deploys
You can define programmatic rate limiting rules in your site’s code for redirects, functions and edge functions.
Note that Netlify calculates requests globally instead of by region for programmatic rules, just like Netlify does for rules defined in the Netlify UI.
# Rule evaluation order
Programmatic rate limiting rules are activated and enforced before any rate limiting rulesets that are defined in the Netlify UI.
Netlify evaluates rate limiting rules in this order:
- Edge functions
- Serverless functions
- Redirects
- Rulesets defined in the Netlify UI
# Define a limit in code
The same general rate limiting calculations apply. Note that a programmatic rate limiting rule can only execute on the path you’ve defined for that rule.
For example, if you set up the following:
- a function on path
/function_path
with a rate limit rule - a rewrite rule on path
/rewrite_path
that rewrites tofunction_path
Then this is how requests to our CDN will result:
- The rate limit rule is applied when there’s a request to
/function_path
- The rate limit rule is not applied when there's a request to
/rewrite_path
# Define a limit for a redirect rule
In this example, there’s a redirect rule defined in a netlify.toml
file:
from = "/some-path"
to = "/function-path"
status = 200
[redirects.rate_limit]
window_limit = 50
In this redirect rule example, there is a limit of 50 requests for every 60 seconds.
# Define a limit for a function
In this example, a programmatic rate limit rule is defined for a function:
export default async (request: Request, context: Context) => {
// ...
};
export const config: Config = {
path: "/function-path",
ratelimit: {
windowLimit: 100
}
};
# Calculate a limit for a function and redirect rule
If you have programmatic rate limiting rules set up for the function and redirect examples shared above, then this is the order that Netlify enforces them:
- If a request hits our CDN on
/some-path
, the 50 request limit applies - If a request hits our CDN on
/function-path
, the 100 request limit applies - If there’s another function also on
/some-path
, both that function’s limit and the redirect limit apply.
# Track rules in the build log
You can find programmatic rules definitions for a relevant deploy and any related errors in your build log under Post-processing.
Note the following:
- An error for a programmatic rule definition cannot make the build fail.
- If your build fails for a deploy, then programmatic rules for that deploy will not apply.
# Redirect examples
Programmatic rate limiting rules for redirects are only supported for redirects defined in netlify.toml
and not those defined in a _redirects
file.
In this example, there’s a proxy redirect rule to an external API that you own. You can define a rate limit rule directly within your redirect definition, which will protect your API against unexpected increases in traffic. Here there’s a defined limit of 50 requests per client IP for every window length (each window is 60 seconds).
# use-case: protecting external proxy
[[redirects]]
from = "/search"
to = "https://api.mysearch.com"
status = 200
force = true
[redirects.rate_limit]
window_limit = 50
aggregate_by = ["ip", "domain"] # optional, will default to "domain" only
# use-case: protecting entire site
[[redirects]]
from = "/*"
to = "/:splat"
[redirects.rate_limit]
action = "rewrite" # optional, will default to "rate_limit"
to = "/custom_rate_limit.html" # only needed if action is "rewrite"
window_limit = 50
aggregate_by = ["domain"]
# Function & edge function examples
Functions must have a path
defined in the config
export of the function, otherwise the custom rate limit will not be evaluated. We do not support rate limiting rules defined in the netlify.toml
file.
In these examples, an edge function and serverless function are invoked on the root path of the site. To avoid unexpected overages on compute usage, we define a rate limit of 100 requests per client IP for every window length (each window is 60 seconds). Once a client is limited, it will be blocked and no invocation will occur.
import type { Config, Context } from "@netlify/edge-functions";
// use-case: safeguarding your edge function usage/spend
export default async (request: Request, context: Context) => {
// ...
};
export const config: Config = {
path: "/",
rateLimit: {
windowLimit: 100,
aggregateBy: ["ip", "domain"],
}
};
// same use-case
export default async (request: Request, context: Context) => {
// ...
};
export const config: Config = {
path: "/",
rateLimit: {
action: "rewrite" // optional, will default to "rate_limit"
to: "/custom_rate_limit.html", // only needed if action is "rewrite"
windowLimit: 100,
aggregateBy: ["ip", "domain"],
}
};
import type { Config, Context } from "@netlify/functions"
// use-case: safeguarding your serverless function usage/spend
export default async (request: Request, context: Context) => {
// ...
};
export const config: Config = {
path: "/",
rateLimit: {
windowLimit: 100,
aggregateBy: ["ip", "domain"],
}
};
// same use-case
export default async (request: Request, context: Context) => {
// ...
};
export const config: Config = {
path: "/",
rateLimit: {
action: "rewrite" // optional, will default to "rate_limit"
to: "/custom_rate_limit.html", // only needed if action is "rewrite"
windowLimit: 100,
aggregateBy: ["ip", "domain"],
}
};
Did you find this doc useful?
Your feedback helps us improve our docs.