Count anything, per anything, over any window.
Counts, sums, minimums and maximums, distinct values, first and last, percentiles. Per user, account, device, meter or order, over the last few minutes, this month or a whole lifetime. Described as configuration, kept current as every event arrives.
Nine ways to keep a number
Pick what to keep and from which events. The same operations serve every field: a few examples below.
- Count
How many events happened.
SaaSAPI calls per key, this minute - Sum
The total of a value, exact to the last decimal.
EnergyKilowatt-hours per meter, this month - Minimum and maximum
The smallest or the largest value.
BankingLargest transfer per account, last 48 hours - Happened within
Whether something happened at all.
GamingBonus granted to this player in the last 7 days? - Distinct values
How many different values: estimated, or exact up to 10,000.
MediaDifferent titles watched per profile, this week - First and last
The earliest or latest value, or when it happened.
MobilityLast charging station per vehicle, and when - Percentiles
A distribution, read as the percentile you ask for.
Logistics95th percentile delivery time per region - Filters
Count only what matches: an amount, a status, a code.
ManufacturingReadings above 80 °C per machine, last hour
Rolling, calendar, lifetime, and more
One total answers over many windows. Pick one and see which of a shopper's orders it reads, and what it answers.
Orders in the last 7 days
Moves with the clock. Add an offset to compare with the same span earlier, as a baseline.
{"rolling": "7d"}Keep numbers per anything you track
A user, an account, a device, a meter, an order: you name the kinds of things you track, and each one appears the moment an event mentions it. One event updates the numbers of everything it names.
- Variants of one id count as one: emails, IP addresses, phone numbers
- Attributes hold what events don't carry: a plan, a credit limit, a time zone
- Combinations as keys: this user on this device, this card at this shop
- Up to 16 things per event, all updated at once
- User
- Account
- Device
- Card
- Meter
- Vehicle
- Player
- API key
- IP address
- Order
" Alice@Example.COM "emailalice@example.com::ffff:203.0.113.7ip203.0.113.7+49 30 1234567phone+49301234567
userdeviceSign-ins of this user on this device14One event counts for the user, their team and their company
Link what belongs together, and a total rolls up the chain as each event arrives. A question about a user can read their company's number too.
- Roll-ups up to 3 levels: user, team, company; device, site, region
- Every level on the way is updated, not only the top
- Counted where it happened: someone who changes teams takes only future events along
- No link, no guess: the value is reported as missing, never as 0
Same idea:device → site → regionstore → city → country
Exact to the cent. A USD order never inflates a EUR total.
Amounts are kept as exact decimals, never as floating point, and come back as strings like "559.90". Money totals know their currency.
- A scale per currency: no decimals for JPY, 2 for EUR, 3 for BHD
- Amounts with too many decimals are refused, or rounded half to even if you choose
- One currency per total, or one total per currency, picked when you ask
- Totals converted at the rates you keep; a missing rate is reported, never guessed
- 19.90 EURCounted
- 25.00 USDOther currency: not in this total
- 540.00 EURCounted
- 12.345 EURToo many decimals: refused
"559.90"- JPY
decimal(0)1250 - EUR
decimal(2)19.90 - BHD
decimal(3)4.125
The last 15 minutes and the last 12 months, from one definition
A total can keep up to three resolutions at once. Every event updates each of them, and every question reads the one that fits its window, so short and long windows both stay lean.
- Up to 3 resolutions per total, finest first
- Kept for up to 400 days
- Every window is checked against its total, with a memory estimate, before anything goes live
- Last 15 minutesreads 1-minute buckets
- Last 30 daysreads 1-hour buckets
- Last 12 monthsreads 1-day buckets
- 1-minute bucketskept 2 hours
- 1-hour bucketskept 70 days
- 1-day bucketskept 400 days
A total and a metric, as JSON or in a guided form
Define what to keep once, then ask about it over any window. Every definition is versioned: validate it, fill it with history and roll it out without a deploy.
{
"name": "spend_by_customer",
"description": "Order amounts per customer, EUR only",
"spec": {
"on": "order_placed",
"key": ["customer"],
"op": "sum",
"value": "attrs.amount",
"valueType": "decimal(2)",
"money": true,
"currency": { "only": "EUR" },
"tiers": [
{ "resolution": "1m", "retention": "2h" },
{ "resolution": "1h", "retention": "70d" },
{ "resolution": "24h", "retention": "400d" }
],
"lifetime": true
}
}{
"name": "spend_this_month",
"description": "This month's spend, in the customer's own time zone",
"spec": {
"state": "spend_by_customer",
"window": {
"calendar": "month",
"tz": "subject.timezone",
"defaultTz": "UTC"
}
}
}{
"name": "api_calls",
"description": "API calls per user, rolled up to team and company",
"spec": {
"on": "api_call",
"key": ["user"],
"op": "count",
"resolution": "1m",
"retention": "24h",
"rollup": ["in_team.part_of"]
}
}Key bounds
What a total, a window and an event can hold. Fixed by the engine, the same for every workspace.
| Rolling windows | 15 to 1,440 bucketsAt 1-minute buckets: 15 minutes to 24 hours |
|---|---|
| Calendar windows | Day, week, month or yearUp to 12 periods back, up to 31 at once, any time zone |
| Retention | Up to 400 days per total |
| Resolutions per total | Up to 3Up to 10,080 buckets each |
| Things per event | Up to 16 |
| Kinds of things in one key | Up to 3 |
| Roll-ups and paths | Up to 3 levelsFan-out up to 100, up to 256 things reached per event |
| Exact distinct values | Up to 10,000 per setDefault 1,000; otherwise estimated |
| Decimal scale | 0 to 9 decimals |
| Percentile bins | Up to 15 bounds |
| Events per batch | Up to 500 |
Put a live number on anything
Request access and tell us what you want to count.