AdministrationUsage metering

Usage metering

Neens records what every tenant is doing, feature by feature, as durable integer counters. This powers a per-workspace Usage view for admins.

Counters are integer aggregates only — a usage row is (company, project, feature, day, connection, count). No trace, prompt, or response content is ever stored or transmitted by metering. That invariant is what lets the aggregates roll up for billing and fleet operations while every byte of content stays inside the tenant.

At a glance

Where (tenant)Usage in the left nav — per-agent, per-feature counts and trends
Where (operator)Usage in the operator console — the same counts, fleet-wide
Who can use itAny workspace member sees their workspace’s usage; the operator sees every tenant
Key API routesGET /usage, GET /usage/summary; operator: GET /admin/usage, GET /admin/usage/companies
What’s storedInteger counts per (company, project, feature, day, connection) — never content
Rolls upNightly into the cross-tenant rollup table

Metering is on by default and needs no configuration. The full tenant and operator Usage views work with nothing to set up.

What’s metered

Every metered feature belongs to one category. Ingestion and LLM counters are recorded on the hot path as traces arrive and models are called; compute, curation, and storage counters are recorded when the corresponding job runs or artifact is created.

CategoryFeatures
IngestionTraces, sessions, spans, and tool calls ingested
LLMLLM calls, input tokens, output tokens, and spend — sliced per connection
ComputeClustering runs, issue-classification jobs, eval runs, eval targets scored, pre-prod eval runs, enrichment runs, scenario generations, remediations generated, playground runs, chat messages, MCP calls
CurationAnnotations, judges, datasets, dashboards, prompt versions, and scores created
StorageStorage used (a point-in-time level, not a running total)

Spend is stored as integer micro-dollars (1 USD = 1,000,000) so it stays an integer aggregate like every other counter and can roll up and cross the operator boundary without ever becoming a floating-point or free-text field. The Usage view renders it back as dollars.

Most counters accumulate — each event adds to that day’s running total. Storage used is the exception: it’s a level metric, so each reading overwrites the day’s value (the latest reading is the truth, not the sum).

Tenant usage view

An admin (or any member) opens Usage to see their workspace’s activity. Behind it:

  • GET /usage returns per-feature (or per-day, per-agent, per-connection) integer totals for a time window, scoped to the caller’s workspace.
  • GET /usage/summary returns the per-feature totals plus a daily timeseries for the headline features (traces ingested, LLM calls, LLM spend).

The window defaults to the last 30 days; pass since/until (YYYY-MM-DD) to change it. Because the store is scoped by tenant, one workspace can never see another’s counters.

Operator fleet view

An operator opens Usage in the operator console to see the same counts across every tenant — the usage-based cost basis for the fleet.

  • GET /admin/usage reads the cross-tenant rollup, grouped by company, feature, day, or project (operator-gated; an agent key is always denied).
  • GET /admin/usage/companies lists per-company totals with each company’s name, tier, and status.

The operator view reads the rollup table, which the nightly job keeps in sync (below) — so it’s fast and doesn’t fan out live queries across every tenant schema.

How it works

Counters are recorded locally

As traces are ingested, LLM calls run, jobs execute, and artifacts are created, Neens increments the matching counter in a durable per-tenant table. Recording is best-effort and never blocks or breaks the operation it’s counting.

The nightly rollup folds tenants into the operator view

Once a day, a leader-elected job reads each tenant’s counters and upserts them into the operator’s cross-tenant rollup table. The upsert is idempotent — re-running the same day’s rollup overwrites the same rows, so it never double-counts. This is what the operator fleet view reads.

The rollup runs under leader election, so a scaled deployment with several app replicas elects exactly one replica to run it — you never get N× rollups.

Troubleshooting

SymptomCauseFix
Operator Usage view lags the tenant viewThe rollup runs nightlyWait for the next nightly rollup, or re-check after it fires
Usage view is empty on a brand-new workspaceNo activity has been metered yetIngest traces / run evals; counters accrue as you use the product

See also: Cost & model pricing (the per-model prices behind every dollar figure — a separate signal from these feature counters) and Data retention and Erasure.