67 docs indexed
Find each model's in-flight knee with a bounded ramp probe, then apply the recommended max_in_flight slots from the dashboard or Management API.
Each registered model can carry its own max_in_flight slot cap — an optional ceiling on concurrent requests for that route, inside the global fairshare scheduler limit (OBLETH_GLOBAL_MAX_IN_FLIGHT). Auto-tune helps you set that cap for self-hosted chat and embedding models by driving real load directly at the upstream and measuring where throughput stops climbing or tail latency breaches your SLO.
Cloud-hosted models should stay on a static cap so spend stays bounded. Auto-tune is intentionally recommend-only: the probe never writes config; you apply the suggestion explicitly.
From the dashboard, open a chat or embedding model and switch to its Capacity tab to set the admission weight, capacity mode (static/tuned), max-slot cap, and to launch the auto-tune probe:
| Mode | Meaning |
|---|---|
static (default) | max_in_flight is operator-set. Use for cloud APIs and any model where you want a fixed spend/concurrency ceiling. |
tuned | max_in_flight was last written by auto-tune. capacity_tuned_at records when. You can flip back to static at any time without clearing the slot value. |
Both modes use the same max_in_flight field. The mode is metadata for operators and audit — it does not change admission behavior on the data plane.
The ramp probe runs in the Management API (obleth-admin). It:
api_base, bypassing obleth's gateway admission, so the measurement reflects the upstream's true capacity rather than the gateway's current cap.baseline_p99_ms × latency_headroom, with a 100 ms absolute floor so a very fast model isn't tripped by ordinary jitter.latency_degraded — a step's p99 climbed past the latency ceilingplateau — throughput gain vs the previous step fell below ~7% (saturation)max_concurrency — reached the ceiling with no knee; the real knee may be higherno_data — no step produced usable samples (upstream unreachable)The recommended max_in_flight is the highest concurrency that stayed under the
latency ceiling while still meaningfully improving throughput.
The ceiling is sized from whichever of these you supply, in order — so a one- or two-replica backend is never pounded all the way to 512:
| Input | Ceiling |
|---|---|
max_concurrency | Used as given (clamped to 512) |
replicas | replicas × 32 — 32 concurrent probes per replica, generous headroom above the likely knee |
| neither | 64 |
Latency, and therefore the in-flight knee, is very different for a short chat turn than for a large-context coding turn, so the probe request is shaped to match real usage:
workload | Prompt | Reply |
|---|---|---|
chat (default) | ~512 tokens | 128 tokens |
coding | ~6,000 tokens | 512 tokens |
| Limit | Value |
|---|---|
| Wall clock | ≤ 60 seconds (all steps combined) |
| Total requests | ≤ 20,000 |
| Max concurrency | ≤ 512 (regardless of request) |
latency_headroom | clamped to 1.5 – 20 |
| Supported modalities | chat, embedding only |
Defaults when omitted: workload = chat, latency_headroom = 4.0, and a ramp
ceiling of 64 when neither replicas nor max_concurrency is given.
All three routes are audit-logged. See Management API — Models for the full listing.
curl -X PUT "http://localhost:9180/api/v1/models/$MODEL_ID/capacity-mode" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"capacity_mode": "static"}'
curl -X POST "http://localhost:9180/api/v1/models/$MODEL_ID/autotune" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"workload": "chat", "latency_headroom": 4.0, "replicas": 2}'
Example response (truncated):
{
"model_id": "...",
"model_name": "qwen3-8b",
"modality": "chat",
"workload": "chat",
"recommended_max_in_flight": 32,
"knee_reason": "latency_degraded",
"baseline_p99_ms": 280,
"latency_ceiling_ms": 1120,
"latency_headroom": 4.0,
"max_concurrency": 64,
"recommended_throughput_rps": 18.4,
"duration_ms": 12400,
"steps": [
{
"concurrency": 16,
"throughput_rps": 17.2,
"p50_ms": 420,
"p99_ms": 890,
"requests": 430,
"errors": 0
},
{
"concurrency": 32,
"throughput_rps": 18.4,
"p50_ms": 510,
"p99_ms": 1120,
"requests": 460,
"errors": 0
}
]
}
curl -X POST "http://localhost:9180/api/v1/models/$MODEL_ID/autotune/apply" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"max_in_flight": 32}'
This sets max_in_flight, flips capacity_mode to tuned, stamps capacity_tuned_at, syncs the data plane, and records an audit entry. You can also apply a value from a saved probe report without re-running the probe.
On the Models page, expand a chat or embedding route:
Static / Tuned toggle in operational controls (calls PUT …/capacity-mode).max_in_flight editor (calls PUT …/capacity).The auto-tune panel is hidden for non-probeable modalities (image, audio_*, etc.).
| Scenario | Recommendation |
|---|---|
| Self-hosted vLLM / Aibrix / local OpenAI-compatible server | Run auto-tune during a quiet window, then apply. Re-run after hardware or replica changes. |
| OpenAI, Together, or other metered cloud APIs | Keep static and set a conservative max_in_flight manually to cap spend. |
| Production model under heavy traffic | Avoid probing during peak — the probe adds real concurrent load at the upstream. |
| After apply | Confirm obleth_queue_depth stays near zero and GPU/backend utilization looks healthy. |
Per-model slots sit inside the global scheduler cap. Effective admission is the minimum of global max_in_flight, per-model slots, tenant/group limits, and fairshare. See Capacity Provider and Scaling.