diff --git a/docs/guides/rate-limits-legacy.mdx b/docs/guides/rate-limits-legacy.mdx deleted file mode 100644 index 3418f2c9f..000000000 --- a/docs/guides/rate-limits-legacy.mdx +++ /dev/null @@ -1,333 +0,0 @@ ---- -id: rate-limits-legacy -title: Ory Network rate limits - legacy -sidebar_label: Rate limits - legacy ---- - -:::info - -This page describes the legacy project rate limit policy, which applies to existing Ory Network customers who haven't been -migrated to the new rate limit policy yet. If you're a new customer or have already been migrated, see the -[rate limits - new](/docs/guides/rate-limits-new). See [Rate limits](/docs/guides/rate-limits) to learn about both policies and -the migration plan. Endpoint rate limits have not changed. - -::: - -This page provides a high-level overview of the rate limiting mechanisms employed by Ory to ensure system security and -availability. Rate limiting protects your applications against abuse and attacks, prevents service disruptions, and ensures fair -usage for all our customers. - -## Types of rate limits - -Ory implements two main rate limit types: - -- **Project rate limits**: Based on your subscription plan and environment (Production, Staging, or Development). These control - the overall request volume your projects can make to Ory's APIs. -- **Endpoint-based rate limits**: Additional security controls that protect specific endpoints against attacks like brute-force, - credential stuffing, and concurrent request abuse, regardless of your project limits. - -## Project rate limits in workspaces - -With the introduction of workspaces in Ory Network, rate limits are now applied to projects based on their assigned environment -and the workspace's subscription plan. This approach ensures fair resource allocation and maintains the stability of the Ory -Network across different usage scenarios. - -### How project rate limits work in workspaces - -Rate limits for each project are determined by two main factors: - -- Workspace subscription—Your subscription plan (Developer, Production, Growth, or Enterprise) sets the baseline for your rate - limits. -- Project environment—Within each workspace, projects can be assigned to Production, Staging, or Development environments, each - with specific rate limit configurations. - -For a detailed explanation of workspaces and environments, see our [Workspaces and environments guide](/docs/guides/workspaces). - -### Rate limit structure - -Each rate limit policy includes two limits: - -- Burst limit—Maximum requests per second (rps), allowing for short traffic spikes. -- Sustained limit—Maximum requests per minute (rpm), ensuring consistent performance over time. - -## Monitor rate limit headers - -Ory Network includes rate limit information in API response headers. Use these headers to avoid exceeding the applicable rate -limit. Your client must handle these responses to maintain service quality. - -| Header | Description | -| ----------------------- | --------------------------------------------------------------------------------------- | -| `x-ratelimit-limit` | The rate limit ceiling(s) for the current request, including burst and sustained limits | -| `x-ratelimit-remaining` | Number of requests remaining in the current window | -| `x-ratelimit-reset` | Number of seconds until the rate limit window resets | - -Example header values: - -```shell -x-ratelimit-limit: 10, 10;w=1, 300;w=60 -x-ratelimit-remaining: 8 -x-ratelimit-reset: 1 -``` - -The `x-ratelimit-limit` header follows the -[IETF RateLimit header fields draft](https://datatracker.ietf.org/doc/draft-ietf-httpapi-ratelimit-headers/), where `w=1` -indicates a 1-second window and `w=60` indicates a 60-second window. Use these headers to throttle requests proactively and reduce -the likelihood of hitting 429 errors. - -## How to handle 429 responses - -When your client receives a `429 Too Many Requests` response, you've exceeded the applicable rate limit. Your client must handle -these responses to maintain service quality. - -Your implementation must: - -- **Detect 429 responses**: Monitor for HTTP 429 status codes on all API calls. -- **Implement exponential backoff**: When receiving a 429, pause and retry with increasing delays (for example: 1s, 2s, 4s, 8s). -- **Respect rate limit headers**: Check `x-ratelimit-remaining` and `x-ratelimit-reset`, when available, to throttle requests - proactively. -- **Avoid retry storms**: Don't retry failed requests in a tight loop. - -### Exponential backoff strategy - -When a request returns `429`, back off before retrying. Prefer the server's `x-ratelimit-reset` header when it's present, fall -back to exponential backoff capped at 30 seconds otherwise, and always add jitter so concurrent clients don't retry in lockstep. - -```jsx -async function callApiWithBackoff(request, maxRetries = 5) { - for (let attempt = 0; attempt < maxRetries; attempt++) { - const response = await fetch(request) - if (response.status !== 429) return response - - const resetAfter = response.headers.get("x-ratelimit-reset") - const baseDelay = resetAfter ? parseInt(resetAfter, 10) * 1000 : Math.min(Math.pow(2, attempt) * 1000, 30000) // cap at 30s - - const jitter = Math.random() * 1000 - await new Promise((resolve) => setTimeout(resolve, baseDelay + jitter)) - } - throw new Error("Max retries exceeded") -} -``` - -You can also throttle proactively using `x-ratelimit-remaining` to slow down before hitting a 429: - -```jsx -async function callApiWithThrottle(request) { - const response = await fetch(request) - const remaining = parseInt(response.headers.get("x-ratelimit-remaining"), 10) - const resetIn = parseInt(response.headers.get("x-ratelimit-reset"), 10) - - if (remaining < 5 && resetIn > 0) { - const paceDelay = (resetIn * 1000) / Math.max(remaining, 1) - await new Promise((resolve) => setTimeout(resolve, paceDelay)) - } - return response -} -``` - -Clients that repeatedly exceed rate limits without proper backoff may have their API access temporarily blocked. For high-volume -use cases that exceed your plan's limits, open a support ticket via the [Ory Console](https://console.ory.com/support) or email -[support@ory.com](mailto:support@ory.com). - -### Determine your project's rate limits - -To identify the rate limits that apply to your project: - -1. Check your workspace subscription plan (Developer, Production, Growth, or Enterprise). -2. Identify the environment (Production, Staging, or Development) assigned to your project. -3. Refer to the tables below based on your subscription plan and project environment. - -### Rate limit tables by subscription plan - -#### Developer plan rate limits - -| Environment | Path / Bucket | Burst (rps) | Sustained (rpm) | -| :---------- | :-------------------------------- | ----------: | --------------: | -| Development | `/sessions/whoami` | 10 | 300 | -| | `/admin/oauth2/introspect` | 10 | 300 | -| | `/relation-tuples/check` | 10 | 300 | -| | `GET /admin/identities` | 1 | 10 | -| | `POST /admin/identities` | 1 | 10 | -| | `PATCH /admin/identities` | 1 | 10 | -| | `POST /admin/recovery/*` | 1 | 10 | -| | `POST /self-service/registration` | 1 | 10 | -| | `POST /self-service/recovery` | 1 | 10 | -| | `POST /self-service/settings` | 1 | 10 | -| | `POST /self-service/verification` | 1 | 10 | -| | `/scim/**` | 1 | 10 | -| | `*` | 5 | 150 | - -:::note - -For Developer plans, all environments (Production, Staging, Development) use the same rate limits. - -::: - -#### Production plan rate limits - -| Environment | Path / Bucket | Burst (rps) | Sustained (rpm) | -| :-------------------- | :-------------------------------- | ----------: | --------------: | -| Production | `/sessions/whoami` | 80 | 1800 | -| | `/admin/oauth2/introspect` | 80 | 1800 | -| | `/relation-tuples/check` | 80 | 1800 | -| | `GET /admin/identities` | 10 | 300 | -| | `POST /admin/recovery/*` | 10 | 30 | -| | `/scim/**` | 10 | 300 | -| | `*` | 40 | 900 | -| Development / Staging | `/sessions/whoami` | 10 | 300 | -| | `/admin/oauth2/introspect` | 10 | 300 | -| | `/relation-tuples/check` | 10 | 300 | -| | `GET /admin/identities` | 1 | 10 | -| | `POST /admin/identities` | 1 | 10 | -| | `PATCH /admin/identities` | 1 | 10 | -| | `POST /admin/recovery/*` | 1 | 10 | -| | `POST /self-service/registration` | 1 | 10 | -| | `POST /self-service/recovery` | 1 | 10 | -| | `POST /self-service/settings` | 1 | 10 | -| | `POST /self-service/verification` | 1 | 10 | -| | `/scim/**` | 1 | 10 | -| | `*` | 5 | 150 | - -:::note - -Production plan rate limits also apply to the Legacy `Essential` plan. - -::: - -#### Growth plan rate limits - -| Environment | Path / Bucket | Burst (rps) | Sustained (rpm) | -| :-------------------- | :-------------------------------- | ----------: | --------------: | -| Production | `/sessions/whoami` | 800 | 18000 | -| | `/admin/oauth2/introspect` | 800 | 18000 | -| | `/relation-tuples/check` | 800 | 18000 | -| | `GET /admin/identities` | 20 | 600 | -| | `POST /admin/recovery/*` | 10 | 300 | -| | `/scim/**` | 10 | 300 | -| | `*` | 400 | 9000 | -| Development / Staging | `/sessions/whoami` | 10 | 300 | -| | `/admin/oauth2/introspect` | 10 | 300 | -| | `/relation-tuples/check` | 10 | 300 | -| | `GET /admin/identities` | 1 | 10 | -| | `POST /admin/identities` | 1 | 10 | -| | `PATCH /admin/identities` | 1 | 10 | -| | `POST /admin/recovery/*` | 1 | 10 | -| | `POST /self-service/registration` | 1 | 10 | -| | `POST /self-service/recovery` | 1 | 10 | -| | `POST /self-service/settings` | 1 | 10 | -| | `POST /self-service/verification` | 1 | 10 | -| | `/scim/**` | 1 | 10 | -| | `*` | 5 | 150 | - -:::note - -Growth plan rate limits also apply to the legacy `Scale` plan. - -::: - -#### Enterprise plan rate limits - -The Enterprise plan has the same default rate limits as the Growth plan. If your use case requires higher limits, -[get in touch with us to discuss your requirements](https://ory.com/contact). - -| Environment | Path / Bucket | Burst (rps) | Sustained (rpm) | -| :-------------------- | :-------------------------------- | ----------: | --------------: | -| Production | `/sessions/whoami` | 1200 | 36000 | -| | `/admin/oauth2/introspect` | 1200 | 36000 | -| | `/relation-tuples/check` | 1200 | 36000 | -| | `GET /admin/identities` | 60 | 1200 | -| | `POST /admin/recovery/*` | 20 | 600 | -| | `/scim/**` | 20 | 600 | -| | `*` | 800 | 18000 | -| Development / Staging | `/sessions/whoami` | 10 | 300 | -| | `/admin/oauth2/introspect` | 10 | 300 | -| | `/relation-tuples/check` | 10 | 300 | -| | `GET /admin/identities` | 1 | 10 | -| | `POST /admin/identities` | 1 | 10 | -| | `PATCH /admin/identities` | 1 | 10 | -| | `POST /admin/recovery/*` | 1 | 10 | -| | `POST /self-service/registration` | 1 | 10 | -| | `POST /self-service/recovery` | 1 | 10 | -| | `POST /self-service/settings` | 1 | 10 | -| | `POST /self-service/verification` | 1 | 10 | -| | `/scim/**` | 1 | 10 | -| | `*` | 5 | 150 | - -## Endpoint-based rate limits - -Endpoint-based rate limits are controls applied to individual API endpoints within your Ory projects. Unlike project rate limits, -which govern overall project request volumes, endpoint-based rate limits focus on safeguarding specific functionalities against -abuse. - -:::note - -Endpoint-based rate limits operate independently from project rate limits in workspaces. While project rate limits control overall -request volumes based on your subscription and environment, endpoint-based rate limits provide additional security for specific -endpoints regardless of your project rate limit values. - -::: - -### Purpose of endpoint-based rate limits - -Endpoint-based rate limits protect individual endpoints against common attack vectors like brute-force and credential stuffing. -These attacks typically involve numerous attempts to guess credentials or exploit vulnerabilities, often from a limited set of IP -addresses or JA4 fingerprints. - -Benefits: - -- Enhanced security—Restricts requests from specific sources, making attacks significantly harder to succeed -- Bot protection—Differentiates genuine users from harmful automated activity -- Granular control—Fine-tunes security for individual endpoints without compromising user experience - -### Types of endpoint-based protection - -Ory implements two layers of endpoint-based protection: - -#### Volumetric rate limits - -Analyzes incoming request patterns based on: - -- Source identification—IP addresses and JA3/JA4 fingerprints -- Request frequency—Detects volumetric attacks and system overwhelm attempts -- Authentication status—Different limits for authenticated vs. unauthenticated requests -- HTTP method—Varying limits based on GET, POST, etc. - -#### Inflight rate limits - -Inflight rate limits protect critical endpoints from concurrent request attacks. By preventing multiple requests to the same -resource at once, it eliminates race conditions, ensures data consistency, and lets critical operations complete safely. - -:::note - -These limits mainly protect against write requests to the same resource happening in parallel — usually caused by implementation -issues. - -::: - -### Protected endpoints - -The following endpoints are protected by different types of rate limiting: - -| Type | Endpoint | HTTP Methods | Ratelimit Key | Action | -| :------- | :------------------------------------------ | :----------------------- | :----------------------------------------------- | :------------------------------------- | -| Inflight | `/admin/identities` | `POST`, `PATCH` | `{project_id} + {full_path}` | Blocks concurrent requests (enforced) | -| Inflight | `/admin/identities/{id}` | `PUT`, `PATCH`, `DELETE` | `{project_id} + {full_path}` | Blocks concurrent requests (enforced) | -| Inflight | `/admin/identities/{id}/credentials/{type}` | `DELETE` | `{project_id} + {full_path}` | Blocks concurrent requests (enforced) | -| Inflight | `/admin/identities/{id}/sessions` | `DELETE` | `{project_id} + {full_path}` | Blocks concurrent requests (enforced) | -| Inflight | `/admin/sessions/{id}` | `DELETE` | `{project_id} + {full_path}` | Logs concurrent requests (report-only) | -| Inflight | `/admin/sessions/{id}/extend` | `PATCH` | `{project_id} + {full_path}` | Logs concurrent requests (report-only) | -| Inflight | `/self-service/recovery` | `POST` | `{project_id} + {path} + "/" + {email\|flow_id}` | Logs concurrent requests (report-only) | - -:::note - -Report-only endpoints are observed over a period of time before enforcement is enabled. They currently log rate limit violations -for monitoring purposes but don't block requests, while enforced endpoints return HTTP 429 when rate limits are exceeded. GET, -OPTIONS, and HEAD requests are exempt from rate limiting. - -::: - -### Configuration and management - -#### Rule management - -The endpoint-based rate limit rules are set and managed by Ory. These rules aren't directly configurable by Enterprise and Growth -customers yet. diff --git a/docs/guides/rate-limits-new.mdx b/docs/guides/rate-limits-new.mdx deleted file mode 100644 index 01d0f4a48..000000000 --- a/docs/guides/rate-limits-new.mdx +++ /dev/null @@ -1,111 +0,0 @@ ---- -id: rate-limits-new -title: Ory Network rate limits - new -sidebar_label: Rate limits - New ---- - -:::info - -There is a new project rate limit policy, which applies to all new Ory Network customers and to existing customers after they've -been migrated. If you're an existing customer and haven't received a migration notice yet, see the -[rate limits - legacy](/docs/guides/rate-limits-legacy). See [Rate limits](/docs/guides/rate-limits) to learn about both policies -and the migration plan. Endpoint-based rate limits have not changed. - -::: - -Ory uses rate limits to protect your applications against abuse, attacks, and service disruptions, and to maintain fair resource -allocation and network stability. - -## Types of rate limits - -Ory uses two types of rate limits: - -- **Project rate limits**: Control the overall request volume your projects can make to Ory APIs, based on your subscription tier - and project environment. See [Project rate limits](./rate-limits-project) for more information. -- **Endpoint-based rate limits**: Control traffic to individual endpoints to protect against volumetric attacks, brute-force - attempts, and concurrent request abuse—regardless of your project rate limits. See - [Endpoint-based rate limits](./rate-limits-endpoint) for more information. - -## Monitor rate limit headers - -Ory Network includes rate limit information in API response headers. Use these headers to avoid exceeding the applicable rate -limit. Your client must handle these responses to maintain service quality. - -| Header | Description | -| ----------------------- | --------------------------------------------------------------------------------------- | -| `x-ratelimit-limit` | The rate limit ceiling(s) for the current request, including burst and sustained limits | -| `x-ratelimit-remaining` | Number of requests remaining in the current window | -| `x-ratelimit-reset` | Number of seconds until the rate limit window resets | - -Example header values: - -```shell -x-ratelimit-limit: 10, 10;w=1, 300;w=60 -x-ratelimit-remaining: 8 -x-ratelimit-reset: 1 -``` - -The `x-ratelimit-limit` header follows the -[IETF RateLimit header fields draft](https://datatracker.ietf.org/doc/draft-ietf-httpapi-ratelimit-headers/), where `w=1` -indicates a 1-second window and `w=60` indicates a 60-second window. Use these headers to throttle requests proactively and reduce -the likelihood of hitting 429 errors. - -## How to handle 429 responses - -When your client receives a `429 Too Many Requests` response, you've exceeded the applicable rate limit. Your client must handle -these responses to maintain service quality. - -Your implementation must: - -- **Detect 429 responses**: Monitor for HTTP 429 status codes on all API calls. -- **Back off before retrying**: Prefer the server's `x-ratelimit-reset` header when available; fall back to exponential backoff - capped at 30 seconds. Always add jitter so concurrent clients don't retry in lockstep. -- **Throttle proactively**: Check `x-ratelimit-remaining` and `x-ratelimit-reset` to slow down before you hit a 429. -- **Avoid retry storms**: Don't retry failed requests in a tight loop. - -### Exponential backoff strategy - -When a request returns `429`, back off before retrying. Prefer the server's `x-ratelimit-reset` header when it's present, fall -back to exponential backoff capped at 30 seconds otherwise, and always add jitter so concurrent clients don't retry in lockstep. - -```jsx -async function callApiWithBackoff(request, maxRetries = 5) { - for (let attempt = 0; attempt < maxRetries; attempt++) { - const response = await fetch(request) - if (response.status !== 429) return response - - const resetAfter = response.headers.get("x-ratelimit-reset") - const baseDelay = resetAfter ? parseInt(resetAfter, 10) * 1000 : Math.min(Math.pow(2, attempt) * 1000, 30000) // cap at 30s - - const jitter = Math.random() * 1000 - await new Promise((resolve) => setTimeout(resolve, baseDelay + jitter)) - } - throw new Error("Max retries exceeded") -} -``` - -You can also throttle proactively using `x-ratelimit-remaining` to slow down before hitting a 429: - -```jsx -async function callApiWithThrottle(request) { - const response = await fetch(request) - const remaining = parseInt(response.headers.get("x-ratelimit-remaining"), 10) - const resetIn = parseInt(response.headers.get("x-ratelimit-reset"), 10) - - if (remaining < 5 && resetIn > 0) { - const paceDelay = (resetIn * 1000) / Math.max(remaining, 1) - await new Promise((resolve) => setTimeout(resolve, paceDelay)) - } - return response -} -``` - -Clients that repeatedly exceed rate limits without proper backoff may have their API access temporarily blocked. For high-volume -use cases that exceed your plan's limits, open a support ticket via the [Ory Console](https://console.ory.com/support) or email -[support@ory.com](mailto:support@ory.com). - -## Load testing - -Load testing against the Ory Network requires prior written approval. Unauthorized tests will be detected and may result in -temporary blocking. To request an approved window, open a support ticket via the [Ory Console](https://console.ory.com/support) or -email [support@ory.com](mailto:support@ory.com). diff --git a/docs/guides/rate-limits.mdx b/docs/guides/rate-limits.mdx index 33a98eb60..bc863e658 100644 --- a/docs/guides/rate-limits.mdx +++ b/docs/guides/rate-limits.mdx @@ -4,54 +4,100 @@ title: Ory Network rate limiting sidebar_label: Rate limits --- -Ory Network uses rate limits to protect your applications against abuse and ensure fair resource allocation across all customers. -Ory is currently migrating to a new project rate limiting policy. New workspaces are automatically on the new policy; existing -customers are being migrated by subscription tier. +Ory Network uses rate limits to protect your applications against abuse, attacks, and service disruptions, and to maintain fair +resource allocation and network stability. Rate limits apply to all workspaces, based on your subscription tier and project +environment. -## Which rate limit system applies to you? +## Types of rate limits -| You are... | Your system | -| ------------------------------------------------------ | -------------------------------------------- | -| A new customer (workspace created on or after June 15) | [Rate limits - new](./rate-limits-new) | -| An existing customer, migration not yet completed | [Rate limits - legacy](./rate-limits-legacy) | -| An existing customer, migration completed | [Rate limits - new](./rate-limits-new) | +Ory uses two types of rate limits: -:::tip +- **Project rate limits**: Control the overall request volume your projects can make to Ory APIs, based on your subscription tier + and project environment. See [Project rate limits](./rate-limits-project.mdx) for more information. +- **Endpoint-based rate limits**: Control traffic to individual endpoints to protect against volumetric attacks, brute-force + attempts, and concurrent request abuse—regardless of your project rate limits. See + [Endpoint-based rate limits](./rate-limits-endpoint.mdx) for more information. -You can check which policy your workspace is on in the Ory Console under **Settings → Rate Limits**, or by checking your migration -notification email. +## Monitor rate limit headers -::: +Ory Network includes rate limit information in API response headers. Use these headers to avoid exceeding the applicable rate +limit. Your client must handle these responses to maintain service quality. -## What's changing? +| Header | Description | +| ----------------------- | --------------------------------------------------------------------------------------- | +| `x-ratelimit-limit` | The rate limit ceiling(s) for the current request, including burst and sustained limits | +| `x-ratelimit-remaining` | Number of requests remaining in the current window | +| `x-ratelimit-reset` | Number of seconds until the rate limit window resets | -The legacy rate limit policy applied project rate limits per endpoint-path and limits were fixed per subscription plan and -environment. The new project rate limit policy is a more structured model that distributes project rate limits across different -types of API operations. API operations are now organized into **buckets** based on service, access level, and rate limit -threshold. This allows the Ory platform to handle traffic more efficiently while giving you clearer and more consistent behavior -when interacting with the APIs. +Example header values: -## Migration plan +```shell +x-ratelimit-limit: 10, 10;w=1, 300;w=60 +x-ratelimit-remaining: 8 +x-ratelimit-reset: 1 +``` -The new rate limits will be introduced gradually to ensure a smooth transition. No action is required on your end. Ory will notify -you before your workspace is migrated. During the migration, your project rate limit behavior remains unchanged until the cutover -completes. +The `x-ratelimit-limit` header follows the +[IETF RateLimit header fields draft](https://datatracker.ietf.org/doc/draft-ietf-httpapi-ratelimit-headers/), where `w=1` +indicates a 1-second window and `w=60` indicates a 60-second window. Use these headers to throttle requests proactively and reduce +the likelihood of hitting 429 errors. -Migration schedule: +## How to handle 429 responses -| Phase | Plan | Date | -| ----- | ------------------------------------------------ | --------------- | -| 1 | New workspaces and existing Developer workspaces | Week of June 15 | -| 2 | Existing Production workspaces | Week of June 22 | -| 3 | Existing Growth workspaces | Week of June 29 | -| 4 | Existing Enterprise workspaces | Week of July 6 | +When your client receives a `429 Too Many Requests` response, you've exceeded the applicable rate limit. Your client must handle +these responses to maintain service quality. -For more details on the rollout and migration schedule, read the -[announcement blog post](https://www.ory.com/blog/new-rate-limit-model-ory-network). +Your implementation must: -The types of rate limits, for project-based and endpoint-based, remain the same in both rate limit policies. +- **Detect 429 responses**: Monitor for HTTP 429 status codes on all API calls. +- **Back off before retrying**: Prefer the server's `x-ratelimit-reset` header when available; fall back to exponential backoff + capped at 30 seconds. Always add jitter so concurrent clients don't retry in lockstep. +- **Throttle proactively**: Check `x-ratelimit-remaining` and `x-ratelimit-reset` to slow down before you hit a 429. +- **Avoid retry storms**: Don't retry failed requests in a tight loop. -## Learn more about rate limits +### Exponential backoff strategy -- [Rate limits - new](./rate-limits-new)—applies to new customers and migrated workspaces -- [Rate limits - legacy](./rate-limits-legacy)—applies to existing customers pending migration +When a request returns `429`, back off before retrying. Prefer the server's `x-ratelimit-reset` header when it's present, fall +back to exponential backoff capped at 30 seconds otherwise, and always add jitter so concurrent clients don't retry in lockstep. + +```jsx +async function callApiWithBackoff(request, maxRetries = 5) { + for (let attempt = 0; attempt < maxRetries; attempt++) { + const response = await fetch(request) + if (response.status !== 429) return response + + const resetAfter = response.headers.get("x-ratelimit-reset") + const baseDelay = resetAfter ? parseInt(resetAfter, 10) * 1000 : Math.min(Math.pow(2, attempt) * 1000, 30000) // cap at 30s + + const jitter = Math.random() * 1000 + await new Promise((resolve) => setTimeout(resolve, baseDelay + jitter)) + } + throw new Error("Max retries exceeded") +} +``` + +You can also throttle proactively using `x-ratelimit-remaining` to slow down before hitting a 429: + +```jsx +async function callApiWithThrottle(request) { + const response = await fetch(request) + const remaining = parseInt(response.headers.get("x-ratelimit-remaining"), 10) + const resetIn = parseInt(response.headers.get("x-ratelimit-reset"), 10) + + if (remaining < 5 && resetIn > 0) { + const paceDelay = (resetIn * 1000) / Math.max(remaining, 1) + await new Promise((resolve) => setTimeout(resolve, paceDelay)) + } + return response +} +``` + +Clients that repeatedly exceed rate limits without proper backoff may have their API access temporarily blocked. For high-volume +use cases that exceed your plan's limits, open a support ticket via the [Ory Console](https://console.ory.com/support) or email +[support@ory.com](mailto:support@ory.com). + +## Load testing + +Load testing against the Ory Network requires prior written approval. Unauthorized tests will be detected and may result in +temporary blocking. To request an approved window, open a support ticket via the [Ory Console](https://console.ory.com/support) or +email [support@ory.com](mailto:support@ory.com). diff --git a/sidebars.ts b/sidebars.ts index 560b259ac..06ce261ba 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -44,21 +44,7 @@ const api: SidebarItemsConfig = [ type: "doc", id: "guides/rate-limits", }, - items: [ - "guides/rate-limits-legacy", - { - type: "category", - label: "Rate limits - New", - link: { - type: "doc", - id: "guides/rate-limits-new", - }, - items: [ - "guides/rate-limits-project", - "guides/rate-limits-endpoint", - ], - }, - ], + items: ["guides/rate-limits-project", "guides/rate-limits-endpoint"], }, "guides/load-performance-testing", "guides/ip-allowlist", diff --git a/vercel.json b/vercel.json index 83335659f..10dcdbc75 100644 --- a/vercel.json +++ b/vercel.json @@ -5,6 +5,16 @@ "cleanUrls": true, "trailingSlash": false, "redirects": [ + { + "source": "/docs/guides/rate-limits-legacy", + "destination": "/docs/guides/rate-limits", + "permanent": false + }, + { + "source": "/docs/guides/rate-limits-new", + "destination": "/docs/guides/rate-limits", + "permanent": false + }, { "source": "/", "destination": "/docs",