Implement hybrid rate limiting: built-in API + KV#130
Merged
Conversation
Switch from Workers KV to Cloudflare's built-in Rate Limiting API. Benefits: - Free and unlimited (no KV write limits) - In-memory, faster (no network round-trips) - Simpler code (30 lines to 15 lines) - Same functionality (per-minute and per-hour limits) Changes: - wrangler.toml: Replace kv_namespaces with rate_limit binding - index.js: Simplify checkRateLimit() to use env.RATE_LIMITER.limit() - README.md: Remove KV setup instructions Closes #129
Pivot from full built-in API to hybrid approach based on PR review. Per-minute (bot protection): - Built-in Rate Limiting API - Fast (<1ms), in-memory - Configured in wrangler.toml with namespace_id Per-hour (human abuse prevention): - Workers KV for global consistency - Supports arbitrary time windows (3600s) - 1 write per request instead of 2 Benefits: - 50% reduction in KV writes (1 vs 2 per request) - Faster bot protection (<1ms vs ~10-50ms) - Global hourly limits across edge locations - Works on Pro Plan (unlimited KV writes) Changes: - wrangler.toml: Add [[ratelimits]] + keep [[kv_namespaces]] - index.js: Check built-in API first, then KV for hourly - README.md: Document hybrid approach and rationale Addresses review feedback on PR #130
Per IP address limits: - Production: 20/hour (~1 question every 3 minutes) - Development: 100/hour (for testing) Rationale: - Prevents sustained abuse - Allows reasonable research sessions - 20/hour is sufficient for legitimate use
Update CI/CD workflow to trigger on worker file changes, not just CORS. Changes: - Add workers/osa-worker/** to trigger paths - Check for worker file changes in push event - Deploy if CORS sync changed files OR worker files were pushed - Only commit CORS changes (not worker changes, already committed) - Update PR comment to reflect auto-deployment Now merging to develop will automatically deploy worker changes.
Address PR review findings: Critical fixes: - Reorder checks: hourly (KV read) → per-minute (token) → hourly (KV write) Prevents wasting per-minute tokens on hourly-rejected requests - Add radix parameter to parseInt() calls for safety Important fixes: - Use 'wrangler deploy' instead of 'wrangler deploy --env=""' for prod - Document KV race condition as known limitation This ensures per-minute tokens are only consumed by requests that pass the hourly check, preventing token waste and clearer error messages.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Hybrid rate limiting approach: Built-in Rate Limiting API for per-minute (bot protection) + Workers KV for per-hour (human abuse prevention).
Problem with Full Built-in API Approach
Initial attempt to use only the built-in API had critical issues:
period: 10orperiod: 60secondsHybrid Solution
Use the best tool for each job:
Benefits
Rate Limits
Per IP address:
Scope: Limits are per IP address, not per session. 20/hour prevents abuse while allowing reasonable research sessions.
Changes
wrangler.toml:
[[ratelimits]]binding for per-minute (built-in API)[[kv_namespaces]]for per-hour (KV)index.js:
README.md:
Implementation Details
Per-Minute (Built-in API):
Per-Hour (KV):
Deployment
No additional setup needed - KV namespaces already exist, built-in API is automatic.
Testing
Expected: First 10 fail Turnstile (403), then 429 (rate limit)
Performance Impact
References
Closes #129