Rate Limiting
maps.guru enforces rate limits to protect the platform and ensure fair access for all users.
Types of Limits
Monthly Quotas
Each subscription tier has monthly request quotas per service. See Rate Limits for tier-specific numbers.
Per-Second Rate Limits
To prevent abuse, there are per-second request limits:
| Tier | Requests/Second |
|---|---|
| Free | 10 |
| Pro | 100 |
| Enterprise | Custom |
How Enforcement Works
Rate limiting uses Cloudflare Durable Objects for real-time tracking:
- Each request increments a counter in the organization's Durable Object
- The counter is checked against the monthly quota
- If the quota is exceeded, the request is rejected with
429 - Counters reset on the first day of each month (UTC)
Rate Limit Headers
Every API response includes these headers:
X-RateLimit-Limit: 500000
X-RateLimit-Remaining: 499234
X-RateLimit-Reset: 2025-02-01T00:00:00Z
| Header | Description |
|---|---|
X-RateLimit-Limit | Monthly quota for this service |
X-RateLimit-Remaining | Requests remaining this month |
X-RateLimit-Reset | When the quota resets (UTC) |
Handling Rate Limits
When you receive a 429 response:
{
"statusCode": 429,
"message": "Monthly quota exceeded for maps service"
}
Best Practices
- Cache responses — Store geocoding results to avoid duplicate requests
- Use batch endpoints — Where available, batch multiple operations
- Monitor usage — Check the dashboard or API for current usage
- Implement backoff — For per-second limits, use exponential backoff
- Upgrade proactively — Monitor usage trends and upgrade before hitting limits
async function fetchWithRetry(url, retries = 3) {
for (let i = 0; i < retries; i++) {
const response = await fetch(url);
if (response.status === 429) {
const delay = Math.pow(2, i) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
return response;
}
throw new Error('Rate limit exceeded after retries');
}