Usage-Based Pricing
6
Minutes Read
Published
October 3, 2025
Updated
October 3, 2025

Usage-Based Billing with Stripe: Technical Setup Guide for SaaS Founders and Engineers

Learn how to set up metered billing in Stripe to automatically charge your SaaS customers based on their actual product consumption.
Glencoyne Editorial Team
The Glencoyne Editorial Team is composed of former finance operators who have managed multi-million-dollar budgets at high-growth startups, including companies backed by Y Combinator. With experience reporting directly to founders and boards in both the UK and the US, we have led finance functions through fundraising rounds, licensing agreements, and periods of rapid scaling.

Step 1: Translating Your Pricing Model into Stripe Objects

Transitioning from flat-rate subscriptions to usage-based billing is a logical step for many SaaS companies. This model aligns your price with customer value, which can boost adoption and retention. However, the technical implementation is a significant challenge. The goal is not just to enable a feature but to accurately capture and sync real-time usage data with Stripe. This prevents the under-billing that hurts revenue and the over-billing that erodes customer trust. This guide provides a technical roadmap for how to set up metered billing in Stripe, ensuring your data reporting is reliable and your financial insights are sound.

Before writing any code, the first step is to translate your pricing model into Stripe's product and price structure. This foundational work prevents costly re-architecting later. Stripe refers to usage-based billing as "metered billing." The entire system is built around its core Product and Price objects. A Product represents the service you sell, while a Price defines the specific charging mechanics.

For any consumption-based model, the configuration begins at the Price level. The key setting for a Stripe metered billing setup is recurring[usage_type=metered]. This instructs Stripe not to charge a fixed amount but to invoice based on usage reported during the billing cycle. The next critical decision is controlled by the aggregate_usage parameter, which determines how Stripe combines all the usage records for a single subscription item to calculate the final invoice quantity.

Choosing Your Aggregation Method

The two most common aggregation options are sum and last_during_period. Your choice directly impacts how invoices are calculated, so it must align perfectly with what your customers expect to be billed for.

  • Sum of Usage (sum): This option adds up all usage reported during the billing period. It is best for transactional metrics where each event contributes to the final bill. Common use cases include API calls, gigabytes of data processed, or minutes of service used. For example, if you report quantities of 500, 1200, and 800, the final invoice quantity is 2500.
  • Last Reported Usage (last_during_period): This option uses only the most recent usage record reported within the billing period. It is designed for high-water mark or seat-based pricing models where you bill for the quantity in effect at the end of the period. A typical use case is active user or seat counts. If you report 10 seats, then 12, then 11, the invoice is for a quantity of 11 seats.

Choosing the wrong aggregation method can lead to immediate billing disputes. For instance, using sum for seat-based pricing would incorrectly add up every seat change, leading to a massively inflated bill. Getting this setting right is the first and most important step for accurate Stripe usage tracking.

Step 2: How to Set Up Metered Billing in Stripe by Reporting Usage

Once your pricing model is configured, the central technical task is to report usage data from your application to Stripe accurately and reliably. The mechanism for this is Stripe's Usage Reporting API, specifically the stripe.subscriptionItems.createUsageRecord endpoint. This call reports a single data point: a quantity of usage that occurred at a specific time, linked to a specific subscription item.

The most common and dangerous pitfall here is double-reporting usage. This error leads directly to over-billing and damages customer relationships. To prevent this, idempotency is not optional; it is a requirement. You must use idempotency keys with every API call that reports usage. An idempotency key is a unique token, like a UUID generated by your system, that you send with your API request. If a network error causes you to retry the request, Stripe uses the key to recognize it has already processed that specific event and prevents a duplicate record.

Here is an example of an idempotent API call in Node.js for a Stripe metered billing setup:

const stripe = require('stripe')('your_secret_key');
const idempotencyKey = 'unique-key-for-this-usage-record'; // e.g., your internal event ID

const usageRecord = await stripe.subscriptionItems.createUsageRecord(
'si_XXXXXXXXXXXXXX', // The subscription item ID
{
quantity: 100,
action: 'set', // or 'increment'
timestamp: Math.floor(Date.now() / 1000),
},
{
idempotencyKey: idempotencyKey,
}
);

The pattern across SaaS startups is consistent: early-stage companies often start by making direct API calls from their application server whenever a billable event occurs. This approach works for low volumes but lacks resilience. For a scalable system, a queue-based architecture is recommended. When a billable event happens, your application adds a message to a queue (like AWS SQS or RabbitMQ). A separate, dedicated worker process then reads from the queue and makes the idempotent call to Stripe. This architecture decouples your billing mechanism from your main application and handles retries gracefully if the Stripe API is temporarily unavailable. As you scale, you will eventually face a decision to build or buy your metering system.

Step 3: Managing the Customer Lifecycle with Stripe Billing Automation

Your customers will inevitably change their subscriptions. They will upgrade, downgrade, or modify services mid-cycle. Correctly handling these changes is crucial for maintaining a fair and transparent billing relationship. This is where proration and tiered pricing models intersect, and it is a primary area where configuration mistakes can cause significant billing confusion.

Stripe automatically handles proration for changes in recurring fees, but you must ensure your usage reporting logic adapts correctly. When a customer upgrades to a plan with a different set of metered prices, their subscription will have two subscription items for that billing period: one for the old plan (now inactive) and one for the new plan. Your system must be smart enough to stop reporting usage to the old item and start reporting it to the newly active subscription item.

