Skip to main content
A platform asks one question no single tenant can answer: across all my tenants, which are turning? Each tenant is a namespace Vainona keeps apart on purpose, so nothing reads across them. A tenant summary is the one way up: a template publishes a tenant document per namespace under it, into the template’s own namespace, built from that tenant’s groups and banded. Your platform then defines ordinary judgments, queries and subscriptions over the tenant documents. Only bands cross the boundary. A judgment over tenant documents reads no tenant’s text, only the labels each tenant published. It is the one relation that crosses namespaces, and only upward.

Set one up

Say every tenant under acme/prod/* has a template group abuse_by_day, keyed by a day bucket you write, and by_plan. Choose the groups each tenant publishes, and a band for each aggregate you want to judge by:
Every group must exist on the template, and every key of bands names one of their aggregates as <group>.<aggregate>, as a group’s rows key them. A value takes the label of how many cut points are at or below it, so each band has one more label than cut points. Templates need the Team plan or above.

The tenant document

Once an hour a run reads each tenant’s merged group rows and writes its document into the template’s namespace, here acme/prod:
  • id is the tenant’s namespace name, and attributes.kind is tenant.
  • state.groups holds the labels of the aggregates you banded. An aggregate without a band appears only in state.source.values.
  • state.source says where the labels came from: the values, the storage merge they are exact at (as_of), the tenant’s incarnation (life) and the run that wrote them (lease).
A run writes a tenant’s document only when its labels moved, so a quiet tenant costs nothing to keep current. A tenant with none of the groups merged yet has no document.

Judge your tenants

A tenant document is an ordinary document, so a judgment reads it like any other:
It is judged when a tenant’s labels move, queried like any judgment, and a subscription on it tells you when a tenant turns. Its audit stops at the tenant document, whose state.source carries the values it was built from.

How current it is

GET lists each tenant by name with its status:
A group is exact as of its tenant’s last storage merge, at most about an hour behind its writes, and the run reads it once an hour and pages through your tenants. So a tenant document lags its tenant by up to a run plus the paging, not one hour: read published_at and source_as_of rather than assuming.

Changing it

  • Groups and bands change with PATCH, each replacing the setting whole. The next run rewrites every tenant document whose labels move, which re-judges each of them, so a PATCH without "confirm": true changes nothing and returns what that costs: one line per judgment on the template’s namespace that reads tenant documents. Send it again with "confirm": true and it applies from the next run, unattended.
  • Delete with DELETE. Runs stop; the tenant documents stay, as ordinary documents.

Tenants that come and go

  • A tenant created under the template gets its document at the first run after its groups first merge.
  • A tenant deleted and created again under the same name has its document deleted and written anew, so the history of anything judging it splits at the new incarnation, as it does for the tenant itself.
  • A tenant document is deleted only once a strong read says the tenant’s namespace is deleted, never because a listing missed it.

Billing and failures

Tenant documents are written like any write to the template’s namespace: they bill your organization as writes and stored bytes, and judgments over them bill as any judgment does. An idle tenant writes nothing. If the template’s namespace refuses the writes, for example because it is over its budget with on_exceeded: reject, the tenant summary shows the warning tenant_summary_failed and the events feed carries one namespace.tenant_summary_failed for the run, with the reason. Nothing is lost: the next run that can write catches every tenant up and clears the warning.