Billable Metrics
Measure and track user usage and consumption.
Billable metrics operate on a per-buyer basis and provide the foundational data for billing.
Instead of reflecting the resultant charge (e.g., $0.10 for 10 API calls at $0.01 each), they count or aggregate usage units (e.g., 10 API calls).
Definition
A billable metric is defined by the following properties:
- ID: Unique identifier for the billable metric. If omitted, the system generates one.
- Name: The display name of the billable metric.
- Description: A description for reference.
- Filter Groups: Criteria for determining which events should contribute to the metric.
- Aggregation Type: Defines how the selected events are aggregated.
- Property Unique On: Used for distinct counts when the aggregation type is UNIQUE COUNT.
Filter Groups
Filter groups allow users to specify which events affect the metric. Each filter group consists of one or more filters. The filters are combined using the logical OR operator, and the filter groups are combined using the logical AND operator.
Filters are based on the properties of the event. The following filters are supported:
- For string properties:
is
,not is
,contains
,not contains
,exists
,not exists
. - For numeric properties:
greater than
,greater than equal
,less than
,less than equal
,equal
,not equal
.
Aggregation Types
Aggregation types define how consumption is measured.
Aggregation Type | Description | Example |
---|---|---|
COUNT | Count the numbers of events matching filter groups. | COUNT(meteringUsageRecordGroup.metaInfo.billableRecords[index].key) WHERE filters |
UNIQUE COUNT | Count distinct values of a specified property. | COUNT_DISTINCT(meteringUsageRecordGroup.metaInfo.billableRecords[index].properties[propertyUniqueOn ]) WHERE filters |
SUM | Sum the values of a specified property. | SUM(meteringUsageRecordGroup.metaInfo.billableRecords[index].quantity) WHERE filters |
MAX | Retrieve the maximum value of a property. | MAX(meteringUsageRecordGroup.metaInfo.billableRecords[index].quantity) WHERE filters |
LATEST | Retrieve the most recent value of a property. | LAST_VALUE(meteringUsageRecordGroup.metaInfo.billableRecords[index].quantity) WHERE filters |
UNIQUE COUNT
For unique count metrics, the property to count must be specified via propertyUniqueOn
when create. The distinct counting process involves three levels of aggregation.
Calculation Logic:
- In hourly report aggregation, we only save the new added property values.
- Aggregate the target property values of all record groups in this hour.
- Read all target property values of the previous hours today from db.
- Remove data from current hourly result that already exist in the previous hours results.
-
In daily report aggregation, we just need to concat the result of 24 hourly reports, because each of them only keep the new values. We only keep the distinct count of values in the daily report, not the raw values array.
-
In usage invoice generate, we aggregate all hourly reports data.
- Read all hourly reports in the invoice period.
- Aggregate hourly reports to daily reports. In this step, we just need to concat values of all hourly reports. We keep the concated array in memeory temporarily for daily reports aggregation.
- Aggregate daily reports. In this step, we merge values of all daily reports to get the final distinct count. After get the final count, delete the source array kept in daily reports to forbid they are saved to the db.
- Calculate fee by the final count.
E2E Testing Plan
- Count metric with filters.
ID: api_call
Name: API Call
Description: Count the number of API calls.
Filter Groups:
- Filters:
- Property: api
Operator: is
Value: /api/v1
Aggregation Type: COUNT
- Unique count metric with filters.
ID: api_call_by_cluster
Name: API Call by Cluster
Description: Count the number of unique API calls by cluster.
Filter Groups:
- Filters:
- Property: api
Operator: is
Value: /api/v1
Aggregation Type: UNIQUE COUNT
- Sum metric with filters.
ID: network_traffic
Name: Network Traffic
Description: Sum the network traffic.
Filter Groups:
- Filters:
- Property: region
Operator: is
Value: east
- Property: protocol
Operator: is
Value: tcp
Aggregation Type: SUM
- Max metric without filters.
ID: cpu_usage
Name: CPU Usage
Description: Get the maximum CPU usage.
Filter Groups: []
Aggregation Type: MAX
- Latest metric with filters.
ID: <empty>
Name: <empty>
Description: <empty>
Filter Groups:
- Filters:
- Property: region
Operator: is
Value: east
Aggregation Type: LATEST
Billable Dimension
Price Model
Basic pricing
In a basic price model, each unit of a product or service is assigned a fixed cost.
For example, consider a company offering cloud storage services at a rate of $0.5 per gigabyte (GB).
In this scenario, the unit amount
is set to $0.5, indicating that each GB costs $0.5.
For 10 units, 10 x 0.5(unit amount) = 5
, $5 in total.
Tierd pricing
In tiered pricing, the cost of a given unit depends on the tier range that it falls into, defined by upper and lower bounds.
For example, the first 5 GB costs $0.5 each, 6-10 GB costs $0.3 each, and all subsequent GBs cost $0.2 each.
Tier Range (GB) | Price per GB ($) |
---|---|
1 - 5 | $0.5 |
6 - 10 | $0.3 |
11+ | $0.2 |
For 4 units, 4 x 0.5 = 2
, $2 in total.
For 8 units, 5 x 0.5 + 3 x 0.3 = 3.4
, $3.4 in total.
For 15 units, 5 x 0.5 + 5 * 0.3 + 5 * 0.2 = 5
, $5 in total.
Bulk pricing
In bulk pricing, units are billed in predefined bundles (bulk sizes).
For example, if the bulk size is 5, then 4 units will be billed as 5 and 6 units will be billed at 10.
For 4 units: 1 bulk x 5 (bulk amount) = $5
, $5 in total.
For 6 units: 2 bulks x 5 (bulk amount) = $10
, $10 in total.
Bulk Size | Bulk Amount |
---|---|
5 | $5 |
Volume pricing
In volume pricing, the total number of units determines the cost per unit for all units.
For example, if you've bought 8 units, total price will be 8 x 0.5(unit price) + 5(flat fee) = 9
, $9 in total.
Once you've bought more than 10 units, say 15 units, the total price will be
15 x 0.4(unit price) + 0.0(flat fee) = 6
, $6 in total.
Number of Units | Price per Unit ($) | Flat Fee ($) |
---|---|---|
1 - 10 | $0.50 | $5.00 |
11+ | $0.40 | $0.00 |
Percentage pricing
Percentage pricing applies a per-event rate (e.g., per-payment) expressed as a percentage of the transaction value. For example, if the price is set as following
Percentage rate | Flat Fee ($) |
---|---|
0.25 | $3.00 |
For a payment of $100, the charge will be
100 x 0.25(percentage rate) + 3(flat fee) = 27
, $27 in total.
Tiered percentage pricing
Tiered percentage pricing applies when a per-event (e.g., per-payment) rate is expressed as a percentage of the transaction value with several tiers.
For example, if the price is set as following
Number of Units | Percentage rate | Flat Fee ($) |
---|---|---|
1 - 10 | 0.25 | $3.00 |
11+ | 0.2 | $1.00 |
For a payment of 9, the charge will be 9 x 0.25(percentage rate) + 3(flat fee) = 5.25
, $5.25 in total.
For a payment of 20, the charge will be 10 x 0.25(percentage rate) + 3(flat fee) + 10 x 0.20(percentage rate) + 1(flat fee) = 8.5
, $8.5 in total.
Matrix pricing
In matrix pricing, the cost depends on combinations of two or more properties.
For example, if the price is set as following
Property 1 | Property 2 | Price per Unit ($) |
---|---|---|
partner = aws | region = us-east-1 | $0.5 |
partner = aws | region = us-west-1 | $0.3 |
partner = gcp | $0.4 |
Default price: $0.2
E2E Testing Plan
- Basic pricing
price := PriceModelBasic{
UnitAmount: 0.5
}
- With Count metric
- Tiered pricing
price := PriceModelTiered{
Tiers: []PriceModelTieredConfig{
{
FirstUnit: 1,
LastUnit: 1000,
UnitAmount: 0.5
},
{
FirstUnit: 1001,
LastUnit: 2000,
UnitAmount: 0.3
},
{
FirstUnit: 2001,
LastUnit: 0,
UnitAmount: 0.2
}
}
}
- With Unique Count metric
- Bulk pricing
price := PriceModelBulk{
BulkSize: 1000,
BulkAmount: 0.5
}
- With Sum metric
- Volume pricing
price := PriceModelVolume{
Volume: []PriceModelVolumeConfig{
{
FirstUnit: 1,
LastUnit: 1000,
UnitAmount: 0.5
},
{
FirstUnit: 1001,
LastUnit: 0,
UnitAmount: 0.4
}
},
}
- With Max metric
- Percentage pricing
price := PriceModelPercentage{
PercentageRate: 0.05
FlatFee: 0.3
}
- With Latest metric
- Tiered percentage pricing
price := []PriceModelTieredPercentageConfig{
{
PercentageRate: 0.05,
FirstUnit: 1,
LastUnit: 1000
},
{
PercentageRate: 0.01
FirstUnit: 1001,
LastUnit: 0
}
}
- With Count metric
- Matrix pricing
price := PriceModelMatrix{
DefaultUnitAmount: 0.2,
Prices: []PriceModelMatrixConfig{
{
Properties: [{
Name: "partner",
Value: "gcp"
}],
UnitAmount: 0.4
},
{
Properties: [{
Name: "partner",
Value: "aws"
Name: "region",
Value: "us-east-1"
}],
UnitAmount: 0.5
},
{
Properties: [{
Name: "partner",
Value: "aws"
Name: "region",
Value: "us-west-1"
}],
UnitAmount: 0.3
}
}
}
- With SUM metric