Skip to main content

One deployment-wide runtime policy governs how Rolter talks to upstreams under load: how hard it retries, how long it waits, and how many requests it admits at once. Edit it from Settings → Performance Tuning in the dashboard, or through the management API.


Retries#

SettingRangeMeaning
retry_max_retries0–10Retry budget for a single client request.
retry_base_ms0–60000First backoff interval.
retry_max_ms0–600000Ceiling the exponential backoff grows to.

The cap cannot be lower than the base — an incoherent pair is rejected rather than silently clamped.


Timeouts#

timeout_connect_s (0–300) bounds establishing the upstream connection; timeout_request_s (0–3600) bounds the wait for the upstream’s response headers. Once the headers arrive the body is not timed, so a streaming response that has started runs to completion however long it takes. Zero disables the corresponding timeout.


Admission queue#

Rolter creates an independent bounded queue and worker set per provider, so one slow provider cannot consume the admission capacity that healthy providers need.

SettingRangeMeaning
queue_capacity1–100000Requests that may wait for a worker.
queue_workers1–2048Requests per provider waiting for response headers (does not cap streams).
queue_backpressuredrop / block / errorWhat happens when the queue is full.
queue_block_ms0–120000How long block waits for capacity.

On the dashboard the queue fields are disabled while the queue is off, and the block timeout unless the policy is block. A disabled field is not validated, so an out-of-range value already stored never blocks Save, and saving keeps it unchanged. It is checked again once the field is enabled.

The dashboard shows each problem under the field it belongs to, all at once, and the backpressure dropdown offers Drop, Block and Error for the wire values below. Save and Discard changes wait for an edit; a panel holding one is marked Edited, the footer counts the unsaved settings, and leaving the screen with unsaved edits asks first.

The three backpressure policies:

  • drop — shed the request immediately with an overload response.
  • block — wait for capacity until queue_block_ms expires. This requires a non-zero timeout; blocking forever would park callers indefinitely, so the combination is rejected.
  • error — return a structured queue_full error immediately. This is the default.

Shed requests never fail over to a sibling target and never retry: admission backpressure is a signal to the caller, not an upstream fault. Each policy has a fixed wire shape:

PolicyHTTP statuserror.codeerror.type
drop503queue_droppedoverloaded_error
block (timed out)429queue_timeoutrate_limit_error
error429queue_fullrate_limit_error

Rejections and timeouts are counted separately on the gateway metrics endpoint as rolter_provider_queue_rejections_total and rolter_provider_queue_timeouts_total, so backpressure is visible as a real counter rather than only as a client-side status code.


API#

Both endpoints are for a superadmin or an operator (a deployment role). Every update is audited.

Send the full policy, not a patch. A successful update bumps config_version, so gateways pick it up on their next snapshot poll without a restart.