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

# Rate limits

> Learn about Dub's API rate limits.

Dub's API rate limiting is in conformance with the [IETF standard](https://datatracker.ietf.org/doc/html/draft-ietf-httpapi-ratelimit-headers):

| Header Name             | Description                                                                     |
| ----------------------- | ------------------------------------------------------------------------------- |
| `X-RateLimit-Limit`     | The maximum number of requests that the consumer is permitted to make per hour. |
| `X-RateLimit-Remaining` | The number of requests remaining in the current rate limit window.              |
| `X-RateLimit-Reset`     | The time at which the current rate limit window resets in UTC epoch seconds.    |
| `Retry-After`           | The number of seconds to wait before retrying the request again.                |

Dub's API is capped at **60 requests per minute** per key on the Free plan, with elevated limits for [Pro plan](https://dub.co/pricing) and above.

This is implemented to ensure a fair usage policy so that excessive use by a single user does not adversely affect the performance and usage of the API by others.

You'll receive a `429 Too Many Requests` response code if the rate limit is exceeded.

## Rate limits by plan

Depending on your Dub plan, you can expect the following rate limits:

| Plan                                    | Rate limit                                                              |
| --------------------------------------- | ----------------------------------------------------------------------- |
| Free                                    | 60 requests per minute                                                  |
| [Pro](https://dub.co/pricing)           | 600 requests per minute                                                 |
| [Business](https://dub.co/pricing)      | 1,200 requests per minute                                               |
| [Advanced](https://dub.co/pricing)      | 3,000 requests per minute                                               |
| [Enterprise](https://dub.co/enterprise) | Custom – [reach out to sales](https://dub.co/contact/sales) for details |

## Rate limits by endpoint

Dub's [analytics endpoints](/docs/concepts/analytics/introduction) have separate, per-second rate limits to ensure optimal performance:

| Plan                                    | Analytics API rate limit                                                |
| --------------------------------------- | ----------------------------------------------------------------------- |
| Free                                    | N/A                                                                     |
| [Pro](https://dub.co/pricing)           | 2 requests per second                                                   |
| [Business](https://dub.co/pricing)      | 4 requests per second                                                   |
| [Advanced](https://dub.co/pricing)      | 8 requests per second                                                   |
| [Enterprise](https://dub.co/enterprise) | Custom – [reach out to sales](https://dub.co/contact/sales) for details |

Analytics endpoints include:

* [`GET /analytics`](/docs/api-reference/analytics/retrieve) – retrieving aggregated analytics
* [`GET /events`](/docs/api-reference/events/list) – retrieving paginated lists of events

All other API endpoints use the standard rate limits listed in the [Rate limits by plan](#rate-limits-by-plan) section above.

## How to comply with rate limits

Here's how you can optimize your API setup to comply with rate limits:

### 1. Bulk link creation

If you need to create a lot of links within a short period of time, try our [bulk link creation endpoint](/docs/api-reference/links/bulk-create) instead (create up to 100 links in one API call)

<CodeGroup>
  ```javascript Node.js theme={null}
  await dub.links.createMany([
    {
      url: "https://google.com",
    },
    {
      url: "https://twitter.com",
    },
    {
      url: "https://linkedin.com",
    },
  ]);
  ```

  ```python Python theme={null}
  res = d.links.create_many(request=[
    {
      url: "https://google.com",
    },
    {
      url: "https://twitter.com",
    },
    {
      url: "https://linkedin.com",
    },
  ]);
  ```

  ```go Go theme={null}
  var request []operations.RequestBody =
    []operations.RequestBody{
      operations.RequestBody{
          URL: "https://google.com",
      },
      operations.RequestBody{
        URL: "https://twitter.com",
      },
      operations.RequestBody{
        URL: "https://linkedin.com",
      },
    }
  ctx := context.Background()
  res, err := s.Links.CreateMany(ctx, request)
  ```

  ```ruby Ruby theme={null}
  s.links.create_many(
    ::OpenApiSDK::Operations::BulkCreateLinksRequest.new(
      request_body: [
        ::OpenApiSDK::Operations::RequestBody.new(
          url: "https://google.com",
        ),
        ::OpenApiSDK::Operations::RequestBody.new(
          url: "https://twitter.com",
        ),
        ::OpenApiSDK::Operations::RequestBody.new(
          url: "https://linkedin.com",
        ),
      ]
    )
  )
  ```
</CodeGroup>

### 2. Fetch workspace-level analytics

If you're using our [Analytics API](/docs/api-reference/analytics/retrieve), instead of retrieving the clicks count for every single link, try making a single API call to get workspace-level click analytics instead.

<CodeGroup>
  ```javascript Node.js theme={null}
  await dub.analytics.retrieve({
    groupBy: "top_links",
    start: "4 hours ago", // we support natural language for start/end params
  });
  ```

  ```python Python theme={null}
  res = d.analytics.retrieve(request={
      "groupBy": "top_links",
      "start": "4 hours ago", // we support natural language for start/end params
  })
  ```

  ```go Go theme={null}
  func main() {
  	// Retrieve the timeseries analytics for the last 7 days for a link
  	request := operations.RetrieveAnalyticsRequest{
          GroupBy: "top_links",
          Start: "4 hours ago", // we support natural language for start/end params
  	}

  	ctx := context.Background()
  	res, err := d.Analytics.Retrieve(ctx, request)
  	if err != nil {
  		log.Fatal(err)
  	}
  	if res.OneOf != nil {
  		// handle response
  	}
  }
  ```

  ```ruby Ruby theme={null}
  req = ::OpenApiSDK::Operations::RetrieveAnalyticsRequest.new(
    group_by: ::OpenApiSDK::Operations::GroupBy::TOP_LINKS,
    start: "4 hours ago", // we support natural language for start/end params
  )

  res = dub.analytics.retrieve(req)

  puts res.raw_response.body
  ```
</CodeGroup>

### 3. Leverage webhooks

If you're expecting high volume, fast-changing data (e.g. thousands of clicks on your links per day) and would prefer to store the data on your end, we recommend using our [real-time webhooks feature](https://dub.co/blog/introducing-webhooks) instead.

<Frame>
  <img src="https://assets.dub.co/blog/webhook-event-logs.jpg" alt="Webhook event logs" />
</Frame>

[Webhooks](/docs/webhooks/introduction) are *push-based*, meaning that Dub will send events to your webhook receiver endpoint when specific events occur, while a REST API is *pull-based*, meaning that you need to consistently poll the API endpoint to get real-time updates.

Check out our [webhooks documentation](/docs/webhooks/introduction) to learn more.
