Creating Meters
Learn what meters are and how to define them.
General Usage: Portal
A meter defines a feature of your system that you want to measure. It sets the expectations of the measurements including what the values represent and what labels are required.
Motivation
Usage based billing per customer starts by metering applications and infrastructure. Meters can range from CPU usage to number of trees planted. It is important to maintain clear definitions and expectations of our measurements so that they are well understood and can be used accurately in analysis and price plans. Meters do not have to measure things that you currently plan on billing for immediately, which makes them ideal for experimenting with new pricing models.
Usage
After creating a meter in Octane, you can send measurements corresponding to the meter from anywhere using Octane's REST API directly or client SDKs.
Creating meters through the portal

Definition
Field Name | Description | Type | Required |
---|---|---|---|
name | The meter identifier. Must be unique. Should be a dev-friendly string. NOTE: This is shown as 'ID' in the portal. | String | Required |
display_name | The name used in the UI. NOTE: This is shown as 'Name' in the portal. | String | Optional |
description | A description of the meter. Defaults to empty string. | String | Optional |
unit_name | The unit associated with the meter. Defaults to unit-less (e.g., a simple count). | Enum | Optional |
is_incremental | Whether the values specify an increment to the total or overwrite the existing total (see Incremental Values ). Defaults to True. | Boolean | Optional |
meter_type | The meter type (i.e., 'GAUGE' or 'COUNTER'). Defaults to 'counter'. | Enum | Optional |
primary_labels | A list of labels that identify a unique stream of measurements (see Independent Streams). Primary labels are required to be specified with any measurement for this meter. Defaults to empty list. | List | Optional |
Creating meters programmatically
Meters should generally be created through the portal
Example 1
We start with an example for tracking the number of API requests. First, we define a "num_api_requests" meter. We specify it as an incremental counter, meaning each measurement will identify the additional number of requests made to the API (learn more here).
import octane
octane.api_key = "<YOUR_API_KEY>"
octane.Meter.create(
name="num_api_requests",
description="Number of API requests to the system",
meter_type="COUNTER",
is_incremental=True,
)
import Octane from "octane-node";
const octane = new Octane("<YOUR_API_KEY>");
octane.meters.create({
name: "num_api_requests",
description: "Number of API requests to the system",
meterType: "COUNTER",
isIncremental: true,
primaryLabels: ["customer_id"],
expectedLabels: ["customer_id"]
});
package main
import "github.com/getoctane/octane-go"
func main() {
client := octane.NewClient("<YOUR_API_KEY>")
args := octane.MeterInputArgs{
Name: "num_api_requests",
Description: "Number of API requests to the system",
MeterType: "COUNTER",
IsIncremental: true,
PrimaryLabels: []string{"customer_id"},
ExpectedLabels: []string{"customer_id"},
}
_, _, err := client.Meters.Create(args)
if err != nil {
panic(err)
}
}
Example 2
In this example, we define a "storage" meter. We specify it as a gauge (learn more here), meaning that measurements represent a point-in-time value that can fluctuate. We also specify the unit, so that the value of measurements are understood to be in bytes. Finally, we specify that the primary label which will contain "storage_id" to distinguish measurements for the same customer across different storage instances. The primary label is important to ensure that the same meter can receive measurements for the same user from multiple sources. See our guide on Measurement Labels for more details.
import octane
octane.api_key = "<YOUR_API_KEY>"
octane.Meter.create(
name="storage",
description="Size of files in bytes",
meter_type="GAUGE",
unit="byte",
primary_labels=["storage_id"],
)
import Octane from "octane-node";
const octane = new Octane("<YOUR_API_KEY>");
octane.meters.create({
name: "storage",
description: "Size of files in bytes",
meterType: "GAUGE",
unitName: "byte",
primaryLabels: ["customer_id"],
expectedLabels: ["customer_id", "machine_id"]
});
package main
import "github.com/getoctane/octane-go"
func main() {
client := octane.NewClient("<YOUR_API_KEY>")
args := octane.MeterInputArgs{
Name: "storage",
Description: "Size of files in bytes",
MeterType: "GAUGE",
UnitName: "byte",
PrimaryLabels: []string{"customer_id"},
ExpectedLabels: []string{"customer_id", "machine_id"},
}
_, _, err := client.Meters.Create(args)
if err != nil {
panic(err)
}
}
Editing, deleting, and archiving meters
Meters typically can't be changed once created. Their display names can be updated, but things like their codename can't be changed retroactively since they might cause breaking changes in code integrations. However, we do allow for archiving and deleting meters. All of this can be done from the context menu for each meter on the Meters page.

Updating the display name of a meter allows you to update the name that shows up in places like price plans, invoices, and Octane components. It doesn't change how the meter is referenced in our API.
Deleting a meter totally removes it from our system. Meters can only be deleted if they were never used, or if they were used in a price plan that has never had a subscription.
Archiving a meter hides the meter from the UI and prevents it from being added to new price plans. It effectively deletes the meter, while allowing it to still be referenced from price plans without subscriptions, as well as invoices. An archived meter's codename is still reserved and can't be re-used by other meters in the future.
Updated about 1 year ago