Understand limits, headers, and production throttling strategies
How WAVE counts and enforces API request limits
WAVE uses a sliding window algorithm to track API usage. Each request is counted against your tier's limit for the current 60-second window.
Your limit resets continuously, not at fixed intervals. If you make 60 requests at 12:00:00, you can make another at 12:01:00 (60 seconds later).
Pro tier allows short bursts above the per-minute rate. You can send 50 requests instantly, then throttle to the sustained rate.
Track your API usage with response headers
Every API response includes headers showing your current rate limit status:
HTTP/1.1 200 OK X-RateLimit-Limit: 300 X-RateLimit-Remaining: 247 X-RateLimit-Reset: 1635724800 X-RateLimit-Window: 60 Retry-After: 45
X-RateLimit-LimitMaximum number of requests allowed in the current window
X-RateLimit-RemainingNumber of requests remaining in the current window
X-RateLimit-ResetUnix timestamp when the rate limit window resets
Retry-AfterSeconds to wait before retrying (only present on 429 errors)
Production-grade retry strategies
import { WaveClient } from '@wave/api-client';
const client = new WaveClient({
apiKey: 'wave_live_xxxxx',
retryOn429: true,
maxRetries: 3
});
// Manual rate limit handling
async function createStreamWithRetry() {
try {
return await client.streams.create({
title: 'My Stream'
});
} catch (error) {
if (error.status === 429) {
const retryAfter = parseInt(error.headers['retry-after'] || '60');
console.log(`Rate limited. Retry after ${retryAfter}s`);
await sleep(retryAfter * 1000);
return createStreamWithRetry(); // Retry
}
throw error;
}
}
// Pre-emptive throttling
import { RateLimiter } from 'limiter';
import { DesignTokens, getContainer, getSection } from '@/lib/design-tokens';
const limiter = new RateLimiter({
tokensPerInterval: 60,
interval: 'minute'
});
await limiter.removeTokens(1);
const stream = await client.streams.create({ title: 'My Stream' });Optimize API usage and avoid rate limits
Cache API responses locally (Redis, memory) to reduce redundant requests.
Cache-Control: max-age=300, must-revalidateUse pagination and filtering to fetch multiple resources in a single request instead of individual calls.
GET /v1/streams?limit=100&status=live,idleOn rate limit errors, wait longer between each retry attempt (1s, 2s, 4s, 8s...).
delay = min(2^attempt * 1000, 30000) // Max 30sTrack X-RateLimit-Remaining and alert when it drops below 20%.
if (remaining < limit * 0.2) { alert('Low rate limit') }Instead of polling for status updates, use webhooks to receive real-time notifications.
→ Learn about webhooks