Docs / Routing
Profiles and selectors
Switch model sets at runtime with profiles, or resolve a virtual model ID per request with selectors.
Both let a client ask for a stable model name and get a different real model behind it. They solve different problems.
Profiles: switch a whole set at once
A profile is a named set of model ID replacements. One profile, or none, is active at a time, and you switch it from the web UI or the API.
profiles:
coding:
description: "Coding-focused model routing"
pins:
llm-code: "qwen3-coder-30b"
llm-plan: "gpt-oss-120b"
image-gen: ~
writing:
description: "Long-form writing"
pins:
llm-code: "gemma-3-27b"
llm-plan: "gemma-3-27b"
Your editor always requests llm-code. Flip the active profile and it gets a
different model, with no client-side change.
- Pin targets may be a local model, a fully qualified peer model, an alias, a
setParamsByIDalias, or a selector. - An empty string or YAML
~disables the pin — requests get a 404 and it is left out of model listings. Existing local, alias and peer IDs stay reachable. - Pins are applied first, before aliases, filters and routing.
- Startup and config reload select no profile.
Switch at runtime:
$ curl http://localhost:8080/api/profiles
$ curl -X PUT http://localhost:8080/api/profiles/active -d '{"name":"coding"}'
$ curl -X PUT http://localhost:8080/api/profiles/active -d '{"name":null}'
Selectors: resolve per request
A selector is a virtual model ID resolved to a concrete target on every request, based on a strategy.
selectors:
coding-model:
strategy: warm
targets: [gpt-oss-120b, qwen3-coder-30b]
name: "Coding Model"
description: "Best currently loaded coding model"
Three strategies:
warm — use the first target that is already ready; failing that, one that
is already starting; failing that, cold-start the first. This is the one you
want for "just use whatever is already loaded and don't make me wait".
pin — always the first target. The remaining entries are reference data
only. Useful as a stable indirection you can edit in one place.
spillover — fill each target up to a reservation count, then move to the
next. Good for spreading load across local and remote capacity:
selectors:
llama:
strategy: spillover
targets: [local-llama, peer-a/llama, peer-b/llama]
settings:
spillover: 4 # requests per active target before spilling over
Rules worth knowing:
- Selector IDs cannot collide with model IDs, aliases or fully qualified peer model names.
- A selector's targets cannot be other selectors.
- Selectors are not supported on
/upstream/<model>paths. - Profiles run first, so a profile pin may target a selector.
Which one?
Profiles are a mode switch you make deliberately — "I'm coding now". They change several mappings at once and persist until you change them again.
Selectors are automatic, per request, and based on current state. Nobody flips them.
They compose: pin llm-code in the coding profile to a warm selector, and
you get "when I'm coding, use whichever coding model is already hot".
Related
reference/config/profilesandreference/config/selectorsguides/routing/groups-and-matrix— which models can be loaded at the same time