Skip to main content
Vainona is built on object storage and decision models. That design has costs you should know before you build on it.
The latency and freshness numbers on this page are targets. We measure them continuously and will publish the measurements here.
  • Writes take roughly 80 to 150 ms, because each batch is committed to object storage before it is acknowledged. It is not a replacement for your transactional database. If writes of that speed are too slow for your use case, Vainona is not the right fit for it.
  • Answers lag writes by seconds while the engine is healthy. Freshness is always visible.
  • A document can end failed until it is written again: when it fails for a reason of its own (the engine refuses it or cannot process it), or when it is still failing 24 hours after it last changed. Failures of the engine as a whole are retried, not given up on.
  • Cold queries take hundreds of milliseconds after a node change or cache eviction. On a 1M-document namespace the warm p90 target is under 10 ms for eventual reads, and the cold p90 target is under 500 ms. strong reads (the default) always add two storage round trips to see the newest writes, so their warm number is higher; we publish it once measured. Pinning keeps a namespace warm, at a price.
  • Freshness lag for on_change judgments targets under 5 s at p90 with a healthy engine.
  • Answers that read related documents lag them by the debounce, typically minutes, and by at most the ceiling (max_wait_ms). That is the price of judging an account once per burst of tickets rather than once per ticket. A question about a single event, such as a fraudulent payment, stays a judgment of that document.
  • The cost of a judgment with related documents follows how often they change. Creating one shows the monthly cost, replayed from your last 30 days of writes, before you confirm.
  • A judgment that reads the document each judged document points at re-judges, on each change to that document, every judged document in its re-judge scope. That is the fan-out, and it costs changes × documents in scope. So only a change to what the relation shows counts, bands hide moves inside a band, the scope defaults to documents created in the last 30 days, and a burst of changes is debounced to one fan-out. Changes that never settle still fan out at least once per ceiling, an hour by default, for as long as they keep coming. A fan-out above 10,000 documents waits for you to confirm its estimate. The replay estimate cannot count fan-out and says so. Every one of these defaults is yours to change.
  • A fan-out runs behind ordinary judging, on at most half of your namespace’s engine requests, so a large one takes hours; its job shows how long. Answers outside the re-judge scope keep the version of the referenced document they read, and their watermark says which.
  • Probabilities are the engine’s. They are not calibrated to your outcomes until you give us outcomes. We label the difference. From 100 outcomes, answers carry a calibrated object beside the raw fields, fitted per judgment version and engine epoch and refitted nightly.
  • Composite judgments need at least 50 of your labels before they can answer, and cost one judgment per part. Suggested sub-questions come from a general-purpose LLM that sees up to 30 of your labelled examples; it is off unless you turn it on.
  • Jev’s answers vary from call to call. We asked Jev the same questions about the same text 20 times: a probability’s standard deviation was up to about 0.031, and the widest gap between its lowest and highest value was about 0.12. So a document whose probability is within about 0.06 of a threshold can land on either side of it each time it is judged, and within about 0.03 it often will. That includes a re-judgment after a change that has nothing to do with the question. For documents that close, treat the threshold as a band rather than a line. An unchanged context is never re-judged, so a stored answer never changes on its own, with three exceptions: a periodic judgment re-judges every document on its interval whether or not it changed; a composite’s combined p moves when its combiner is refitted overnight; and a calibrated value moves when calibration is refitted overnight, while the raw numbers beside it stay as they were.
  • The engines cannot abstain. We inject an escape option on choices and expose it. For bool judgments, a probability near 0.5 is the only signal.
  • No ad hoc questions. Define the judgment, then query it.
  • Large backfills can take days. Every backfill estimate shows the duration before you confirm.
  • Laya, when it ships, takes at most 512 tokens. A longer context on a Laya judgment is cut to 512 tokens, with context_truncated: true on the evaluation; it is never sent to Jev instead. Long text needs a Jev judgment. Jev current has no versions for us to retire: it follows whatever model its provider serves, and each change we detect in its behaviour starts a new epoch, recorded in every answer’s engine_version. A judgment on any engine version that is retired fails with engine_version_unavailable, and we never re-pin silently.
  • Your system of record stays yours. You keep documents in sync through the write API. CDC connectors come later.

Consistency, stated separately

There are two consistency models, one for documents and one for answers.
  • Documents: strong. After a write acks, a strong query sees the new revision and its attributes, even before the write is folded into the namespace’s segments. Eventual queries may lag up to 60 seconds.
  • Answers: eventually judged, with explicit freshness. After a write acks, the answer for that revision arrives seconds later while the engine is healthy. Until then the answer carries freshness: pending or stale and the revision it was computed against. Queries can ask for answers: "fresh_only" to exclude pending documents. A write can pass wait_for: ["needs_escalation"] to block until the answer for a revision at or after its own exists.