Security /Secure access to sites /

Rate limiting

This feature is available on Enterprise plans and requires High-Performance Edge.

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.

# Overview

As a Team Owner, you can create rate limiting rules in the following ways:

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 equals Bearer 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:

  1. As a Team Owner, go to

    .

  2. Select Create ruleset.

  3. Enter your ruleset name and description.

  4. 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.
  5. Confirm your rule by selecting Add rule.

  6. Optionally, repeat steps 4 and 5 to add more rules to your ruleset as needed.

  7. 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:

  1. As a Team Owner, go to

    .

  2. From your Team rulesets, select the ruleset you want to edit.

  3. Under your ruleset description, choose Edit ruleset.

  4. 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:

  1. As a Team Owner, go to

    .

  2. From your Team rulesets, select the ruleset you want to delete.

  3. 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:

  1. For the desired site, go to

    .

  2. Under Rulesets for [site name], select Manage rulesets.

  3. 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:

  1. Go to

    .

  2. Select Configure team policy.

  3. 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:

  1. Edge functions
  2. Serverless functions
  3. Redirects
  4. 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 to function_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:

  1. If a request hits our CDN on /some-path, the 50 request limit applies
  2. If a request hits our CDN on /function-path, the 100 request limit applies
  3. 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"],
  }
};