Designing your meters & events

What you can price, report on, and change later depends on the usage events you send. This page covers how to design them: work backward from what you need, work forward from what you have, and maximize your flexibility.

Solvimon’s metering system can handle around 1 million transactions per second - suited for the most demanding workflows.


Why this matters

Pricing plans can be reconfigured in minutes; the shape of the usage data feeding them cannot. Getting the split right up front, raw facts in events and billing logic in meters and plans, is the highest-leverage design decision in a Solvimon integration.

Events carry facts, meters carry logic

A usage event is a record of something that happened in your product: an API call, a completed job, a seat added. A meter defines how those events are filtered and aggregated into a billable quantity.

Keep the billing logic out of your events. If you pre-aggregate (“total API calls this month: 41,203”), every pricing change, whether new tiers, new dimensions, or per-region pricing, needs an engineering change on your side. If you send one event per action, pricing changes are configuration in Solvimon.

Start from what you need

Start from the invoice you want to produce and derive the minimum event that supports it. Suppose you charge for API calls. The billable number is “count of api_calls events, per customer, per billing period”, so the minimum event is:

One event per action, with dimensions as properties
1{
2 "meter_reference": "api_calls",
3 "customer_reference": "cust_8271",
4 "timestamp": "2026-07-01T10:50:00+02:00",
5 "reference": "evt_01J8ZQ3FJ2",
6 "meter_properties": [
7 { "reference": "endpoint_group", "value": "search" },
8 { "reference": "region", "value": "EU" }
9 ],
10 "meter_values": [
11 { "reference": "call_count", "number": "1" }
12 ]
13}

The exact pricing doesn’t need to be settled just yet as prices, tiers, and commitments are plan configuration and can be applied or adjusted later, as long as the metric exists.

Invoicing is also not the only consumer: the same events power usage alerts and cost dashboards, so factor those requirements in too.

Two decisions should be derived from your needs:

  1. Choose the billable actions. One meter per action (api_calls, gb_processed, seats, megapixels_generated), not per their price point. For example, “Premium API calls” is a property on api_calls and not a separate meter.
  2. Pick the aggregation. A meter value plus a calculation method makes a usage metric. Is the billable number a count of events (API calls), a sum of a value (GB processed, tokens), or a max/last of a level (seats, storage)? Levels deserve care: for seats, send the current seat count as a gauge (aggregated with max or last) rather than +1/−1 deltas, which corrupt the total if one event is lost.

Work forward from what you already have built

The usage is recorded in your system today usually decides when and where you send events.

  • If you have a central event stream or log pipeline, send one event per action as it happens. This is the best case: maximum granularity and best visibility.
  • If usage only exists as periodic summaries (per node, per data source), send those summaries over the shortest window you can tolerate, for example per hour per customer, never per billing period. Keep any aggregation on your side a pure rollup of raw facts; pricing logic stays in Solvimon.
  • Send events from the place that can resolve the customer. If edge systems don’t know your customer IDs, aggregate centrally where the lookup is possible rather than sending events without a reliable customer_reference.

Always consider these best-practices:

  • Make references idempotent. The event reference is your idempotency key: the first event with a given reference is processed, any later event with the same reference is flagged DUPLICATE and ignored. Derive it deterministically from the action in your system (for example your transaction GUID) so retries are safe. See event ingestion best practices.
  • Timestamp when usage happened, not when you sent it. The timestamp places the usage in the right billing period, including backfills.

Maximize your flexibility for the future

Requirements frequently change in pricing and packaging. Since you can’t anticipate all of it, you can make sure the data is already there when it arrives.

We recommend sending more events than you need today. Anything that might affect the price of the same action, or that anyone might want to slice usage by, belongs in meter_properties: region, endpoint group, model, plan tier. An unused property costs nothing; a missing one costs an engineering change and leaves you with no history for events already sent. With the property in place, a new requirement like per-region pricing is a pricing rule conditioning on region, not a code change.

Two constraints on properties that you should take into account:

  • Use a small, stable set of values. Don’t send unbounded values (raw URLs, user IDs) as properties. Use something like a country ISO code.
  • Properties used in pricing conditions must be configured as required on the meter.

Send usage as granularly as you can. Aggregation is the meter’s job; granular events keep every future pricing model open.

You don’t have to define everything up front

Solvimon supports dynamic meter creation: pass meter_validation=DYNAMIC on the ingest call and missing meters, values, and properties are created on the fly from the events themselves. This lets you start sending rich events immediately and let the meter configuration follow, which is useful while your usage model is still evolving.

Common mistakes to avoid with meters

MistakeCost
Pre-aggregated events per billing periodEvery pricing change needs engineering; no real-time cost visibility
One meter per price point instead of propertiesMeter sprawl; can’t restructure tiers without new meters
Random or timestamp-based event referencesRetries create duplicates that bill twice
Seat changes as +1/−1 deltasOne lost event corrupts the seat count for the whole period
Optional properties used in pricing rulesEvents price incorrectly or fail to match

Where to go next