> ## Documentation Index
> Fetch the complete documentation index at: https://ngrok.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# How to Rate Limit Traffic

> Learn how to rate limit requests using Traffic Policy with examples for endpoint-based, IP-based, and key-based rate limiting.

With Traffic Policy, you can rate limit requests to your endpoints based on a variety of criteria. This page demonstrates a few example rules that do so.

See [the `rate-limit` Traffic Policy action docs](/traffic-policy/actions/rate-limit/) for more information.

## By endpoint

This rule applies rate limiting of 30 requests per minute to the endpoint `/api/videos`.

<CodeGroup>
  ```yaml policy.yml theme={null}
  on_http_request:
  - expressions:
    - req.url.contains('/api/specific_endpoint')
    actions:
    - type: rate-limit
      config:
        name: Only allow 30 requests per minute
        algorithm: sliding_window
        capacity: 30
        rate: 60s
        bucket_key:
        - conn.client_ip
  ```

  ```json policy.json theme={null}
  {
    "on_http_request": [
      {
        "expressions": [
          "req.url.contains('/api/specific_endpoint')"
        ],
        "actions": [
          {
            "type": "rate-limit",
            "config": {
              "name": "Only allow 30 requests per minute",
              "algorithm": "sliding_window",
              "capacity": 30,
              "rate": "60s",
              "bucket_key": [
                "conn.client_ip"
              ]
            }
          }
        ]
      }
    ]
  }
  ```
</CodeGroup>

## Based on authentication status

This rule creates a lower rate limit for unauthenticated (likely free) users, while allowing authenticated users a higher level of capacity.

<CodeGroup>
  ```yaml policy.yml theme={null}
  on_http_request:
  - expressions:
    - "!('Authorization' in req.headers)"
    name: Unauthorized rate limiting tier
    actions:
    - type: rate-limit
      config:
        name: Allow 10 requests per minute
        algorithm: sliding_window
        capacity: 10
        rate: 60s
        bucket_key:
        - conn.client_ip
  - expressions:
    - "('Authorization' in req.headers)"
    name: Authorized rate limiting tier
    actions:
    - type: rate-limit
      config:
        name: Allow 100 requests per minute
        algorithm: sliding_window
        capacity: 100
        rate: 60s
        bucket_key:
        - conn.client_ip
  ```

  ```json policy.json theme={null}
  {
    "on_http_request": [
      {
        "expressions": [
          "!('Authorization' in req.headers)"
        ],
        "name": "Unauthorized rate limiting tier",
        "actions": [
          {
            "type": "rate-limit",
            "config": {
              "name": "Allow 10 requests per minute",
              "algorithm": "sliding_window",
              "capacity": 10,
              "rate": "60s",
              "bucket_key": [
                "conn.client_ip"
              ]
            }
          }
        ]
      },
      {
        "expressions": [
          "('Authorization' in req.headers)"
        ],
        "name": "Authorized rate limiting tier",
        "actions": [
          {
            "type": "rate-limit",
            "config": {
              "name": "Allow 100 requests per minute",
              "algorithm": "sliding_window",
              "capacity": 100,
              "rate": "60s",
              "bucket_key": [
                "conn.client_ip"
              ]
            }
          }
        ]
      }
    ]
  }
  ```
</CodeGroup>

## Based on pricing tiers

Using a naming scheme in your upstream servers with API calls using a `tier` header, you can quickly customize access to your API based on any number of pricing tiers.

This rule checks for a `Tier` header in the request and applies rate limiting based on the value of that header.

<CodeGroup>
  ```yaml policy.yml theme={null}
  on_http_request:
  - expressions:
    - "!('Tier' in req.headers)"
    name: Free rate limiting tier
    actions:
    - type: rate-limit
      config:
        name: Allow 10 requests per minute
        algorithm: sliding_window
        capacity: 10
        rate: 60s
        bucket_key:
        - conn.client_ip
  - expressions:
    - getReqHeader('tier').exists(v, v.matches('(?i)bronze'))
    name: Bronze rate limiting tier
    actions:
    - type: rate-limit
      config:
        name: Allow 100 requests per minute
        algorithm: sliding_window
        capacity: 100
        rate: 60s
        bucket_key:
        - conn.client_ip
  - expressions:
    - getReqHeader('tier').exists(v, v.matches('(?i)silver'))
    name: Silver rate limiting tier
    actions:
    - type: rate-limit
      config:
        name: Allow 1000 requests per minute
        algorithm: sliding_window
        capacity: 1000
        rate: 60s
        bucket_key:
        - conn.client_ip
  - expressions:
    - getReqHeader('tier').exists(v, v.matches('(?i)gold'))
    name: Gold rate limiting tier
    actions:
    - type: rate-limit
      config:
        name: Allow 10000 requests per minute
        algorithm: sliding_window
        capacity: 10000
        rate: 60s
        bucket_key:
        - conn.client_ip
  ```

  ```json policy.json theme={null}
  {
    "on_http_request": [
      {
        "expressions": [
          "!('Tier' in req.headers)"
        ],
        "name": "Free rate limiting tier",
        "actions": [
          {
            "type": "rate-limit",
            "config": {
              "name": "Allow 10 requests per minute",
              "algorithm": "sliding_window",
              "capacity": 10,
              "rate": "60s",
              "bucket_key": [
                "conn.client_ip"
              ]
            }
          }
        ]
      },
      {
        "expressions": [
          "getReqHeader('tier').exists(v, v.matches('(?i)bronze'))"
        ],
        "name": "Bronze rate limiting tier",
        "actions": [
          {
            "type": "rate-limit",
            "config": {
              "name": "Allow 100 requests per minute",
              "algorithm": "sliding_window",
              "capacity": 100,
              "rate": "60s",
              "bucket_key": [
                "conn.client_ip"
              ]
            }
          }
        ]
      },
      {
        "expressions": [
          "getReqHeader('tier').exists(v, v.matches('(?i)silver'))"
        ],
        "name": "Silver rate limiting tier",
        "actions": [
          {
            "type": "rate-limit",
            "config": {
              "name": "Allow 1000 requests per minute",
              "algorithm": "sliding_window",
              "capacity": 1000,
              "rate": "60s",
              "bucket_key": [
                "conn.client_ip"
              ]
            }
          }
        ]
      },
      {
        "expressions": [
          "getReqHeader('tier').exists(v, v.matches('(?i)gold'))"
        ],
        "name": "Gold rate limiting tier",
        "actions": [
          {
            "type": "rate-limit",
            "config": {
              "name": "Allow 10000 requests per minute",
              "algorithm": "sliding_window",
              "capacity": 10000,
              "rate": "60s",
              "bucket_key": [
                "conn.client_ip"
              ]
            }
          }
        ]
      }
    ]
  }
  ```
</CodeGroup>
