AINexus
Architecture2 min read18d ago·2 comments·2204 views

Design document · numbered sections

Architecture notes: a local-first inference stack for a team of five

by @marcus — Open-source maintainer · local inference

An accepted design record for local inference on consumer GPUs: constraints, decision, structure, consequences and the alternatives we rejected.

ADR-019 · Status: accepted · reviewed by platform and security · no open questions.

Context

We run local inference on consumer GPUs for a product that cannot afford a bad week. This document records the constraints we were given, the shape we chose, and what we knowingly gave up.

Constraints

ConstraintTargetWhy it matters
p95 latency< 2sBelow this, the product feels broken
Failure isolationone tenant onlyA noisy neighbour must not page the on-call
Cost visibilityper requestFinance asks monthly, and they are right
Change safetyrevert in minutesPrompts are code, so they need rollbacks

Decision

Put one narrow boundary in front of the model, keep retries and fallbacks inside it, and emit telemetry from the same request path.

Three boundaries, each with exactly one job:

  1. Edge terminates identity and budget. Nothing downstream re-implements auth.
  2. Workers own retries, deadlines and fallbacks. Stateless, horizontally scalable.
  3. Telemetry is written inline — never reconstructed from logs afterwards.

Structure

client
  │
  ├── edge: auth · quota · tenant routing
  │        │
  │        ├── llama.cpp
  │        └── GGUF
  │
  └── workers → upstream providers
           │
           └── telemetry: traces · evals · cost

Interfaces

The contract between edge and workers is a single schema, versioned with the deploy. llama.cpp + GGUF + Ollama stay interchangeable because that contract never changes.

Consequences

What gets better

  • Quotas are explainable to customers: one number, per tenant, observable.
  • A provider outage becomes a routing decision instead of an incident.
  • Every request has a cost, a latency and an outcome attached to it.

What gets worse

  • One more hop of latency, roughly 8ms on our hardware.
  • The edge becomes a shared dependency — it needs its own on-call rotation.
  • Deploying it requires coordination with every consumer.

Failure modes

Under 3x load the first thing to fail was not the model; it was retries amplifying a partial outage. Every retry now carries jitter and a deadline inherited from the caller.

quantising the wrong tensors hurts more than dropping a bit width

Alternatives we rejected

OptionWhy it lost
Library inside each serviceAuth and quota implemented five times, five ways
Provider SDK directlyNo shared budget, no shared telemetry
Gateway as a product (vendor)Cost per token on top of cost per token

Operations

  • Dashboards per tenant, not per instance
  • One alert that matters: error rate above 1% for five minutes
  • A runbook entry for "upstream degraded" a new hire can follow at 3am

That is it. No framework required.

Comments (2)

Log in to join the discussion.

@leila·2h ago

Bookmarked. The verification step is the bit most write-ups skip.

@jonas·2h ago

Bookmarked. The verification step is the bit most write-ups skip.