Rate Limits

Understanding rate limiting, quotas, and how to handle limits effectively

Overview

Placewise implements rate limiting to ensure fair usage and maintain service quality for all users. Rate limits are applied per API key (or IP address for anonymous requests) based on your subscription plan.

Rate Limit Tiers

Anonymous

10 requests/hour

For requests without an API key, identified by IP address

Window:

1 hour sliding

Reset:

Rolling (per request)

Free Plan

1,000 requests/month

Perfect for personal projects and development

Window:

30 days sliding

Overage:

Requests blocked

Pro Plan

50,000 requests/month

Ideal for production applications and growing businesses

Window:

30 days sliding

Overage:

Available for purchase

Business Plan

500,000 requests/month

For high-traffic applications and enterprises

Window:

30 days sliding

Overage:

Discounted rates

Enterprise Plan

Unlimited requests

Custom solutions with dedicated support and SLA

Window:

Not applicable

Support:

Dedicated account manager

Rate Limit Headers

Every API response includes headers that help you track your current rate limit status:

HeaderDescriptionExample
X-RateLimit-LimitTotal requests allowed in the current window1000
X-RateLimit-RemainingRequests remaining in current window987
X-RateLimit-ResetISO timestamp when the limit resets2025-02-09T12:00:00Z

Example Response Headers:

HTTP/1.1 302 Found
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 987
X-RateLimit-Reset: 2025-02-09T12:00:00Z
X-Cache: HIT
Location: https://images.unsplash.com/...

Rate Limit Exceeded (429)

When you exceed your rate limit, the API returns a 429 status code with details:

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 2025-02-09T12:00:00Z
Retry-After: 3600

{
  "error": "Rate limit exceeded",
  "code": "RATE_LIMIT_EXCEEDED",
  "limit": 1000,
  "remaining": 0,
  "reset": "2025-02-09T12:00:00Z",
  "retryAfter": 3600
}

Important

The Retry-After header tells you how many seconds to wait before retrying. Always respect this value.

Best Practices

Monitor rate limit headers

Check X-RateLimit-Remaining in your responses to track usage

const remaining = parseInt(response.headers.get('X-RateLimit-Remaining'));
if (remaining < 100) {
  console.warn('Approaching rate limit!');
}

Implement exponential backoff

When receiving 429 errors, wait progressively longer between retries

async function fetchWithRetry(url, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const response = await fetch(url);
    
    if (response.status !== 429) return response;
    
    const retryAfter = response.headers.get('Retry-After');
    const delay = retryAfter ? parseInt(retryAfter) * 1000 : Math.pow(2, i) * 1000;
    
    await new Promise(resolve => setTimeout(resolve, delay));
  }
}

Leverage caching

Cache responses on your end to reduce API calls. Images are cached for 24 hours on our end too.

Batch similar requests

If you need multiple similar images, consider reusing the same query with different dimensions

Upgrade when needed

Monitor your usage patterns and upgrade your plan before hitting limits regularly

How Sliding Windows Work

Placewise uses a sliding window algorithm for rate limiting, which is more flexible than fixed windows:

❌ Fixed Window (Not Used)

Resets at specific times, allows bursts

11:59 AM: 1000/1000 requests ✅

12:00 PM: 0/1000 (reset) ✅

12:01 PM: 1000/1000 requests ✅

→ 2000 requests in 2 minutes!

✅ Sliding Window (Used)

Continuous tracking, prevents bursts

11:59 AM: 1000/1000 requests ✅

12:00 PM: Still 1000/1000 ❌

12:30 PM: ~500/1000 ✅

→ Smooth, predictable limits