- Overview
- Project Structure
- Key Components
- System Architecture
- Workflow
- Rate Limiting Logic
- Configuration
- API Endpoints
- Durable Objects
- Development
- Deployment
- Testing
- Error Handling and Logging
- Security Considerations
- Limitations
- Future Improvements
- Related Components
The Rate Limiting Worker is a Cloudflare Worker designed to implement rate limiting based on configurable rules. It works in conjunction with the Rate Limit Configurator UI and Config Storage Worker, fetching rules from a shared Durable Object and applying them to incoming requests.
The project now follows a modular architecture:
src/
├── constants/ # Application constants and configuration
├── core/ # Core application logic
├── services/ # Business logic services
│ ├── action-handler-service.ts
│ ├── condition-evaluator-service.ts
│ ├── config-service.ts
│ ├── fingerprint-service.ts
│ ├── rate-limiter-service.ts
│ └── static-assets-service.ts
├── types/ # TypeScript types and interfaces
├── utils/ # Utility functions
│ ├── crypto.ts
│ ├── request.ts
│ └── index.ts
└── index.ts # Entry point
public/ # Static assets (served by Cloudflare's asset platform)
└── pages/ # Rate limit page templates
├── rate-limit.html
└── rate-limit-info.html
graph TD
A[index.ts] --> B[core/worker.ts]
B --> C[services/config-service.ts]
B --> D[services/condition-evaluator-service.ts]
B --> E[services/fingerprint-service.ts]
B --> F[services/rate-limiter-service.ts]
B --> G[services/action-handler-service.ts]
C --> I[ConfigStorage Durable Object]
F --> J[RateLimiter Durable Object]
- index.ts: The main entry point for the worker, exports the RateLimiter Durable Object class.
- core/worker.ts: Contains the core worker functionality, handling requests and dispatching to appropriate services.
- services/config-service.ts: Manages fetching and caching of rate limiting rules with performance optimizations.
- services/condition-evaluator-service.ts: Provides functions for evaluating conditions with field caching and optimized regex handling.
- services/fingerprint-service.ts: Handles the generation of unique identifiers for requests based on configured parameters.
- services/rate-limiter-service.ts: Implements the core rate limiting logic and Durable Object functionality.
- services/action-handler-service.ts: Handles different actions when rate limits are exceeded.
- services/static-assets-service.ts: Manages the serving of static HTML pages for rate limit responses.
- utils/: Contains utility functions for cryptography, request handling, logging, and performance tracking.
- public/pages/: Contains static HTML pages for rate limit and rate limit info responses, which are served with Cloudflare's assets platform.
graph TD
A[Client] -->|HTTP Request| B[Rate Limiting Worker]
B -->|Fetch Rules| C[Config Storage Worker]
B -->|Apply Rate Limit| D[RateLimiter Durable Object]
B -->|Allow/Block| E[Origin Server]
F[Rate Limiter UI] -->|Manage Rules| C
sequenceDiagram
participant Client
participant RateLimitingWorker
participant ConfigStorageWorker
participant RateLimiterDO
participant OriginServer
Client->>RateLimitingWorker: HTTP Request
RateLimitingWorker->>ConfigStorageWorker: Fetch Rules
ConfigStorageWorker->>RateLimitingWorker: Return Rules
RateLimitingWorker->>RateLimitingWorker: Evaluate Request
RateLimitingWorker->>RateLimiterDO: Check Rate Limit
RateLimiterDO->>RateLimitingWorker: Rate Limit Status
alt Rate Limit Not Exceeded
RateLimitingWorker->>OriginServer: Forward Request
OriginServer->>RateLimitingWorker: Response
RateLimitingWorker->>Client: Forward Response
else Rate Limit Exceeded
RateLimitingWorker->>Client: Rate Limit Response
end
The rate limiting is based on a sliding window algorithm. Each client is identified by a unique fingerprint generated from configurable request properties. The worker tracks the number of requests made by each client within the specified time window.
The rate limiting rules are stored in and fetched from a ConfigStorage
Durable Object. Each rule can specify:
- Rate limit (requests per time period)
- Fingerprint parameters
- Matching conditions
- Actions to take when rate limit is exceeded
The worker handles the following special endpoints:
/_ratelimit
: Returns information about the current rate limit status for the client.
The worker uses two types of Durable Objects:
- ConfigStorage: Stores and manages the rate limiting rules (via the Config Storage Worker).
- RateLimiter: Implements the rate limiting logic for each unique client identifier.
- Node.js (v16+)
- npm or yarn
- Wrangler CLI
-
Clone the repository:
git clone https://github.com/erfianugrah/rate-limiter-worker.git cd rate-limiter-worker
-
Install dependencies:
npm install
Run the development server:
npm run dev
This command starts a local development server that simulates the Cloudflare Workers environment.
npm run lint # Check for code style issues
npm run lint:fix # Fix code style issues
npm run typecheck # Verify TypeScript types
npm run validate # Run typecheck, lint, and tests in one command
npm run test # Run tests in watch mode
npm run test:run # Run tests once without watch mode
# Build TypeScript files
npm run build
# Full validation and deployment
npm run publish
# Environment-specific deployments
npm run publish:staging # Deploy to staging environment
npm run publish:prod # Deploy to production environment
To deploy the worker:
-
Ensure you have the Wrangler CLI installed and authenticated with your Cloudflare account.
-
Choose the appropriate deployment command:
# Deploy to default environment after running tests npm run publish # Deploy to staging environment npm run publish:staging # Deploy to production environment npm run publish:prod
Each command will build the TypeScript files and deploy the worker to the appropriate Cloudflare environment. The publish
command also runs tests to ensure everything is working correctly before deployment.
The project uses Vitest for unit testing. Run the tests with:
npm test
Test files are organized to match the structure of the source code:
test/
├── core/ # Tests for core worker functionality
├── services/ # Tests for business logic services
│ ├── action-handler-service.test.ts
│ ├── condition-evaluator-service.test.ts
│ ├── config-service.test.ts
│ ├── fingerprint-service.test.ts
│ └── rate-limiter-service.test.ts
└── utils/ # Tests for utility functions
├── crypto.test.ts
└── request.test.ts
To test the rate limiting functionality, you can use the provided rate-limit-tester.py
script. This script allows you to simulate multiple requests and analyze the rate limiting behavior.
Usage:
python rate-limit-tester.py -u <URL> -n <NUMBER_OF_REQUESTS> -d <DELAY_BETWEEN_REQUESTS>
The script provides detailed output, including response times, status codes, and rate limit headers. It also generates a graph of the results, saved as rate_limit_test_results.png
.
You can also use the bash-based test script for quick testing:
./rl-test.sh <URL>
This script will send a series of requests to the specified URL and display the rate limit headers.
The worker includes extensive logging throughout its execution. In production, these logs can be viewed in the Cloudflare dashboard. Errors are caught and logged, with the worker attempting to gracefully handle failures by passing through requests when errors occur.
- Ensure that the worker is deployed with appropriate access controls to prevent unauthorized manipulation of rate limiting rules.
- The worker trusts headers like
true-client-ip
andcf-connecting-ip
for client identification. Ensure these are set correctly in your Cloudflare configuration. - Consider implementing additional security measures such as API key validation for the configuration endpoints.
- The current implementation has a hard-coded body size limit for fingerprinting and condition evaluation.
- The configuration is cached to reduce Durable Object reads. This means that rule changes may take some time to propagate.
The codebase includes several performance optimizations:
- Config Caching: Implements a TTL-based cache with background refresh for configuration data
- Field Value Caching: Caches field values to avoid redundant extractions in condition evaluation
- Body Caching: Prevents duplicate parsing of request bodies
- Regex Pattern Caching: Reuses compiled regex patterns for recurring evaluations
- Memory Optimizations: Careful memory management to avoid excessive allocations
For detailed information on performance improvements, see PERFORMANCE-IMPROVEMENTS.md.
The codebase has been refactored with the following improvements:
- ✅ Improved modular architecture with proper separation of concerns
- ✅ TypeScript support with comprehensive type definitions
- ✅ Enhanced caching mechanisms for configuration and rate limit data
- ✅ Optimized condition evaluation with field and regex caching
- ✅ Structured logging for better debugging and monitoring
- ✅ Improved error handling and fallback mechanisms
Additional improvements planned for the future:
- Add more comprehensive test coverage with unit tests for all services
- ✅ Create a proper UI component library for rate limit pages
- Implement additional fingerprinting methods for more accurate client identification
- Add telemetry and metrics for monitoring rate limit behavior in production
- Support for more complex rate limiting scenarios like tiered limits or dynamic limits
This Rate Limiting Worker is part of a larger rate limiting system. The other components are:
- Rate Limiter UI: Provides a user interface for managing rate limiting rules.
- Rate Limiter Config Storage: Stores and manages the rate limiting rules.
For a complete setup, ensure all components are properly configured and deployed.