Pick by how the answer is read
on_changeis 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 onperiodicandmanualanswers too, as they are stored, but not onon_readones, which exist only once something reads them.on_readis the default. The answer is computed the first time a get or query includes it, then cached until the document changes. Cold namespaces withon_readjudgments cost nothing until someone looks. The first read returnspending, unless it passeswait_ms.periodicrecomputes 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.manualanswers change only when you run a backfill.
Switching to on_change
The policy is a setting, so changing it creates no new version:
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 setdebounce_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.
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.
- Defaults. For a judgment with related documents and a
debounce_msabove 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.GETreturns the value in effect. - Bounds. It must be at least
debounce_ms.nullmeans no ceiling. - A setting. Like the debounce, changing it creates no version. A lower ceiling means fresher answers and more evaluations.
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, andfreshness.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, withstale_reasonreferenced_changed, soanswers: "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_msandmax_wait_msstill govern the judged documents’ own writes, so a new judged document is judged within seconds. - Only
on_changefans out. Under the other policies a change makes the in-scope answersstale. - The namespace sets
share, the most of its in-flight engine requests fan-out may use (half by default). See namespaces.
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 readstale, 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.