Skip to main content
Nothing is computed continuously. An answer is computed when its policy says so and not again until the document changes. A document that sits untouched for a year costs storage only. The cost driver is changes per month, not rows, and the policy decides which changes you pay for.

Pick by how the answer is read

  • on_change is the policy to filter or rank on, because every document’s answer stays current. It is also the most expensive: every change to every document is judged. You can filter or rank on periodic and manual answers too, as they are stored, but not on on_read ones, which exist only once something reads them.
  • on_read is the default. The answer is computed the first time a get or query includes it, then cached until the document changes. Cold namespaces with on_read judgments cost nothing until someone looks. The first read returns pending, unless it passes wait_ms.
  • periodic recomputes every document whose answer is older than the interval. Over a large namespace that is a recurring backfill, billed as one. The namespace’s stats show its projected monthly cost.
  • manual answers change only when you run a backfill.

Switching to on_change

The policy is a setting, so changing it creates no new version:
Switching to on_change needs an answer for every document. Without confirm=True the call changes nothing and returns a backfill estimate for the documents that have no current answer, with its cost and duration. Call it again with confirm=True to switch and start the backfill. For a judgment that reads related documents, the estimate also carries replay: what it would cost a month from then on, replayed from your last 30 days of writes. Creating such a judgment with on_change returns the same replay estimate and creates nothing until you pass confirm=True. See the replay estimate, and what “at least” means there.

Chatty documents: debounce

Any policy can set debounce_ms. A document that changed more recently than that is not judged until it settles, and then only its newest revision is judged. For live conversations, 2,000 ms turns a burst of 50 messages into one evaluation, about two seconds after the burst ends.
Rapid writes are coalesced anyway: the engine only ever sees the newest revision at the time it judges. Debounce adds a deliberate wait on top.

Documents that never settle: the ceiling

A debounce never ends for a document that changes more often than the debounce: an account whose tickets arrive every few minutes, or a conversation that never pauses. max_wait_ms is the ceiling. Such a document is judged once it has been quiet for debounce_ms, or once max_wait_ms has passed since its oldest unjudged change, whichever comes first.
With a 10-minute debounce and a 1-hour ceiling, a burst of 100 writes in 5 minutes costs one evaluation, and a document written every minute for 3 hours costs 3.
  • Defaults. For a judgment with related documents and a debounce_ms above 0, the ceiling defaults to 12 × debounce_ms; with no debounce there is nothing to wait for, so there is no ceiling. For any other judgment it defaults to none, so a debounce behaves as it always has. GET returns the value in effect.
  • Bounds. It must be at least debounce_ms. null means no ceiling.
  • A setting. Like the debounce, changing it creates no version. A lower ceiling means fresher answers and more evaluations.
For a judgment with related documents, “changes” includes writes to the documents that point at the judged one, so the ceiling is what keeps a busy account’s answer from lagging for ever. Its answer lags by the debounce, typically minutes, and at most by the ceiling.

Fan-out: when a referenced document changes

A judgment can read the one document each judged document points at: its referenced document. A change to what the relation shows of it re-judges every judged document that points at it and is inside the re-judge scope. That is a fan-out, and freshness.fanout decides which judged documents it re-judges and when. A change to a blocking relation’s block fans out the same way, to the documents in the block. Like the rest of freshness, these are settings: a PATCH changes the keys it sends, merges scope per key, and creates no version.
  • The scope counts from the change, not from now, so one change’s scope stays fixed however long its fan-out waits. A judged document outside it is not re-judged: its answer reads stale, with stale_reason referenced_changed, so answers: "fresh_only" leaves it out. Its watermark says which version of the referenced document it read, and its next own write re-judges it.
  • Only a change to what the relation shows counts. An edit to a field it leaves out, or a move inside a band, neither fans out nor starts the debounce.
  • The fan-out debounce is its own. The judgment’s debounce_ms and max_wait_ms still govern the judged documents’ own writes, so a new judged document is judged within seconds.
  • Only on_change fans out. Under the other policies a change makes the in-scope answers stale.
  • The namespace sets share, the most of its in-flight engine requests fan-out may use (half by default). See namespaces.
In-scope answers are pending from the change until they are re-judged. While a fan-out is deferred past the rolling limit they read stale, with stale_reason limit_reached, and the events feed records judgment.limit_reached. A deferred fan-out runs whole, never in part, once the window has room for all of it or a PATCH raises rolling_limit, with no confirm; one larger than the whole limit stays deferred until you raise the limit above it or set it to null. No event marks the catch-up: each answer reads stale (limit_reached) until it is re-judged, then fresh. Judge a document with the document it points at works through what each setting saves.

Budgets

A namespace budget caps judgment compute per billing period. Each request to the engine is priced before it is sent, and when the next one would not fit what is left, evaluation pauses rather than overspending, and your organization’s owners and admins get an email. Changed documents read stale, and documents never judged read unavailable. A large write is judged up to the last document that fits, and the rest waits until you raise the budget or the next billing period starts. Writes continue, unless the budget says "on_exceeded": "reject". Every backfill is checked against the remaining budget before it starts. See namespaces.