### Install upstash-ratelimit Source: https://upstash.com/docs/redis/sdks/ratelimit-py/gettingstarted Install the upstash-ratelimit package via pip. ```bash pip install upstash-ratelimit ``` -------------------------------- ### Install @upstash/ratelimit Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/gettingstarted Install the @upstash/ratelimit package using npm, or import it directly from a CDN for Deno. ```bash npm install @upstash/ratelimit ``` ```javascript import { Ratelimit } from "https://cdn.skypack.dev/@upstash/ratelimit@latest"; ``` -------------------------------- ### Using multiple limits with different prefixes Source: https://upstash.com/docs/redis/sdks/ratelimit-py/features Applies different rate limits to different user groups by creating separate Ratelimit instances with distinct prefixes. Here free users get 10 requests per 10 seconds and paid users get 60 requests per 10 seconds. ```python from upstash_ratelimit import Ratelimit, SlidingWindow from upstash_redis import Redis class MultiRL: def __init__(self) -> None: redis = Redis.from_env() self.free = Ratelimit( redis=redis, limiter=SlidingWindow(max_requests=10, window=10), prefix="ratelimit:free", ) self.paid = Ratelimit( redis=redis, limiter=SlidingWindow(max_requests=60, window=10), prefix="ratelimit:paid", ) # Create a new ratelimiter, that allows 10 requests per 10 seconds ratelimit = MultiRL() ratelimit.free.limit("userIP") ratelimit.paid.limit("userIP") ``` -------------------------------- ### getDynamicLimit usage example Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/methods Example of setting a dynamic limit and then retrieving it. Requires `dynamicLimits: true` in the Ratelimit configuration. After setting `limit: 5`, `getDynamicLimit()` returns `5`. ```typescript const ratelimit = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(10, "10s"), dynamicLimits: true,});await ratelimit.setDynamicLimit({ limit: 5 });const { dynamicLimit } = await ratelimit.getDynamicLimit(); // returns 5 ``` -------------------------------- ### Enable deny list protection with enableProtection Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/traffic-protection Pass enableProtection: true to the Ratelimit constructor to enable checking the deny list. Note the missing comma after enableProtection in the original example. ```javascript const ratelimit = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(10, "10 s"), enableProtection: true analytics: true,}); ``` -------------------------------- ### setDynamicLimit usage example Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/methods Example of setting and removing a dynamic limit. Requires `dynamicLimits: true` in the Ratelimit configuration. Setting `limit: 5` overrides the default limit of 10; setting `limit: false` removes the dynamic limit and falls back to the default. ```typescript const ratelimit = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(10, "10s"), dynamicLimits: true,});// Set a new dynamic limitawait ratelimit.setDynamicLimit({ limit: 5 });// Remove dynamic limit (falls back to default of 10)await ratelimit.setDynamicLimit({ limit: false }); ``` -------------------------------- ### Using blockUntilReady with sliding window limiter Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/methods Example of creating a Ratelimit instance and using blockUntilReady to wait up to 30 seconds for a request to be allowed. If the request is not allowed after the timeout, it returns an error message. Note: In Cloudflare, blockUntilReady will not work as intended due to Date.now() behavior. ```typescript // Create a new ratelimiter, that allows 10 requests per 10 seconds const ratelimit = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(10, "10 s"), analytics: true, }); // `blockUntilReady` returns a promise that resolves as soon as the request is allowed to be processed, or after 30 seconds const { success } = await ratelimit.blockUntilReady("id", 30_000); if (!success) { return "Unable to process, even after 30 seconds"; } doExpensiveCalculation(); return "Here you go!"; ``` -------------------------------- ### Fixed Window Ratelimit (Multi-Region) Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/algorithms Creates a fixed window rate limiter for multi-region setups, allowing 10 requests per 10 seconds across multiple Redis instances. ```typescript const ratelimit = new MultiRegionRatelimit({ redis: [ new Redis({ /* auth */ }), new Redis({ /* auth */ }) ], limiter: MultiRegionRatelimit.fixedWindow(10, "10 s"), }); ``` -------------------------------- ### Sliding Window Ratelimit (Multi-Region) Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/algorithms Creates a sliding window rate limiter for multi-region setups. Warning: using sliding window with multiregion results in large number of Redis commands and long request processing times; fixed window is recommended for multi-region. ```typescript const ratelimit = new MultiRegionRatelimit({ redis: [ new Redis({ /* auth */ }), new Redis({ /* auth */ }) ], limiter: MultiRegionRatelimit.slidingWindow(10, "10 s"), }); ``` -------------------------------- ### Enable and use dynamic limits with Ratelimit Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/features Set dynamicLimits to true when creating the Ratelimit instance, then use setDynamicLimit to change the limit at runtime, getDynamicLimit to retrieve it, and setDynamicLimit with limit: false to remove it. Dynamic limits work with fixedWindow, slidingWindow, and tokenBucket algorithms; multi-region algorithms are not supported. ```javascript const ratelimit = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(10, "10s"), dynamicLimits: true, // Enable dynamic limits});// Set a global dynamic limitawait ratelimit.setDynamicLimit({ limit: 5 });// All subsequent limit checks use the new limitconst { success } = await ratelimit.limit("user_123");// Get current dynamic limitconst currentLimit = await ratelimit.getDynamicLimit(); // returns 5// Remove dynamic limit (falls back to default)await ratelimit.setDynamicLimit({ limit: false }); ``` -------------------------------- ### Use FixedWindow ratelimiter with Redis Source: https://upstash.com/docs/redis/sdks/ratelimit-py/gettingstarted Create a fixed window ratelimiter with upstash-ratelimit and Redis, allowing 10 requests per 10 seconds. The prefix is optional and defaults to "@upstash/ratelimit". Use a constant string or a user ID, API key, or IP address as the identifier. ```python from upstash_ratelimit import Ratelimit, FixedWindowfrom upstash_redis import Redis# Create a new ratelimiter, that allows 10 requests per 10 secondsratelimit = Ratelimit( redis=Redis.from_env(), limiter=FixedWindow(max_requests=10, window=10), # Optional prefix for the keys used in Redis. This is useful # if you want to share a Redis instance with other applications # and want to avoid key collisions. The default prefix is # "@upstash/ratelimit" prefix="@upstash/ratelimit",)# Use a constant string to limit all requests with a single ratelimit# Or use a user ID, API key or IP address for individual limits.identifier = "api"response = ratelimit.limit(identifier)if not response.allowed: print("Unable to process at this time")else: do_expensive_calculation() print("Here you go!") ``` -------------------------------- ### Multiple Limits with Ratelimit Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/features Create two separate Ratelimit instances with different sliding window limits (10 and 60 requests per 10 seconds) for free and paid users. Use the appropriate instance based on the user's plan. ```typescript import { Redis } from "@upstash/redis"; import { Ratelimit } from "@upstash/ratelimit"; const redis = Redis.fromEnv(); const ratelimit = { free: new Ratelimit({ redis, analytics: true, prefix: "ratelimit:free", limiter: Ratelimit.slidingWindow(10, "10s"), }), paid: new Ratelimit({ redis, analytics: true, prefix: "ratelimit:paid", limiter: Ratelimit.slidingWindow(60, "10s"), }), }; await ratelimit.free.limit(ip); // or for a paid user you might have an email or userId available: await ratelimit.paid.limit(userId); ``` -------------------------------- ### Fixed Window rate limiter usage Source: https://upstash.com/docs/redis/sdks/ratelimit-py/algorithms Sets up a fixed window rate limiter with a maximum of 10 requests per 10-second window. Uses Redis.from_env() for the Redis connection. ```python from upstash_ratelimit import Ratelimit, FixedWindow from upstash_redis import Redis ratelimit = Ratelimit( redis=Redis.from_env(), limiter=FixedWindow(max_requests=10, window=10), ) ``` -------------------------------- ### Pass Redis Credentials Directly Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/gettingstarted Alternative to Redis.fromEnv() when you want to pass the URL and token directly, useful if you use different environment variable names. ```javascript new Redis({ url: "https://****.upstash.io", token: "********", }); ``` -------------------------------- ### Token Bucket rate limiter usage Source: https://upstash.com/docs/redis/sdks/ratelimit-py/algorithms Sets up a token bucket rate limiter with a maximum of 10 tokens, refilling 5 tokens every 10 seconds. Uses Redis.from_env() for the Redis connection. ```python from upstash_ratelimit import Ratelimit, TokenBucket from upstash_redis import Redis ratelimit = Ratelimit( redis=Redis.from_env(), limiter=TokenBucket(max_tokens=10, refill_rate=5, interval=10), ) ``` -------------------------------- ### Sliding Window rate limiter usage Source: https://upstash.com/docs/redis/sdks/ratelimit-py/algorithms Sets up a sliding window rate limiter with a maximum of 10 requests per 10-second window. Uses Redis.from_env() for the Redis connection. ```python from upstash_ratelimit import Ratelimit, SlidingWindow from upstash_redis import Redis ratelimit = Ratelimit( redis=Redis.from_env(), limiter=SlidingWindow(max_requests=10, window=10), ) ``` -------------------------------- ### Add Ratelimit to Your Endpoint Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/gettingstarted Initialize a Ratelimit instance with an Upstash Redis and use it to limit requests. Allows 10 requests per 10 seconds and returns a failure message when the limit is exceeded. ```javascript import { Ratelimit } from "@upstash/ratelimit"; // for deno: see above import { Redis } from "@upstash/redis"; // Create a new ratelimiter, that allows 10 requests per 10 seconds const ratelimit = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(10, "10 s"), analytics: true, /** * Optional prefix for the keys used in redis. This is useful if you want to share a redis * instance with other applications and want to avoid key collisions. The default prefix is * "@upstash/ratelimit" */ prefix: "@upstash/ratelimit", }); // Use a constant string to limit all requests with a single ratelimit // Or use a userID, apiKey or ip address for individual limits. const identifier = "api"; const { success } = await ratelimit.limit(identifier); if (!success) { return "Unable to process at this time"; } doExpensiveCalculation(); return "Here you go!"; ``` -------------------------------- ### Set Environment Variables in .env.local Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/gettingstarted Add the environment variables to your .env.local file for a local Next.js project. ```bash UPSTASH_REDIS_REST_URL=**** UPSTASH_REDIS_REST_TOKEN=**** ``` -------------------------------- ### Sliding window approximation calculation Source: https://upstash.com/docs/redis/sdks/ratelimit-py/algorithms Illustrates the sliding window approximation calculation. Weights requests from the previous window by the remaining time fraction and adds current window requests, then compares to the limit. ```python limit = 10 # 4 request from the old window, weighted + requests in current window rate = 4 * ((60 - 15) / 60) + 5 = 8 return rate < limit # True means we should allow the request ``` -------------------------------- ### Cloudflare and Fastly Redis Imports Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/gettingstarted Use these imports for Cloudflare Workers and Fastly Compute@Edge instead of the default Redis import. ```javascript import { Redis } from "@upstash/redis/cloudflare"; // for cloudflare workers and pages import { Redis } from "@upstash/redis/fastly"; // for fastly compute@edge ``` -------------------------------- ### blockUntilReady Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/methods Documentation for the blockUntilReady method, which waits until a request can be processed instead of rejecting immediately. ```APIDOC ## `blockUntilReady` ### Description Waits until a request can be processed instead of rejecting it immediately. If the current limit has been exceeded, it waits until the next window starts and retries, resolving within a specified timeout. ### Method `blockUntilReady` ### Signature `ratelimit.blockUntilReady(identifier: string, timeout: number): Promise` ### Parameters - **identifier** (string) - Required - The identifier for the rate limit window. - **timeout** (number) - Required - Timeout in milliseconds; the promise resolves after this duration even if the limit is still exceeded. ### Returns - **Promise** - Resolves with the same response as the `limit` method. ### Example ```typescript // Create a new ratelimiter, that allows 10 requests per 10 seconds const ratelimit = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(10, "10 s"), analytics: true, }); // `blockUntilReady` returns a promise that resolves as soon as the request is allowed to be processed, or after 30 seconds const { success } = await ratelimit.blockUntilReady("id", 30_000); if (!success) { return "Unable to process, even after 30 seconds"; } doExpensiveCalculation(); return "Here you go!"; ``` ### Notes - In **Cloudflare**, `blockUntilReady` will not work as intended due to `Date.now()` not behaving the same as in Node environments. - For more information, see: https://developers.cloudflare.com/workers/runtime-apis/web-standards ``` -------------------------------- ### Token Bucket Ratelimit (Regional) Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/algorithms Creates a token bucket rate limiter that refills 5 tokens every 10 seconds with a maximum bucket size of 10, and enables analytics. Not yet supported for MultiRegionRatelimit. ```typescript const ratelimit = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.tokenBucket(5, "10 s", 10), analytics: true, }); ``` -------------------------------- ### Asynchronous Synchronization with context.waitUntil Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/features Handle the pending promise returned by MultiRegionRatelimit.limit on Cloudflare Workers or Vercel Edge functions. Use context.waitUntil to ensure the asynchronous synchronization completes. ```typescript const { pending } = await ratelimit.limit("id"); context.waitUntil(pending); ``` -------------------------------- ### Call limit with deny list context and inspect reason Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/traffic-protection When limit is called, the client checks the deny list and blocks the request if any provided value matches. The reason field will be "denyList" and deniedValue contains the matched value. Await pending if analytics are enabled. ```javascript const { success, pending, reason, deniedValue } = ratelimit.limit("userId", { ip: "ip-address", userAgent: "user-agent", country: "country",});await pending; // await pending if you have analytics enabledconsole.log(success, reason, deniedValue);// prints: false, "denyList", "ip-address" ``` -------------------------------- ### Response metadata from limit method Source: https://upstash.com/docs/redis/sdks/ratelimit-py/gettingstarted Metadata returned by the `limit` method: `allowed` indicates if the request may pass, `limit` is the maximum requests per window, `remaining` is the requests left in the current window, and `reset` is the Unix timestamp when limits reset. ```python @dataclasses.dataclassclass Response: allowed: bool """ Whether the request may pass(`True`) or exceeded the limit(`False`) """ limit: int """ Maximum number of requests allowed within a window. """ remaining: int """ How many requests the user has left within the current window. """ reset: float """ Unix timestamp in seconds when the limits are reset """ ``` -------------------------------- ### Configure ephemeralCache with a Map Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/features Creates an in-memory cache for the Ratelimit instance. The cache must be defined outside of the serverless function handler to persist between invocations. Pass it as the ephemeralCache option to enable caching, which blocks requests before Redis is called. ```javascript const cache = new Map(); // must be outside of your serverless function handler// ...const ratelimit = new Ratelimit({ // ... ephemeralCache: cache,}); ``` -------------------------------- ### Fixed Window Ratelimit (Regional) Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/algorithms Creates a fixed window rate limiter allowing 10 requests per 10 seconds using a single Redis instance. ```typescript const ratelimit = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.fixedWindow(10, "10 s"), }); ``` -------------------------------- ### Custom rates with rate parameter Source: https://upstash.com/docs/redis/sdks/ratelimit-py/features Allows different requests to consume different amounts of tokens by passing the rate parameter to the limit method. Here rate=5 subtracts 5 from the allowed requests in the window. ```python from upstash_ratelimit import Ratelimit, FixedWindow from upstash_redis import Redis ratelimit = Ratelimit( redis=Redis.from_env(), limiter=FixedWindow(max_requests=10, window=10), ) # pass rate as 5 to subtract 5 from the number of # allowed requests in the window: identifier = "api" response = ratelimit.limit(identifier, rate=5) ``` -------------------------------- ### Wait for pending operations with context.waitUntil Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/gettingstarted Use the `pending` promise returned from `ratelimit.limit` to ensure background operations (MultiRegion sync, analytics) complete before the serverless runtime ends. Call `context.waitUntil(pending)` to keep the runtime alive. ```javascript const { pending } = await ratelimit.limit("id");context.waitUntil(pending); ``` -------------------------------- ### MultiRegionRatelimit Usage Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/features Create a MultiRegionRatelimit instance with multiple Redis instances to reduce latency for users in different regions. The API is the same as Ratelimit, but requires an array of Redis instances. ```typescript import { MultiRegionRatelimit } from "@upstash/ratelimit"; // for deno: see above import { Redis } from "@upstash/redis"; // Create a new ratelimiter, that allows 10 requests per 10 seconds const ratelimit = new MultiRegionRatelimit({ redis: [ new Redis({ /* auth */ }), new Redis({ /* auth */ }), new Redis({ /* auth */ }), ], limiter: MultiRegionRatelimit.slidingWindow(10, "10 s"), analytics: true, }); // Use a constant string to limit all requests with a single ratelimit // Or use a userID, apiKey or ip address for individual limits. const identifier = "api"; const { success } = await ratelimit.limit(identifier); ``` -------------------------------- ### Sliding Window Ratelimit (Regional) Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/algorithms Creates a sliding window rate limiter allowing 10 requests per 10 seconds using a single Redis instance. ```typescript const ratelimit = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(10, "10 s"), }); ``` -------------------------------- ### Block until ready with timeout Source: https://upstash.com/docs/redis/sdks/ratelimit-py/features Blocks until a request can pass within the given timeout (in seconds). If the limit is exceeded, it waits for the next window and retries. Returns the same response as the limit method. ```python from upstash_ratelimit import Ratelimit, SlidingWindow from upstash_redis import Redis # Create a new ratelimiter, that allows 10 requests per 10 seconds ratelimit = Ratelimit( redis=Redis.from_env(), limiter=SlidingWindow(max_requests=10, window=10), ) response = ratelimit.block_until_ready("id", timeout=30) if not response.allowed: print("Unable to process, even after 30 seconds") else: do_expensive_calculation() print("Here you go!") ``` -------------------------------- ### Enable Auto IP Deny List protection Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/traffic-protection Set enableProtection to true to enable automatic blocking of malicious IPs using the ipsum repository. The SDK will block IPs when you provide the request IP in the limit method. ```javascript const ratelimit = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(10, "10 s"), enableProtection: true,}); ``` -------------------------------- ### Call limit with IP and await pending for IP list update Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/traffic-protection The IP deny list updates daily at 2 AM UTC. The first call after expiration triggers an asynchronous update; await pending to ensure the update completes before returning the result. ```javascript const { success, pending } = await ratelimit.limit( content, {ip: "ip-address"});await pending; ``` -------------------------------- ### setDynamicLimit Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/methods Sets or removes a global dynamic rate limit. Dynamic limits override the default limiter settings for all subsequent rate limit checks. ```APIDOC ## setDynamicLimit ### Description Sets or removes a global dynamic rate limit. Dynamic limits override the default limiter settings for all subsequent rate limit checks. ### Method SDK Method ### Signature `ratelimit.setDynamicLimit(options: { limit: number | false; }): Promise` ### Parameters - **limit** (number | false) - Required - The new limit value (number), or `false` to remove the dynamic limit and fall back to the default. ### Example ```js const ratelimit = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(10, "10s"), dynamicLimits: true, }); // Set a new dynamic limit await ratelimit.setDynamicLimit({ limit: 5 }); // Remove dynamic limit (falls back to default of 10) await ratelimit.setDynamicLimit({ limit: false }); ``` ``` -------------------------------- ### blockUntilReady method signature Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/methods Shows the TypeScript signature of the blockUntilReady method. It takes an identifier and a timeout in milliseconds, and returns a Promise that resolves with a RatelimitResponse. ```typescript ratelimit.blockUntilReady( identifier: string, timeout: number): Promise ``` -------------------------------- ### limit Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/methods The limit method is the heart of the Ratelimit algorithm. It receives an identifier to rate limit and optionally a request object with geo or rate fields. It returns a RatelimitResponse with metadata about the rate limit status. ```APIDOC ## limit ### Description The `limit` method is the heart of the Ratelimit algorithm. It receives an identifier to rate limit and optionally a request object with geo or rate fields. It returns a RatelimitResponse with metadata about the rate limit status. ### Method limit ### Endpoint ratelimit.limit(identifier: string, req?: { geo?: Geo; rate?: number, ip?: string, userAgent?: string, country?: string }): Promise ### Parameters #### Path Parameters - **identifier** (string) - Required - The identifier to rate limit. #### Request Body - **geo** (Geo) - Optional - Passed to analytics but not in use currently. - **rate** (number) - Optional - The amount of tokens/requests to subtract from the state of the algorithm with regards to the provided identifier. - **ip** (string) - Optional - The IP address of the request. - **userAgent** (string) - Optional - The user agent of the request. - **country** (string) - Optional - The country of the request. ### Response #### Success Response (200) - **success** (boolean) - Whether the request may pass (true) or exceeded the limit (false). - **limit** (number) - Maximum number of requests allowed within a window. - **remaining** (number) - How many requests the user has left within the current window. - **reset** (number) - Unix timestamp in milliseconds when the limits are reset. - **pending** (Promise) - For MultiRegion setup or analytics, used for background synchronization. On Vercel Edge or Cloudflare workers, handle explicitly with context.waitUntil(pending). - **reason** (RatelimitResponseType) - Reason behind the result in success field. Possible values: "timeout", "cacheBlock", "denyList", or undefined. - **deniedValue** (string) - The value which was in the deny list if reason: "denyList". #### Response Example ```json { "success": true, "limit": 10, "remaining": 9, "reset": 1700000000000, "pending": {}, "reason": undefined, "deniedValue": undefined } ``` ``` -------------------------------- ### getDynamicLimit Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/methods Retrieves the current dynamic limit if one is set. ```APIDOC ## getDynamicLimit ### Description Retrieves the current dynamic limit if one is set. ### Method SDK Method ### Signature `ratelimit.getDynamicLimit(): Promise<{ dynamicLimit: number | null }>` ### Returns - **dynamicLimit** (number | null) - The current dynamic limit value, or `null` if no dynamic limit is set. ### Example ```js const ratelimit = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(10, "10s"), dynamicLimits: true, }); await ratelimit.setDynamicLimit({ limit: 5 }); const { dynamicLimit } = await ratelimit.getDynamicLimit(); // returns 5 ``` ``` -------------------------------- ### Configure timeout in Ratelimit Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/features Sets a timeout of 1000 ms (1 second) for the rate limit request. If the request takes longer than the timeout, it is allowed to pass regardless of the current limit. The default timeout is 5 seconds if not provided. When a timeout causes a success, the `reason` field of the limit method indicates this. ```javascript const ratelimit = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(10, "10 s"), timeout: 1000, // 1 second analytics: true,}); ``` -------------------------------- ### Sliding Window Approximation Calculation Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/algorithms Shows the sliding window approximation calculation: weighted requests from the previous window plus current window requests compared against the limit. ```plaintext limit = 10 // 4 request from the old window, weighted + requests in current window rate = 4 * ((60 - 15) / 60) + 5 = 8 return rate < limit // True means we should allow the request ``` -------------------------------- ### ratelimit.limit method signature Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/methods The core method of the Ratelimit algorithm. It takes an identifier to rate limit and an optional request object that can include a geo field (passed to analytics but not currently used) or a rate field to specify the number of tokens/requests to subtract from the state for the identifier. ```typescript ratelimit.limit( identifier: string, req?: { geo?: Geo; rate?: number, ip?: string, userAgent?: string, country?: string },): Promise ``` -------------------------------- ### Enable analytics in Ratelimit Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/features Enables analytics for the rate limiter by setting `analytics: true`. With analytics enabled, each call to `ratelimit.limit()` sends analytics data to Redis, collecting information about the hour, identifier, and success/failure counts. This data is viewable in the Upstash console's Rate Limit dashboard. In serverless environments like Cloudflare Workers or Vercel Edge, ensure the analytics request completes by using the `pending` field from the `limit` method. ```javascript const ratelimit = new Ratelimit({ redis, analytics: true, limiter: Ratelimit.slidingWindow(60, "10s"),}); ``` -------------------------------- ### getDynamicLimit method signature Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/methods Retrieves the current dynamic limit if one is set. Returns the current dynamic limit value, or `null` if no dynamic limit is set. ```typescript ratelimit.getDynamicLimit(): Promise<{ dynamicLimit: number | null }> ``` -------------------------------- ### Custom Rate with rate Parameter Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/features Call the limit method with the rate parameter to subtract a custom value (batchSize) instead of the default 1. Useful for rate limiting based on the number of inputs in a batch. ```typescript const { success } = await ratelimit.limit("identifier", { rate: batchSize }); ``` -------------------------------- ### Set Environment Variables for Cloudflare Workers Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/gettingstarted Set the required environment variables for Cloudflare Workers using Wrangler. You will be prompted to enter the values. ```bash npx wrangler secret put UPSTASH_REDIS_REST_URL ``` ```bash npx wrangler secret put UPSTASH_REDIS_REST_TOKEN ``` -------------------------------- ### setDynamicLimit method signature Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/methods Sets or removes a global dynamic rate limit. Dynamic limits override the default limiter settings for all subsequent rate limit checks. The `limit` parameter is the new limit value (number), or `false` to remove the dynamic limit and fall back to the default. ```typescript ratelimit.setDynamicLimit(options: { limit: number | false;}): Promise ``` -------------------------------- ### RatelimitResponse type definition Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/methods The type returned by the `limit` method. It includes `success`, `limit`, `remaining`, `reset`, `pending`, `reason`, and `deniedValue`. The `pending` promise must be handled explicitly on Vercel Edge or Cloudflare workers using `context.waitUntil(pending)`. The `reason` field can be "timeout", "cacheBlock", "denyList", or undefined. ```typescript export type RatelimitResponse = { /** * Whether the request may pass(true) or exceeded the limit(false) */ success: boolean; /** * Maximum number of requests allowed within a window. */ limit: number; /** * How many requests the user has left within the current window. */ remaining: number; /** * Unix timestamp in milliseconds when the limits are reset. */ reset: number; /** * For the MultiRegion setup we do some synchronizing in the background, after returning the current limit. * Or when analytics is enabled, we send the analytics asynchronously after returning the limit. * In most case you can simply ignore this. * * On Vercel Edge or Cloudflare workers, you need to explicitly handle the pending Promise like this: * * ```ts * const { pending } = await ratelimit.limit("id") * context.waitUntil(pending) * ``` * * See `waitUntil` documentation in * [Cloudflare](https://developers.cloudflare.com/workers/runtime-apis/handlers/fetch/#contextwaituntil) * and [Vercel](https://vercel.com/docs/functions/edge-middleware/middleware-api#waituntil) * for more details. * ``` */ pending: Promise; /** * Reason behind the result in `success` field. * - Is set to "timeout" when request times out * - Is set to "cacheBlock" when an identifier is blocked through cache without calling redis because it was * rate limited previously. * - Is set to "denyList" when identifier or one of ip/user-agent/country parameters is in deny list. To enable * deny list, see `enableProtection` parameter. To edit the deny list, see the Upstash Ratelimit Dashboard * at https://console.upstash.com/ratelimit. * - Is set to undefined if rate limit check had to use Redis. This happens in cases when `success` field in * the response is true. It can also happen the first time sucecss is false. */ reason?: RatelimitResponseType; /** * The value which was in the deny list if reason: "denyList" */ deniedValue?: string;}; ``` -------------------------------- ### getRemaining Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/methods Returns the remaining tokens/requests available for a given identifier. ```APIDOC ## getRemaining ### Description Returns the remaining tokens/requests available for a given identifier. ### Method SDK Method ### Signature `ratelimit.getRemaining(identifier: string): Promise<{ remaining: number; reset: number; }>` ### Parameters - **identifier** (string) - Required - The identifier for which to retrieve the remaining tokens. ### Returns - **remaining** (number) - The remaining tokens. - **reset** (number) - The reset timestamp. ``` -------------------------------- ### resetUsedTokens Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/methods Documentation for the resetUsedTokens method, which resets the rate limit state for a given identifier. ```APIDOC ## `resetUsedTokens` ### Description Resets the state of the rate limiting algorithm with respect to a given identifier. ### Method `resetUsedTokens` ### Signature `ratelimit.resetUsedTokens(identifier: string): Promise` ### Parameters - **identifier** (string) - Required - The identifier whose rate limit state should be reset. ### Returns - **Promise** - Resolves when the state has been reset. ``` -------------------------------- ### resetUsedTokens method signature Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/methods Shows the TypeScript signature of the resetUsedTokens method. It takes an identifier and returns a Promise that resolves when the state is reset. ```typescript ratelimit.resetUsedTokens(identifier: string): Promise ``` -------------------------------- ### getRemaining method signature Source: https://upstash.com/docs/redis/sdks/ratelimit-ts/methods Returns the remaining tokens and reset timestamp for a given identifier. The `remaining` field is the remaining tokens, and `reset` is the reset timestamp. ```typescript ratelimit.getRemaining(identifier: string): Promise<{ remaining: number; reset: number;}> ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.