Metering
View SourceRecording usage
AuroraMeter.track(tenant, :ai_generations) # +1
AuroraMeter.track(tenant, :ai_generations, 5) # +5track/4 runs on the ETS hot path — no database round-trip. It increments an
in-memory counter keyed by {tenant, feature, period} and marks it dirty for the
flusher. Aggregate throughput is millions of increments/second because load
spreads across many counter keys.
Reading usage
AuroraMeter.usage(tenant, :ai_generations) # current-period integer
AuroraMeter.usage_all(tenant) # %{feature => value}A cold counter is seeded once from the last flushed database value, so reads are always correct even after a restart.
Periods
Usage is bucketed by billing period. The free core uses the calendar month (UTC); a new period starts a fresh counter automatically (no reset job). With the Pro package, periods align to the tenant's subscription.
Durability
By default metering is buffered: counters live in ETS and are flushed to
Postgres every :flush_interval ms, so a hard crash can lose at most one interval
of increments — fine for dashboards and soft quotas. For billing-grade exactness,
mark a feature durable and track/4 also writes a raw event row synchronously:
config :aurora_meter, durable_features: [:ai_generations]
# or per call:
AuroraMeter.track(tenant, :ai_generations, 1, durable: true, metadata: %{req: id})