The prediction hot path: route, admit, cache, hook, dispatch, record.
Everything in this module runs in the calling process — a Phoenix controller, an Oban job,
a Task. Nothing here is a GenServer, and that is the point: MLServe adds no serialisation
point between your request and the model.
The order of operations is deliberate:
route lookup (1 ETS read)
→ admission control (atomic counter)
→ telemetry span opens
→ cache lookup
→ preprocess hook
→ dispatch
→ postprocess hook
→ cache write
→ telemetry span closes
→ counters settledCache, hooks and validation all happen before dispatch, so a worker is occupied only for the
duration of actual inference. A preprocess hook that queries Postgres for stored features
runs on the caller's own scheduler time, never on a GPU worker's.
Dispatch strategies
| Model | Path |
|---|---|
concurrency: :shared | :persistent_term.get/1 then the backend, in this process. No message passing, no copies. |
batching: configured | GenServer.call to the model's MLServe.Batcher, which coalesces concurrent callers. |
concurrency: :exclusive | Pick a worker, GenServer.call it. |
Summary
Functions
Runs a batch prediction. See MLServe.batch_predict/3.
Runs a single prediction. See MLServe.predict/3.
Functions
Runs a batch prediction. See MLServe.batch_predict/3.
Runs a single prediction. See MLServe.predict/3.