Rate Limits
Quotas, throttling, and best practices
2 min read
KLOAKD enforces rate limits per organization, per module. Each module has independent quotas based on your plan.
Metered modules
| Module | Metering ID | What counts |
|--------|-------------|-------------|
| Evadr | evadr | Each fetch request |
| Webgrph | webgrph | Each crawl operation |
| Skanyr | skanyr | Each discovery + data retrieval |
| Nexus | nexus | Each analysis request |
| Parlyr | parlyr | Each NLP parse |
| Fetchyr | fetchyr | Each login/session |
| Kolektr | kolektr | Each extraction |
Quotas by tier
| Tier | Requests/day | Discoveries | Pages/discovery | |------|-------------|-------------|-----------------| | Playground | 10 | 10 (lifetime) | 500 | | Pro | 1,000 | 50/month | 500 | | Developer | 100,000 | 200/month | 2,000 | | Enterprise | Unlimited | Unlimited | Unlimited |
See Pricing for full tier comparison.
Response headers
| Header | Description | |--------|-------------| | X-RateLimit-Limit | Requests allowed per window | | X-RateLimit-Remaining | Requests remaining | | X-RateLimit-Reset | Unix timestamp of reset | | Retry-After | Seconds to wait (on 429 only) |
Handling 429
from kloakd.errors import RateLimitError
try:
result = client.evadr.fetch("https://example.com")
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after}s")
Best practices
- Use artifact chaining - one evadr.fetch reused by Webgrph, Skanyr, and Kolektr multiplies throughput.
- Use page_all helpers - they batch efficiently and respect rate limits.
- Use async methods for concurrent requests within your quota.
- Use SSE streaming to avoid polling overhead on long-running operations.