Separate retry from fallback
A retry sends the request to the same route again because the failure may be temporary. A fallback changes the provider or model because the original route is unavailable or unsuitable.
Treating both actions as one generic retry loop makes incidents harder to diagnose and can multiply cost without improving success rate.
- Retry: timeout, connection reset, 429 or temporary 5xx response.
- Fallback: repeated provider failure, model capacity issue or policy restriction.
- Stop: invalid request, unsupported parameter or failed output validation.
Build a capability-compatible route table
Fallback models should be grouped by capability rather than brand. A vision request cannot fall back to a text-only model, and a strict JSON workflow should not route to a model that regularly violates the schema.
- Required input and output modalities.
- Minimum context and output length.
- Tool calling and structured-output support.
- Maximum acceptable price and latency.
Apply one request-level budget
The request budget should cover every retry and fallback attempt. Before starting another attempt, check whether the remaining latency and cost budget can support it.
const routePolicy = {
maxAttempts: 3,
maxLatencyMs: 18_000,
maxEstimatedCost: 0.12,
retryOn: [408, 429, 500, 502, 503, 504],
fallbackModels: ['primary-model', 'quality-fallback', 'fast-fallback'],
};Measure fallback quality, not only availability
A request that returns successfully can still be a product failure. Track output validation, user correction rate and task completion after a fallback event.
Recommended dashboard: route success, fallback rate, p95 latency, estimated cost, validation pass rate and quality score by model.
