Loading...
Before designing the system, we need to estimate the scale at which it will operate.
Daily Requests:
Storage for Logs:
Memory Requirements for Rate Limiting Data:
Define the APIs that will interact with the rate limiter.
POST/rate-limit/checkjson
Copy code
{
"api_key": "string",
"client_id": "string",
"endpoint": "string",
"timestamp": "integer"
}
X-RateLimit-Limit: Maximum number of requests allowed.X-RateLimit-Remaining: Number of requests remaining.X-RateLimit-Reset: Time when the rate limit window resets.GET/rate-limit/statusapi_keyjson
Copy code
{
"limit": 1000,
"remaining": 750,
"reset_time": "timestamp"
}
The rate limiter requires storage for:
| FieldTypeDescription | ||
| api_key | String | Unique identifier for the client |
| limit | Integer | Max requests allowed in time window |
| window_size | Integer | Time window in seconds |
| endpoints | List | Specific endpoints this limit applies to |
| created_at | Datetime | Timestamp of creation |
| updated_at | Datetime | Timestamp of last update |
| FieldTypeDescription | ||
| api_key | String | Unique identifier for the client |
| endpoint | String | API endpoint |
| window_start | Datetime | Start time of the window |
| count | Integer | Number of requests in current window |
| FieldTypeDescription | ||
| request_id | String | Unique identifier for the request |
| api_key | String | Client's API key |
| endpoint | String | API endpoint |
| status | String | Allowed or Blocked |
| timestamp | Datetime | Time of the request |
plaintext
Copy code
function isRequestAllowed(api_key, endpoint):
key = generateKey(api_key, endpoint, current_window)
count = Redis.INCR(key)
if count == 1:
Redis.EXPIRE(key, window_size)
if count > limit:
return False
return True
api_key to distribute load.Choice: Sliding Window Counter for a balance between accuracy and performance.
Choice: Redis for atomic operations and persistence options.
Choice: In-Line for immediate rate limit enforcement.