> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nextmoca.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Adaptive budget

> Let the engine escalate its own budget along a ladder you define, instead of guessing a single number per request.

Most callers do not know the right budget for a given request. A retrieval that
usually needs 2,000 tokens occasionally needs 8,000, and picking one number
means either overspending on the common case or under-serving the hard one.

**Adaptive mode** solves that from the other direction: you define a ladder, and
the engine climbs it only as far as it has to.

```json theme={null}
"budget": {
  "max_context_tokens": 8000,
  "operating_point": "np-2026-07-r2",
  "mode": "adaptive",
  "adaptive": {
    "initial_tokens": 2000,
    "escalation_tokens": [4000, 8000],
    "allow_full_context_fallback": true
  }
}
```

Selection is attempted at 2,000 tokens. If that selection is judged
insufficient, it escalates to 4,000, then 8,000, and — if
`allow_full_context_fallback` is on — finally to passing your context through
intact. The response tells you exactly how far it went:

```json theme={null}
"budget_tokens": 4000,
"attempted_budget_tokens": [2000, 4000]
```

<Note>
  This is per-request, and it is decided by the engine on the evidence in the
  request. It is not a per-tenant setting, and there is nothing to configure ahead
  of time.
</Note>

## When to use it

<CardGroup cols={2}>
  <Card title="Use adaptive" icon="stairs">
    Heterogeneous requests where difficulty varies — a support queue, a document
    Q\&A surface, an agent loop whose turns differ wildly in how much state they
    need. The common case gets the small budget; the hard case gets what it needs.
  </Card>

  <Card title="Use fixed" icon="ruler-horizontal">
    A hard downstream constraint you must not exceed, or a uniform workload where
    you already know the right number. Fixed does one selection pass, so it is the
    cheaper and more predictable of the two.
  </Card>
</CardGroup>

## The fields

| Field                         | Meaning                                                                   |
| ----------------------------- | ------------------------------------------------------------------------- |
| `initial_tokens`              | The first rung. Selection is attempted here first.                        |
| `escalation_tokens[]`         | Further rungs, ascending. Climbed one at a time, only as needed.          |
| `allow_full_context_fallback` | Whether the ladder may end in passing everything through. Default `true`. |

`max_context_tokens` still applies as the outer bound. Set your top rung at or
below it — a rung above it buys nothing.

<Warning>
  `mode: "adaptive"` **with a null or missing `adaptive` object silently runs as a
  fixed-budget request.** It is not an error. If adaptive behaviour matters to
  you, assert on `attempted_budget_tokens` in your integration tests: a fixed-path
  response leaves it empty.
</Warning>

### `allow_full_context_fallback`

Leave it `true` unless you have a **hard** downstream cap that full context
would blow — a model window you cannot exceed, or a contractual token limit.

With it `false`, a request that cannot be satisfied within the ladder returns
the best selection found rather than everything. That is the right behaviour for
a hard cap and the wrong behaviour for an ordinary quality-sensitive path, where
"send everything" is a better answer than "send an under-budget subset".

## What it costs

**Each rung attempted is a full selection pass.** A workload that always
escalates to the top rung does several times the work of one that succeeds on
the first.

That will not cost you more: the meter counts the input you submitted, once,
regardless of how many rungs were climbed (metering is not live yet, and this is
how it is defined). What it does cost you is **latency**, which is the reason to
watch it.

Watch `attempted_budget_tokens` in production:

* Mostly `[2000]` — your first rung is well chosen.
* Mostly `[2000, 4000, 8000]` — your first rung is too small. Raise it. You are
  paying three passes of latency to arrive somewhere you could have started.
* Ladder is never climbed at all — you may not need adaptive mode.

A reasonable starting shape is a first rung near the median of what your
workload actually needs, one or two escalations, and a top rung at your real
downstream limit. Three rungs is usually enough; ten is a latency budget spent
on ceremony.

<Warning>
  **Raising a rung is a latency and fit decision, not a quality one.** Selections
  at different rungs are different computations, and a higher rung is not
  guaranteed to produce a superset — or a better set — than a lower one. Size the
  ladder from what your downstream call can accept and from how often you are
  escalating. Do not sweep the rungs looking for a quality optimum, and do not
  expose them to an end user as a quality control.
</Warning>

## Reading the result

| Field                       | Read it as                                                                                                            |
| --------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `budget_tokens`             | The budget the returned selection was actually produced under.                                                        |
| `attempted_budget_tokens[]` | Every rung tried, in order. Empty on the fixed path.                                                                  |
| `fallback_used`             | The ladder ended in pass-through, or the engine stood down. See [reading a stand-down](/errors#reading-a-stand-down). |
| `safety`                    | Present when a coverage verdict ran. `null` means no verdict was computed — never "the verdict was fine".             |

## Coverage checking

Adaptive mode pairs naturally with `budget.require_evidence_coverage`. With it
set, the engine runs its coverage check and prefers standing down to full
context over returning a selection that does not cover the task's evidence. The
verdict is summarised in `safety`.

```json theme={null}
"budget": {
  "max_context_tokens": 8000,
  "operating_point": "np-2026-07-r2",
  "mode": "adaptive",
  "adaptive": { "initial_tokens": 2000, "escalation_tokens": [4000, 8000] },
  "require_evidence_coverage": true
}
```

Use it where a missing piece of evidence produces a confidently wrong answer
rather than an obviously incomplete one — regulated answers, citations,
anything a human will act on without re-checking.
