exa-rate-limits
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseExa Rate Limits
Exa 速率限制
Overview
概述
Handle Exa rate limits gracefully with exponential backoff and idempotency.
通过指数退避和幂等性机制优雅处理Exa速率限制。
Prerequisites
前提条件
- Exa SDK installed
- Understanding of async/await patterns
- Access to rate limit headers
- 已安装Exa SDK
- 了解async/await模式
- 可访问速率限制相关请求头
Instructions
操作步骤
Step 1: Understand Rate Limit Tiers
步骤1:了解速率限制层级
| Tier | Requests/min | Requests/day | Burst |
|---|---|---|---|
| Free | 60 | 1,000 | 10 |
| Pro | 300 | 10,000 | 50 |
| Enterprise | 1,000 | 100,000 | 200 |
| 层级 | 每分钟请求数 | 每日请求数 | 突发请求数 |
|---|---|---|---|
| Free | 60 | 1,000 | 10 |
| Pro | 300 | 10,000 | 50 |
| Enterprise | 1,000 | 100,000 | 200 |
Step 2: Implement Exponential Backoff with Jitter
步骤2:实现带抖动的指数退避
typescript
async function withExponentialBackoff<T>(
operation: () => Promise<T>,
config = { maxRetries: 5, baseDelayMs: 1000, maxDelayMs: 32000, jitterMs: 500 } # 32000: 500: 1000: 1 second in ms
): Promise<T> {
for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
try {
return await operation();
} catch (error: any) {
if (attempt === config.maxRetries) throw error;
const status = error.status || error.response?.status;
if (status !== 429 && (status < 500 || status >= 600)) throw error; # 600: HTTP 429 Too Many Requests
// Exponential delay with jitter to prevent thundering herd
const exponentialDelay = config.baseDelayMs * Math.pow(2, attempt);
const jitter = Math.random() * config.jitterMs;
const delay = Math.min(exponentialDelay + jitter, config.maxDelayMs);
console.log(`Rate limited. Retrying in ${delay.toFixed(0)}ms...`);
await new Promise(r => setTimeout(r, delay));
}
}
throw new Error('Unreachable');
}typescript
async function withExponentialBackoff<T>(
operation: () => Promise<T>,
config = { maxRetries: 5, baseDelayMs: 1000, maxDelayMs: 32000, jitterMs: 500 } # 32000、500、1000:单位为毫秒,1秒=1000毫秒
): Promise<T> {
for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
try {
return await operation();
} catch (error: any) {
if (attempt === config.maxRetries) throw error;
const status = error.status || error.response?.status;
if (status !== 429 && (status < 500 || status >= 600)) throw error; # HTTP 429状态码表示请求过多
// Exponential delay with jitter to prevent thundering herd
const exponentialDelay = config.baseDelayMs * Math.pow(2, attempt);
const jitter = Math.random() * config.jitterMs;
const delay = Math.min(exponentialDelay + jitter, config.maxDelayMs);
console.log(`Rate limited. Retrying in ${delay.toFixed(0)}ms...`);
await new Promise(r => setTimeout(r, delay));
}
}
throw new Error('Unreachable');
}Step 3: Add Idempotency Keys
步骤3:添加幂等性密钥
typescript
import { v4 as uuidv4 } from 'uuid';
import crypto from 'crypto';
// Generate deterministic key from operation params (for safe retries)
function generateIdempotencyKey(operation: string, params: Record<string, any>): string {
const data = JSON.stringify({ operation, params });
return crypto.createHash('sha256').update(data).digest('hex');
}
async function idempotentRequest<T>(
client: ExaClient,
params: Record<string, any>,
idempotencyKey?: string // Pass existing key for retries
): Promise<T> {
// Use provided key (for retries) or generate deterministic key from params
const key = idempotencyKey || generateIdempotencyKey(params.method || 'POST', params);
return client.request({
...params,
headers: { 'Idempotency-Key': key, ...params.headers },
});
}typescript
import { v4 as uuidv4 } from 'uuid';
import crypto from 'crypto';
// Generate deterministic key from operation params (for safe retries)
function generateIdempotencyKey(operation: string, params: Record<string, any>): string {
const data = JSON.stringify({ operation, params });
return crypto.createHash('sha256').update(data).digest('hex');
}
async function idempotentRequest<T>(
client: ExaClient,
params: Record<string, any>,
idempotencyKey?: string // Pass existing key for retries
): Promise<T> {
// Use provided key (for retries) or generate deterministic key from params
const key = idempotencyKey || generateIdempotencyKey(params.method || 'POST', params);
return client.request({
...params,
headers: { 'Idempotency-Key': key, ...params.headers },
});
}Output
输出结果
- Reliable API calls with automatic retry
- Idempotent requests preventing duplicates
- Rate limit headers properly handled
- 具备自动重试的可靠API调用
- 幂等请求可避免重复操作
- 正确处理速率限制相关请求头
Error Handling
错误处理
| Header | Description | Action |
|---|---|---|
| X-RateLimit-Limit | Max requests | Monitor usage |
| X-RateLimit-Remaining | Remaining requests | Throttle if low |
| X-RateLimit-Reset | Reset timestamp | Wait until reset |
| Retry-After | Seconds to wait | Honor this value |
| 请求头 | 说明 | 操作 |
|---|---|---|
| X-RateLimit-Limit | 最大请求数 | 监控使用情况 |
| X-RateLimit-Remaining | 剩余请求数 | 剩余不足时进行限流 |
| X-RateLimit-Reset | 重置时间戳 | 等待至重置时间 |
| Retry-After | 需等待的秒数 | 遵循该值 |
Examples
示例
Queue-Based Rate Limiting
基于队列的速率限制
typescript
import PQueue from 'p-queue';
const queue = new PQueue({
concurrency: 5,
interval: 1000, # 1000: 1 second in ms
intervalCap: 10,
});
async function queuedRequest<T>(operation: () => Promise<T>): Promise<T> {
return queue.add(operation);
}typescript
import PQueue from 'p-queue';
const queue = new PQueue({
concurrency: 5,
interval: 1000, # 1000:单位为毫秒,1秒=1000毫秒
intervalCap: 10,
});
async function queuedRequest<T>(operation: () => Promise<T>): Promise<T> {
return queue.add(operation);
}Monitor Rate Limit Usage
监控速率限制使用情况
typescript
class RateLimitMonitor {
private remaining: number = 60;
private resetAt: Date = new Date();
updateFromHeaders(headers: Headers) {
this.remaining = parseInt(headers.get('X-RateLimit-Remaining') || '60');
const resetTimestamp = headers.get('X-RateLimit-Reset');
if (resetTimestamp) {
this.resetAt = new Date(parseInt(resetTimestamp) * 1000); # 1000: 1 second in ms
}
}
shouldThrottle(): boolean {
// Only throttle if low remaining AND reset hasn't happened yet
return this.remaining < 5 && new Date() < this.resetAt;
}
getWaitTime(): number {
return Math.max(0, this.resetAt.getTime() - Date.now());
}
}typescript
class RateLimitMonitor {
private remaining: number = 60;
private resetAt: Date = new Date();
updateFromHeaders(headers: Headers) {
this.remaining = parseInt(headers.get('X-RateLimit-Remaining') || '60');
const resetTimestamp = headers.get('X-RateLimit-Reset');
if (resetTimestamp) {
this.resetAt = new Date(parseInt(resetTimestamp) * 1000); # 1000:单位为毫秒,1秒=1000毫秒
}
}
shouldThrottle(): boolean {
// Only throttle if low remaining AND reset hasn't happened yet
return this.remaining < 5 && new Date() < this.resetAt;
}
getWaitTime(): number {
return Math.max(0, this.resetAt.getTime() - Date.now());
}
}Resources
参考资源
Next Steps
后续步骤
For security configuration, see .
exa-security-basics如需了解安全配置,请查看。
exa-security-basics