Skip to content

feat(rate-limit): bypass per-IP throttle for known AI crawler UAs - #615

Merged
Flotapponnier merged 2 commits into
devfrom
feat/ai-crawler-bypass-rate-limit
Jun 21, 2026
Merged

feat(rate-limit): bypass per-IP throttle for known AI crawler UAs#615
Flotapponnier merged 2 commits into
devfrom
feat/ai-crawler-bypass-rate-limit

Conversation

@Flotapponnier

Copy link
Copy Markdown
Collaborator

AI crawlers (PerplexityBot, GPTBot, ClaudeBot, etc.) often share a small
pool of egress IPs across many user queries. The per-IP rate limit on
/api/citable, /api/llm-context, /llms-full.txt (which re-exports
llm-context), /api/stat/[slug], /api/mcp/[transport] and adjacent
read-only endpoints was triggering 429 responses to legitimate AI
citation fetches, lowering OCB visibility in Perplexity, ChatGPT search,
Claude, and Google AI Overviews.

This change adds a User-Agent allowlist in rate-limit.ts. Requests with
a known AI crawler UA bypass the throttle without consuming a token.
Human traffic and unknown UAs remain throttled. UA spoofing is possible
but the read-only nature of these endpoints makes it a non-concern: we
WANT to be cited.

Allowlist patterns (case-insensitive substring match): GPTBot,
ChatGPT-User, OAI-SearchBot, ClaudeBot, anthropic-ai, Claude-Web,
PerplexityBot, Google-Extended, GoogleOther, CCBot, Bytespider,
Applebot-Extended, Amazonbot, Diffbot, YouBot, DuckAssistBot.

Optional AI_BYPASS_DEBUG=true env var enables a one-line console log
per bypass for debugging.

Adds tests covering: known AI UA bypasses a drained bucket, default
Chrome UA still throttled after capacity, missing UA defaults to
throttled, omitting the optional req argument keeps original behaviour.

Validation:

  • pnpm typecheck: clean
  • pnpm lint: clean (only preexisting warnings)
  • bun test src/: 97 pass / 0 fail (6 new tests)
  • pnpm build: green

Adds Meta-ExternalAgent, Meta-ExternalFetcher, cohere-ai, Perplexity-User
(all already in robots.txt), plus AI2Bot, Ai2Bot-Dolma, Kagibot,
FacebookBot, MistralAI-User, TimpiBot, Webzio-Extended for completeness.
Comment now states the regex must stay in sync with src/app/robots.ts.

Western LLM coverage is at ~95 percent after this. Chinese models other
than ByteDance (Bytespider) do not publish a documented bot UA, so they
fetch via generic browser UAs and stay throttled by design.
@Flotapponnier
Flotapponnier merged commit dea277d into dev Jun 21, 2026
1 check passed
@Flotapponnier
Flotapponnier deleted the feat/ai-crawler-bypass-rate-limit branch June 21, 2026 13:29
Flotapponnier added a commit that referenced this pull request Jun 21, 2026
…) (#617)

* feat(rate-limit): bypass per-IP throttle for known AI crawler user agents

* rate-limit: expand AI bot allowlist to match robots.txt

Adds Meta-ExternalAgent, Meta-ExternalFetcher, cohere-ai, Perplexity-User
(all already in robots.txt), plus AI2Bot, Ai2Bot-Dolma, Kagibot,
FacebookBot, MistralAI-User, TimpiBot, Webzio-Extended for completeness.
Comment now states the regex must stay in sync with src/app/robots.ts.

Western LLM coverage is at ~95 percent after this. Chinese models other
than ByteDance (Bytespider) do not publish a documented bot UA, so they
fetch via generic browser UAs and stay throttled by design.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant