A pattern that shows up in a lot of serious homelabs: one small box that is always on (NAS, mini PC, or modest GPU server) running Ollama with “good enough” models, plus a stronger workstation that is sometimes online with larger models. You want requests to succeed when the workstation is asleep, and to get better quality when it is awake — without rewriting every client.
This guide covers the architecture, a simple health-based router, timeouts, logging for cost/quality trade-offs, and the security mistakes that turn a LAN helper into an open proxy.
Single-host setups are simpler. Move to multi-host when uptime and model size start fighting each other.
Always online. Runs smaller coder and general models. Bound to a stable LAN IP. Firewall allows only trusted subnets. This is the default destination when nothing else is healthy.
Optional. Larger models, faster tokens when present. May disappear when the machine sleeps or leaves the network. Clients must treat it as best-effort.
A small program or script that, for each task class (code, reasoning, extraction), walks a preference list:
try boost models first if the host is up, else fall back to baseline. Health is usually
GET /api/tags with a short timeout.
Keep model preference in one config file so every tool does not invent its own failover. Conceptually:
# conceptual preference list (YAML-style)
code:
- host: workstation
model: qwen2.5-coder:14b # or your larger coder
- host: baseline
model: qwen2.5-coder:7b
reasoning:
- host: workstation
model: qwen3:27b
- host: baseline
model: qwen3:14b
extraction:
- host: baseline
model: nuextract:latest
The router resolves host to a base URL, checks health, then calls
/api/chat or /api/generate. If the first choice fails (down, timeout, model missing),
try the next. Do not infinite-loop: after the list is exhausted, return a clear error.
/api/tags, not only that the port answers.
By default many installs listen on localhost only. For multi-host routing, Ollama on each host must accept
LAN connections. Typical approach: set the host environment so the server listens on
0.0.0.0 (or the LAN interface), then restrict with host firewall rules to your trusted subnet.
Without logs, you will not know whether the expensive workstation is actually helping. Log at least:
After a week you can answer: “Did boost host save enough quality to justify leaving it on?” and “Which jobs never need the big model?”
latest tags make debugging harder across machines.An open Ollama port on a flat LAN is an unauthenticated compute and data-exfil surface. Anyone who can reach it can send prompts that include whatever context your agents attach. Treat it like an internal API:
for each candidate in preference[task]:
if not health_ok(candidate.host): # cached
continue
if candidate.model not in tags(candidate.host):
continue
try:
return chat(candidate, messages, timeout=long)
except TemporaryError:
continue
raise NoHealthyModel(task)
That is enough for most labs. You can later add weighted load balancing; start with failover and good logs.
If the problem is “service up on LAN but dead on the public tunnel,” see Origin vs tunnel: reading 502 and 530 and the free OriginReach CLI.
Independent notes from Tactical Data Concepts. Not affiliated with Ollama or Cloudflare. Affiliate disclosure: none in this article.