Skip to main content

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.
Was this page helpful?