Consider this example: a customer is on a "Pro Plan" with a base fee and usage priced at $0.10 per API call. On the 15th of the month, they upgrade to an "Enterprise Plan" with a higher base fee and a tiered pricing model: the first 10,000 calls are $0.08 each, and calls beyond that are $0.06. Your implementation must handle this sequence correctly.

  1. Upgrade Event: On the 15th, your system processes the upgrade. Stripe creates a new subscription item for the Enterprise Plan and deactivates the one for the Pro Plan.
  2. Update Reporting Logic: Your system must now retrieve the new subscription item ID associated with the Enterprise Plan and use it for all subsequent usage reporting. Any usage reported to the old ID will be ignored or fail.
  3. End of Cycle: At the end of the month, the invoice will correctly show a prorated Pro base fee, a prorated Enterprise base fee, and two separate line items for metered usage. One will show usage from the 1st to the 15th, billed at $0.10 per call. The other will show usage from the 15th to the 30th, billed according to the new tiered structure.

Manually testing these complex scenarios is inefficient and prone to error. Instead, you should use Stripe's Test Clocks. This feature lets you simulate a subscription moving through time to test plan changes and proration logic. You can create a test customer, advance the clock by days or weeks, simulate an upgrade, report usage, and then move the clock to the end of the billing period to inspect the draft invoice. This is the only reliable way to ensure your SaaS consumption billing setup handles lifecycle events correctly.

Step 4: Financial Reporting for SaaS Consumption Billing

Variable usage revenue creates a significant challenge for financial reporting and forecasting. Investors and board members want predictability, but your top-line revenue now fluctuates month to month. Your model may also introduce variable COGS tied to usage. The key is to move beyond simple cash-flow tracking in your accounting software, such as QuickBooks or Xero, and adopt an accrual-based perspective.

This becomes important when considering revenue recognition. The governing standard for US companies is US GAAP, specifically ASC 606. For UK companies, FRS 102 provides similar principles. As a fact, ASC 606 is the revenue recognition standard that dictates revenue should be recognized as it is consumed, not when an invoice is paid. This principle ensures your financial statements accurately reflect your business performance during a given period.

This accounting requirement creates the concept of "unbilled revenue," also known as accrued revenue. If a customer consumed $500 of your service in January but will not be invoiced until February 1st, that $500 is unbilled revenue for January. It appears as an asset on your January balance sheet, representing value you have delivered but not yet billed for. This provides a far more accurate picture of your company's performance than just looking at cash collected. For companies in the UK, you should also consider whether your growing variable revenue will exceed VAT registration thresholds, creating new compliance obligations.

To automate this, your billing system needs to communicate with your accounting system. A robust Stripe billing automation workflow relies on webhooks like invoice.created and invoice.paid. When an invoice is created in Stripe, a webhook can trigger a corresponding entry in QuickBooks or Xero. The invoice.paid event can then be used to reconcile the payment. This integration ensures your financial reporting keeps pace with your variable revenue, turning a complex billing model into a source of reliable financial insights.

Key Principles for a Scalable Stripe Metered Billing Setup

Implementing a robust, scalable metered billing system requires a thoughtful approach that goes beyond just calling an API. For SaaS founders managing finances with tools like Stripe and QuickBooks or Xero, focusing on a few key principles can prevent significant headaches and build a foundation for growth.

First, map your business logic to Stripe's pricing objects before you begin implementation. Decide on your aggregate_usage method carefully, as this choice fundamentally impacts how invoices are calculated and what your customers see.

Second, build your usage reporting system for reliability from day one. Using idempotency keys is non-negotiable to prevent duplicate charges. While direct API calls are acceptable for an MVP, plan to move to a queue-based system to ensure no usage data is ever lost. This is central to a trustworthy SaaS payment integration.

Third, test the entire customer lifecycle, not just the happy path. Use Stripe Test Clocks to simulate upgrades, downgrades, and cancellations to verify that proration and tiered pricing behave as you expect. This prevents billing surprises for both you and your customers.

Finally, establish sound financial reporting practices early. To forecast in a usage-based world, you must estimate unbilled revenue. A simple, practical method for internal forecasting is:

Forecasted Revenue = Committed Recurring Revenue (base fees) + (Average Daily Usage Rate * Your Price Per Unit * Days Remaining in Period)

This simple model provides a pragmatic, directionally correct forecast for managing cash flow and communicating with investors. By combining a solid technical setup with disciplined financial practices, you can successfully implement metered pricing and turn variable usage into a predictable, scalable revenue engine.

Frequently Asked Questions

Q: What is the difference between `action: 'set'` and `action: 'increment'` in the Stripe API?

A: The action parameter determines how a new usage record interacts with existing ones. set overwrites any usage reported for the same timestamp, establishing a definitive value. It is best for stateful metrics like seat counts. increment adds to the quantity for the subscription item and is ideal for counting discrete events like API calls.

Q: How do I find the `subscription_item_id` for reporting usage?

A: The subscription_item_id (prefixed with `si_`) is created when a customer subscribes to a specific price. You can retrieve it from the Subscription object, which contains a list of `items`. Your system should store this ID and associate it with the customer to ensure usage is reported to the correct line item.

Q: Can I report usage that occurred in the past?

A: Yes, the timestamp parameter allows you to report usage with a historical date. This is useful for batch processing or correcting data. However, Stripe rejects records with a timestamp outside the current billing period for that subscription item, preventing you from billing for a previously closed cycle.

This content shares general information to help you think through finance topics. It isn’t accounting or tax advice and it doesn’t take your circumstances into account. Please speak to a professional adviser before acting. While we aim to be accurate, Glencoyne isn’t responsible for decisions made based on this material.

Curious How We Support Startups Like Yours?

We bring deep, hands-on experience across a range of technology enabled industries. Contact us to discuss.