Rate Limiting

The Private AI Services Container provides a configurable method to control the number of requests per minute that the container can handle for different categories of endpoints. This improves scalability and helps prevent abuse, including denial-of-service (DOS) attacks.

There are two layers of limitation; a pre-authentication global limit for the whole container, and post-authentication category limits for validated API keys.

Every request first consumes from a shared, global bucket called GLOBAL. This happens before API key authentication, so requests with missing or invalid API keys are still rate limited. The global limit is configured using the following property:

"global_requests_per_min": 30000

This global value is per-container, per-pod limit and must be greater than 0. The default value is 30000.

Once authentication has succeeded, requests also consume from a category bucket tied to the validated API key identity.

The container distinguishes between two types of endpoints, each with an independently configurable rate limit:

This separation ensures that health and metrics scraping, as well as monitoring, does not interfere with the ability to serve regular API traffic from users or client applications.

If authentication is disabled, requests use only the global bucket. No monitor or service category bucket is created.

Container admins can start the container with rate limiting by adding a "ratelimiter" session in the configuration JSON file, as in the following:

{
  "ratelimiter": {
    "global_requests_per_min": 30000,
    "service_requests_per_min": 3000,
    "monitor_requests_per_min": 60
  }
}

This example configuration file would allow up to 30000 total requests per minute to the container, up to 3000 API (service) requests per minute per IP address, and up to 60 monitor (health, metrics) requests per minute per IP address.

Each IP address is tracked independently for both service and monitor groups and counters reset every minute. If a client exceeds its assigned quota within a 60-second window, the server responds with HTTP 429 (Too Many Requests). This logic protects the core APIs from being overwhelmed while ensuring observability endpoints remain responsive.

Several response headers are provided to help monitor the requests usage:

If, for example, service_requests_per_min has a value of 500 and a client sends 400 scoring or inference requests in the first 25 seconds, the response will include: x-ratelimit-limit-requests = 500, x-ratelimit-remaining-requests = 100 (500 - 400), and x-ratelimit-reset-requests = 35s (60 seconds - 25 seconds).

With a monitor_requests_per_minute value of 120, if a client sends 60 health check requests in the first 15 seconds, the response will include: x-ratelimit-limit-requests = 120, x-ratelimit-remaining-requests = 60 (120-60), and x-ratelimit-reset-requests = 45s (60 seconds - 15 seconds).