congestion_control::Component (aka CC) limits the active requests count. CC has a RPS (request per second) limit mechanism that turns on and off automatically depending on the main task processor workload. In case of overload CC responds with HTTP 429 codes to some requests, allowing your service to properly process the rest. The RPS limit is determined by a heuristic algorithm inside CC. All the significant parts of the component are configured by dynamic config options USERVER_RPS_CCONTROL and USERVER_RPS_CCONTROL_ENABLED.
CC can run in fake-mode with no RPS limit (but FSM works). CC goes into fake-mode in the following cases:
fake-mode can be useful for more flexible traffic restriction settings, according to it's more complex logic, which can be implemented in a middleware.
congestion_control::Component can be useful if your service stops handling requests when overloaded, significantly increasing response time, responding with HTTP 500 codes to requests, eating memory.
Including CC in your service will help you handle some reasonable request flow returning HTTP error codes to the rest.
congestion_control::Component cannot be useful if:
It is a good idea to disable congestion_control::Component in unit tests to avoid getting HTTP 429 on an overloaded CI server.
The Congestion Control logic is implemented as sensors (overloads_ps, rps) and a state machine with variables.
Sensor Data:
State Machine Variables:
The congestion control state machine has 5 states:
Semantics of the is_overloaded flag:
Key State Transitions:
Transitions between is_overloaded_now states:
Purpose of splitting is_overloaded and is_overloaded_now: This design mitigates flapping. Services may frequently execute isolated long tasks that monopolize the task processor for significant periods without critically impacting performance (wait times are negligible). Simultaneously, it ensures progressive limit increases when many tasks experience low wait times.
In some situations default settings are ineffective. For example:
in those situations congestion_control::Component settings need adjusting.
Basic dynamic configuration options:
The component exports metrics under the congestion-control.rps prefix. If the service has no handlers with throttling enabled, the component is force-disabled and does not export these metrics.
| Metric | Type | Description |
|---|---|---|
| is-enabled | GAUGE | 1 if congestion control can enforce the RPS limit, 0 in fake mode or when disabled by dynamic config. |
| is-activated | GAUGE | 1 if an RPS limit exists and current_rps * activated_factor < limit, otherwise 0. activated_factor is configured by USERVER_RPS_CCONTROL_ACTIVATED_FACTOR_METRIC. |
| limit | GAUGE | Current RPS limit. The metric is omitted when there is no limit or congestion control is disabled. |
| states.no-limit | RATE | Rate of controller checks with no RPS limit. |
| states.not-overloaded-no-pressure | RATE | Rate of controller checks with is_overloaded=false, is_overloaded_now=false, and an RPS limit. |
| states.not-overloaded-under-pressure | RATE | Rate of controller checks with is_overloaded=false, is_overloaded_now=true. |
| states.overloaded-no-pressure.v2 | RATE | Rate of controller checks with is_overloaded=true, is_overloaded_now=false. |
| states.overloaded-under-pressure.v2 | RATE | Rate of controller checks with is_overloaded=true, is_overloaded_now=true. |
| time-from-last-overloaded-under-pressure-secs | GAUGE | Seconds since the controller was last in the is_overloaded=true, is_overloaded_now=true state. |
| current-state | GAUGE | Numeric identifier of the current controller state; see the mapping below. |
The current-state values correspond to the state metrics as follows:
| Value | State |
|---|---|
| 0 | states.no-limit |
| 1 | states.not-overloaded-no-pressure |
| 2 | states.not-overloaded-under-pressure |
| 3 | states.overloaded-no-pressure.v2 |
| 4 | states.overloaded-under-pressure.v2 |
For compatibility with existing alerts, states.overloaded-no-pressure and states.overloaded-under-pressure are also exported as legacy GAUGE metrics containing raw cumulative counter values. New dashboards and alerts should use their RATE counterparts with the .v2 suffix.
In case RPS mechanism is triggered it is recommended to ensure that there is no mistake. If RPS triggering coincided with peak CPU consumption than there is no mistake and the lack of resources situation needs to be resolved:
If RPS triggering did not coincide with peak CPU consumption than there is no lack of resources but a different kind of problem. Most likely your service has synchronous operations that block the coroutine flow. If this is the case then you need to either: