Docs · Concepts

Admission, scheduling and placement

Two separate decisions. Admission asks whether a workload can safely run; placement asks where. Both are recorded, and both can be replayed.

Admission comes first#

Before anything is created, Nodeau predicts the peak GPU memory a workload will need and compares it with what a card can actually offer. A workload that would not fit is refused, with the arithmetic and with remedies — rather than started and left to be killed.

Terminal
nodeau service explain qwen-local

That prints the decision the controller recorded when it made it. It does not re-run the calculation: if it did, it could disagree with the controller, and you would have two answers with no way to know which one the platform acted on.

The arithmetic#

What the card can offer:

Output
  CUDA-addressable VRAM          15,827 MiB
− what else is already on it      5,950 MiB   your desktop, another program
− safety reserve                    512 MiB
= available                       9,365 MiB

What the workload needs:

Output
  model weights                   4,280 MiB   from the artifact and quantisation
+ KV cache                          512 MiB   context size × parallel sequences
+ runtime overhead                  300 MiB   the engine's own buffers
= predicted peak                  5,092 MiB
+ prediction margin                 256 MiB
+ estimate margin                   768 MiB   ONLY on unmeasured hardware
= required                        6,116 MiB
MarginSizeWhen
Safety reserve512 MiBAlways, per card. What Nodeau keeps back for whatever else is on it
Prediction margin256 MiBAlways. The error bar on the prediction
Estimate margin768 MiBOnly when the configuration has not been measured on hardware like yours
Multi-device allowance128 MiB per deviceOnly for a workload spanning several cards

Estimated and measured#

Where Nodeau has a measurement for this model, this configuration and hardware like yours, it uses the measurement. Where it does not, it computes a figure from the model's architecture and artifact size, adds the 768 MiB estimate margin, and labels the decision estimated.

Terminal
nodeau model info <model>    # which configurations have actually been measured

An empty measurement list is a real answer: it means every decision about that model is computed rather than observed. Each row also states its scope — whether the figure counted the whole device or one process — because the two are different quantities.

Accepting the risk yourself#

Two flags, on nodeau run and nodeau model qualify. Both are explicit, both are per-workload, and both are recorded permanently.

FlagWhat you are accepting
--accept-estimate-riskDrop only the extra margin Nodeau adds for hardware nobody has measured this on. You accept that it may not fit
--spend-safety-reserveLet this workload use the memory Nodeau keeps back for whatever else is on the card. If that GPU also drives your display, an out-of-memory kill takes it too

There is no --force, and admission cannot be bypassed. An unverified artifact, an unentitled device, stale hardware or a busy card are not overridable by either flag. Batch deliberately supports neither.

Nodeau will never spend a margin on your behalf. A qualifier that quietly shrank the margin until a model fit would always succeed and prove nothing.

Ordering#

A capability refusal is decided before the capacity arithmetic, so "this model cannot embed" can never reach you as "insufficient VRAM".

An organisation's governance policy narrows the candidate set before any capacity arithmetic too — so a workload refused by a quota is told it was a quota, in your organisation's own terms, and never as though it did not fit.

Placement#

Among the candidates admission accepted, placement chooses. It reports what it chose and what the alternatives would have cost.

Terminal
nodeau placement explain qwen-local
Output
Selected   nodeforge / NVIDIA GeForce RTX 5060 Ti (GPU-c080d9be-9a0…)
Mode       balanced   (fleet-default)
Work       output tokens

  WHY
    it was already here and still fits — Nodeau does not move a
    running workload for a better score
    predicted 80.8 output tokens/s   confidence observed
    predicted 166 W

  NOT SELECTED
    nodeau-c     NVIDIA GeForce RTX 3080    predicted 114.0/s

  Hardware data 2026-09-hw.3, decided 2026-09-21T06:17:37Z

What it weighs#

  • Which machines and cards are eligible — healthy, reporting fresh telemetry, not drained, not excluded by policy, big enough.
  • Whether the machine already has the model's weights verified locally.
  • A prediction of how the workload will perform there, from observations collected on your own machines.
  • The scheduling mode.
  • Any hard constraints you set on that machine.

Scheduling modes#

Terminal
nodeau scheduling mode                      # show
nodeau scheduling mode balanced             # set for the fleet
nodeau scheduling mode performance --node nodeau-c   # set for one machine
ModeMeans
efficiencyThe most work per unit of energy, never much slower
balancedFastest, while staying near the best efficiency. The default
performanceFastest, whatever it costs
legacyThe pre-Phase-13 tightest-safe-fit scorer

A mode change affects new placements only. Holds and stickiness run before any scorer, so a fleet that changes its mode moves nothing that is running.

Hard constraints#

Constraints are hard: Nodeau refuses to place work rather than exceed one, and no mode can score around them.

Terminal
nodeau scheduling constraints --node nodeforge --power-budget 400
nodeau scheduling constraints --node nodeforge --deny-device GPU-c080d9be-…
nodeau scheduling constraints --node nodeforge --clear
FlagWhat it bounds
--power-budget <W>The most predicted power Nodeau may have running on this machine
--idle-watts <W>What the machine draws with nothing running, so waking it counts as a cost
--max-accelerators <n>The most cards one workload may use here
--deny-device <uuid>Withhold one card from scheduling; it stays visible
--allow-device <uuid>Return a withheld card
--clearRemove every constraint from this machine

What Nodeau will not do#

  • It does not move a running workload. Placement decides once and then holds. A workload on a machine whose telemetry has gone stale is held, not moved, and that hold has no timeout — giving up after N minutes would be automatic failover acquired by accident.
  • It does not fail over, migrate or reschedule. If a card genuinely leaves a machine, Nodeau withdraws the workload that can no longer start and keeps the service, which starts again when a placement is possible. That is not failover.
  • It does not re-split a healthy workload for a better fit.
  • It does not share a card. No time-slicing, no MIG, no preemption, no priority queues.

nodeau restart <name> is how you ask for a workload to be placed again.

Drain#

Terminal
nodeau scheduling drain --node nodeau-c

Nothing running is stopped, moved or disturbed. Nodeau stops choosing that machine for anything new, and says so when it explains a placement. To empty the machine, drain it and then stop what you want gone — nodeau ps shows what is on it.

Terminal
nodeau scheduling undrain --node nodeau-c

Undraining does not bring anything back.

Reason codes#

Every refusal and every scheduling decision carries a machine-readable code and a readable explanation. The same code means the same thing in the CLI, in --json, and in the dashboard.

The model#

CodeMeaningUsually
MODEL_NOT_INSTALLEDThe weights are not on the machine that would run themnodeau model install <id>
MODEL_VERIFICATION_PENDINGPresent; the digest is still being establishedWait — it clears by itself
MODEL_ARTIFACT_INVALIDThe file on disk is not what was pinnedRe-download it
MODEL_UNVERIFIEDPresent, right size, digest not establishednodeau model verify <id>
MODEL_UNSUPPORTEDNo profile for this model, or none for this configuration on this hardwareChange the configuration, or choose another model

The GPU#

CodeMeaningUsually
GPU_TOO_SMALLThe arithmetic says it will not fitSmaller context, or a smaller model
GPU_ALREADY_ALLOCATEDA whole GPU is reserved by another workloadnodeau ps, then wait or stop something
GPU_UNAVAILABLENo healthy GPU was reported at allnodeau doctor
ACCELERATOR_SET_UNSUPPORTEDThe shape of the request cannot be run — not a memory problemAsk for a different set of cards
HARDWARE_STALEA GPU report is too old to be evidence about the card nowCheck the machine is reporting
MACHINE_DRAININGThe machine is deliberately not taking new worknodeau scheduling undrain

The task#

Three codes rather than one, because the three sources of capability truth fail for different reasons and are fixed by different things.

CodeMeaning
TASK_UNKNOWNNot a word Nodeau knows. A typo, or a manifest for a newer Nodeau
MODEL_CAPABILITY_UNSUPPORTEDThese weights cannot do this task
RUNTIME_CAPABILITY_UNSUPPORTEDThis engine cannot drive this task
PLATFORM_CAPABILITY_UNSUPPORTEDThe runtime installed on this machine was not built with it

Being patient, and being gone#

CodeMeaning
WORKLOAD_STARTINGIt is coming up. Not a refusal
QUEUEDEvaluated, correct, waiting for a card to free
WORKLOAD_STOPPEDNodeau has a record and the machine does not have the process. Holds nothing
WORKLOAD_SUPERSEDEDDecided at a placement generation the fleet has moved past

Entitlement#

CodeMeaningRemedy belongs to
FEATURE_NOT_ENTITLEDThe plan does not grant the capabilityA purchase
LIMIT_REACHEDThe capability is granted and a numeric limit is spentA purchase
ENTITLEMENT_INVALIDAn entitlement exists and cannot be acceptednodeau plan refresh

Governance#

CodeMeaningRemedy belongs to
QUOTA_EXCEEDEDYour organisation's own policy, inside what the plan grantsA colleague
POOL_RESTRICTEDA GPU pool or fleet group left no eligible machineA colleague
MODEL_NOT_PERMITTEDAn organisation's model policy disallows this modelA colleague
BATCH_QUOTA_EXHAUSTEDThe organisation's batch allowance is spentA colleague

Batch#

CodeMeaning
BATCH_INPUT_INVALIDThe submitted records are missing, unreadable, or do not match the digest recorded at submission
BATCH_FAILEDAn attempt failed for an infrastructure reason and no attempts remain
BATCH_WORKER_UNAVAILABLEThe worker was placed and its container never started
BATCH_CANCELLEDYou asked for it to stop

Everything else#

CodeMeaning
OKNothing is wrong
INTERNAL_ERRORNodeau itself failed. Every other code above is Nodeau working correctly
UNKNOWNA reason this build has not been taught about. The original text is preserved rather than blanked

Suggested actions#

Alongside the code, every explanation carries a machine-readable suggested action, so the CLI and the dashboard render the same remedy without pattern-matching prose: NONE, WAIT, INSTALL_MODEL, REINSTALL_MODEL, VERIFY_MODEL, CHOOSE_SMALLER_MODEL, REDUCE_CONTEXT, WAIT_OR_STOP_WORKLOAD, CHECK_NODE, UNDRAIN_MACHINE, REVIEW_ENTITLEMENT, REVIEW_QUOTA, REVIEW_POLICY, FIX_INPUT, RUN_DOCTOR, UPDATE_RUNTIME, RUN, CONTACT_SUPPORT.

REVIEW_ENTITLEMENT is deliberately not "upgrade": which plan, and whether to sell you one, is not the scheduler's call.

Documentation for the current published build, the beta channel. Something here wrong or missing? Tell us — a report from a machine we have never seen is the most useful thing we get.