Metering usage is an essential aspect part Wingback as it allows for the creation of plans with complex pricing models that have usage-based components or usage limits. This guide will walk you through the core concepts of metering usage and how to report usage events.

Core Concepts

Usage-based billing allows you to charge customers based on their exact consumption of specific features or resources within your application. In Wingback, usage is tracked and reported on a per-feature basis, allowing you to configure different rules for each feature on a plan. You can also create plans with a fixed price that includes a certain amount of usage up to a specific limit.

As soon as usage is recorded, the live counters for every metered feature will update in near-realtime. They can be accessed through the Entitlement API, enabling you to easily monitor usage and enforce usage limits. Wingback will take care of correctly aggregating usage over a billing cycle and charging every customer accurately based on their specific plans. Customers can also track their live usage in the billing portal.

Wingback also uses the aggregated data to provide you with detailed usage analytics, giving insights into how the product is used and helping you optimize your plans.

Unit Resolution: We internally store all usage as fixed precision decimals with 0.000000000001 step resolution (12 digits), for values up to ±10^26, both for individual usage events and the customer lifetime aggregates. Please always send fractional usage as a string formatted number to prevent float conversion rounding errors.

Reporting Usage

Usage is reported by sending a collection of usage events to the bulk usage API endpoint. Each usage event represents the usage of a certain amount of “units” of a feature for a customer that occurred at a specific time. The units can be any amount of what you are measuring (e.g., a single action, CPU seconds, the number of reports) and you can set a (cosmetic) unit string in the plan editor if you want it to show up on invoices.

const events = [
  {
    "customer_id": "Cust_c40bea18-c0c9-44b1-bd0c-43f5283e1670",
    "feature_slug": "FEATURE_A",
    "units": 10
    // if no timestamp is provided, it will be set at ingestion
  },
  {
    "customer_id": "Cust_98672780-0099-4ec3-b13e-0716d1d38d02",
    "feature_slug": "FEATURE_B",
    // fractional usage should be sent as string
    "units": "10.2493", 
    "timestamp": "2023-03-16T03:45:00.000Z"
  }
];

fetch('https://api.wingback.com/v1/c/usage', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'wb-key': 'YOUR_SECRET_API_KEY'
  },
  body: JSON.stringify(events)
})
.then(response => console.log(response.json()))

Implementation Recommendations

Deciding which Features to Meter

We highly recommend implementing metering and entitlement checks for all your features and not just the ones you are currently charging for or that have limits from the get-go. This will enable your organization to create new plans with new pricing models at any time without requiring any modification in the backend and provide you the full range of analytics. Of course, you can also start by just metering the ones for which you have plans with usage-based pricing and add metering to the remaining features over time or as the need arises.

Ensuring Accurate Measurements

Make sure to account only for usage that has actually occurred by only reporting it at the end of the execution of your feature. For example, if the endpoint returned an error to the user, that usually means the usage should not be recorded. Similarly, jobs that didn’t complete should only record the partial usage.

Batching and Caching Logic

Since sending and ingesting an event takes time, we suggest implementing a local queue where events are collected as they occur. Submit these events in intervals, such as every 1-5 minutes, or when a large block of events has been collected (depending on your application 1.000-100.000). Ensure that this operation is asynchronous and doesn’t delay the current request, as it typically takes 5-15 seconds. If you have a distributed system, every instance or worker should have its own queue.

We highly advise against setting up periodic jobs (e.g. daily, hourly) that collect, aggregate, and report usage unless no other options are viable. Instead, aim to submit usage data within 1 to 5 minutes of its occurrence. This timely reporting ensures that usage limits can be accurately enforced, and customers are charged within the . It is generally recommended to provide exact timestamps for the most accurate reporting.

Handling Errors and Connection Issues

To prevent the loss of usage events due to network or server outages, strategies that reduce the potential loss of data should be implemented. If a batch of events fails to send, the operation should be retried using an exponential backoff strategy. In the unexpected case of an unrecoverable error, commit the batch to local disk or external storage for later manual reconciliation. Similarly, events that resulted in validation issues should be inspected to identify and resolve any potential issues in your codebase. We recommend setting up a monitoring system that sends alerts when such errors occur.

Issuing Corrections

Occasionally, miscalculations may occur, leading to over or under-reported usage, or there may be a partial outage in the service used to send usage events. In these cases, you can report usage corrections by sending the corresponding negative or positive amount(s) of unit(s) for the affected features with the timestamp(s) of the period in which it occurred. The live meters will update instantly, and the corrected usage numbers will be used for calculating your customers’ next invoices.

If the correction affected a previous billing period for which an invoice was already issued and the customer charged, Wingback will re-rate that period based on the updated usage. If there is any difference in the original invoice amount, a correction charge or refund will be added to the next invoice at the end of the current billing cycle.

High-Frequency Events

High-frequency events are typically not directly initiated by user actions (e.g., clicking a button in your app that results in an action) but generated from automated systems (for example, measuring consumed GPU or CPU hours for computing tasks or used bandwidth). While we support ingesting large amounts of very fine-grained data at second-precision, this can result in high bandwidth and processing requirements and will produce a lot more data than would be actually useful for both billing and analytics purposes. In these cases, it is recommended to sum all usage of a resource during a sensible interval first (e.g., 1, 5, or 10 minutes) and then only submit the aggregated data.

This is never an issue for lower-frequency usage events, and we do not recommend implementing such a strategy as it increases complexity and the risk of miscalculations.