Skip to the content.

Context

A user-facing app makes many LLM calls, but only some are on a user’s critical path, where the model has to respond fast. The rest (pre-computation, batch classification, offline validation) are latency-insensitive. This pattern is about latency, not quality: latency-tolerant work can reach the same quality far more cheaply, because tolerating a slower turnaround unlocks a batch endpoint (the same model at roughly half price), a comparably capable cheaper provider, or owned hardware.

Example

Zeeguu runs the pattern in two places.

Two model tiers for one task. Article simplification takes two paths, chosen by whether a reader is waiting.

  1. When a learner opens an article that has not been simplified yet, the on-demand simplification runs on a fast model (Anthropic Haiku, the “real-time text-simplification” path), so the reader is waiting as little as possible.
  2. The bulk, ahead-of-time simplification of the crawled article feed, which no user is blocking on, is pinned to the cheaper, slower DeepSeek model (crawl_round_robin(..., simplification_provider='deepseek')); the CEFR (reading-difficulty) assessment done during crawling is likewise DeepSeek-only, “for consistency with batch crawling”.

Same task, two model tiers, selected by latency-sensitivity rather than by the task itself.

An owned machine as the slow path. Zeeguu’s latency-insensitive LLM work (CEFR assessment, translation validation, meaning-frequency classification, ahead-of-time example generation) all bills against metered APIs, yet none of it is on a user’s critical path. A single owned machine (a Mac Studio running Ollama) drains that entire queue overnight on a local model at zero per-token cost, with the cloud API as a deadline-bound fallback for whatever is not done by morning. It moves a whole category of spend off the metered bill onto hardware that already sits idle at night.

Problem

How can the premium cost of the real-time model be avoided on the large share of LLM work that no user is waiting for?

Forces

Solution

Split inference into a fast path and a slow path, and route each task by whether a user is blocking on the result, not by what the task is.

Realize the slow path with whatever is cheapest for the work, in rough order of adoption cost:

Consequences

Slow-path output is much cheaper and best-effort in timing, so only latency-insensitive work is eligible, and the fast path (or cloud) stays as a deadline-bound fallback (composes with Fail-Fast Provider Chain and Escalate to the LLM). The slow path targets the same quality as the fast one, only more cheaply, so it is not a quality compromise. Results carry a different model identity and should be recorded as such (composes with LLM Output Provenance); untrusted slow-path output may need validation (composes with LLM Content Validation Tracking). Which model runs on which path should live in one place (composes with Centralized Model Selection), so re-tiering a feature is a one-line change.

Known Uses

Notes


💬 Open an issue about this pattern