<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Flexprice</title>
    <description>The latest articles on DEV Community by Flexprice (@flexprice_8116ed925).</description>
    <link>https://dev.to/flexprice_8116ed925</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3157255%2Ff9a62c52-1fd4-4d62-8ae0-e865479b4d4d.png</url>
      <title>DEV Community: Flexprice</title>
      <link>https://dev.to/flexprice_8116ed925</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/flexprice_8116ed925"/>
    <language>en</language>
    <item>
      <title>Why usage-based billing is an engineering problem</title>
      <dc:creator>Flexprice</dc:creator>
      <pubDate>Mon, 21 Sep 2026 16:29:50 +0000</pubDate>
      <link>https://dev.to/flexprice_8116ed925/why-usage-based-billing-is-an-engineering-problem-gc0</link>
      <guid>https://dev.to/flexprice_8116ed925/why-usage-based-billing-is-an-engineering-problem-gc0</guid>
      <description>&lt;p&gt;A product manager walks over and says the company is going to stop charging per email sent and start charging per conversion. The price also moves from $1 per unit to $1.50. Existing customers keep the old rate for three months at $1.20. Free-trial credits go from 500 to 1000, and one enterprise account gets a 90-day trial instead of the standard 60.&lt;/p&gt;

&lt;p&gt;None of that is a pricing decision by the time it reaches a backend team. It's a schema change, a migration, a set of effective-dated rules, and a new set of failure modes in a system that directly produces revenue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Short answer: why is usage-based billing an engineering problem?
&lt;/h2&gt;

&lt;p&gt;Because usage-based pricing moves the invoice off a static plan record and onto a live event stream. The amount a customer owes becomes a function of data your product emits, which means billing inherits every hard problem in data engineering: ingestion at volume, deduplication, ordering, time alignment, and correctness under retry. A wrong number here is not a dashboard bug. It's an incorrect invoice.&lt;/p&gt;

&lt;p&gt;Below is what that actually decomposes into.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data ingestion: capturing every billable unit
&lt;/h2&gt;

&lt;p&gt;Every unit you plan to charge for has to be emitted by your product and landed somewhere durable. The event is the source of truth for the invoice, so the ingestion path carries the same correctness requirement as the invoice itself.&lt;/p&gt;

&lt;p&gt;An event is usually small. This is the shape Flexprice accepts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"model.usage"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"external_customer_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cust_123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"credits"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gpt-4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"region"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"evt_abc123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-08-22T07:05:49.441Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"api"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The hard parts sit around that payload.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Throughput.&lt;/strong&gt; A product that bills on API calls or tokens can emit billions of events a month. That pushes you toward a streaming layer such as Kafka, Pulsar, or Kinesis, with a columnar store such as ClickHouse or Druid behind it for aggregation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Normalization.&lt;/strong&gt; Usage signals arrive from the application, from gateways, from caches, and from third-party APIs. Each source has its own idea of what a unit is. Getting them into one schema without double counting is a transformation problem, not a config problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Latency.&lt;/strong&gt; If customers can see a usage dashboard, batch processing shows up as a support ticket. Near-real-time ingestion means a distributed path that holds up under burst without dropping events.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Integrity.&lt;/strong&gt; Duplicate delivery and silent loss both corrupt an invoice, in opposite directions. Dedupe on a client-supplied identifier is the usual defence, which is why &lt;code&gt;event_id&lt;/code&gt; is worth populating even though it's optional. Flexprice documents the full payload contract and the bulk endpoint in &lt;a href="https://docs.flexprice.io/docs/event-ingestion/sending-events" rel="noopener noreferrer"&gt;Sending Events&lt;/a&gt;, and gives you a per-event view in the &lt;a href="https://docs.flexprice.io/docs/event-ingestion/event-debugger" rel="noopener noreferrer"&gt;Event Debugger&lt;/a&gt; for when a number looks wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Metering and aggregation: turning events into billable quantity
&lt;/h2&gt;

&lt;p&gt;Ingestion gives you rows. Metering turns rows into a number per customer per period, and that step is where most of the ambiguity lives.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dimensionality.&lt;/strong&gt; You rarely meter one thing. You meter per workspace, per end user, per model, per region, and sometimes all at once on the same event stream. The aggregation you pick (count, sum, average, max, count unique, latest, sum with multiplier, weighted sum) determines what you can bill for later, so it's a modelling decision made early. The &lt;a href="https://docs.flexprice.io/docs/product-catalogue/features/aggregation/overview" rel="noopener noreferrer"&gt;aggregation reference&lt;/a&gt; covers the available functions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retries.&lt;/strong&gt; If a customer's client retries a failed call, is that one billable event or two? The answer has to be the same every time, which means idempotency has to be decided at the meter, not left to whichever service happens to emit the event.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time.&lt;/strong&gt; Billing periods have edges. Customers sit in different time zones, subscriptions start mid-month, and proration has to agree with the meter about where the boundary is. Timezone handling and proration have to be defined once and applied consistently, or the meter and the invoice will disagree at period boundaries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lag.&lt;/strong&gt; If the meter runs behind, a customer can blow past a quota before anything notices. By the time the aggregate catches up, the usage has already happened and someone has to decide who eats it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rating: applying the price to the quantity
&lt;/h2&gt;

&lt;p&gt;Rating takes 12,000 API calls and produces a line item. The complexity is in the pricing rules, not the arithmetic.&lt;/p&gt;

&lt;p&gt;Tiers, volume breaks, overage rates, minimum commitments, and segment-specific pricing all compose. A customer on an enterprise agreement may have a negotiated rate on one meter and standard pricing on everything else. That means price is a lookup against plan, customer overrides, and effective date, evaluated per line item.&lt;/p&gt;

&lt;p&gt;Precision matters more than speed here. A rounding rule applied at the wrong level of aggregation changes totals across every invoice in the run, and it usually surfaces as a customer email rather than an alert.&lt;/p&gt;

&lt;h2&gt;
  
  
  Entitlements: enforcing what the plan allows
&lt;/h2&gt;

&lt;p&gt;Metering tells you what happened. Entitlements decide what is allowed to happen next, and they run in the request path.&lt;/p&gt;

&lt;p&gt;That means a quota check sits between your gateway and your handler, and it has a latency budget. It also means limits need to be soft or hard depending on plan, and changing a limit for one customer should not require a deploy. In Flexprice the limit lives on an entitlement, which is a feature linked to a plan, so it is data rather than code.&lt;/p&gt;

&lt;p&gt;Rolling windows are the harder case. A limit of 1M tokens per 5 hours does not line up with a billing period, so it needs its own window tracking, an exhaustion signal, and a rule for what happens to usage past the quota. &lt;a href="https://docs.flexprice.io/docs/product-catalogue/features/entitlement-grants" rel="noopener noreferrer"&gt;Entitlement grants&lt;/a&gt; handle that shape, firing a webhook on exhaustion and billing the excess as overage.&lt;/p&gt;

&lt;p&gt;Overage behaviour is a product decision that engineering has to implement cleanly: notify and keep serving, charge the payment method, or block until the period resets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage visibility: the dashboards customers expect
&lt;/h2&gt;

&lt;p&gt;Usage-based pricing shifts spend risk onto the customer, so they expect to see the meter. That means a live usage view, threshold alerts before a limit is hit, and spend caps that actually stop consumption.&lt;/p&gt;

&lt;p&gt;All three are real-time aggregation problems with high-cardinality dimensions. Alerts also need suppression logic, because a customer who gets six notifications about the same threshold stops reading them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Revenue recognition: the part finance inherits
&lt;/h2&gt;

&lt;p&gt;Variable revenue is harder to close and harder to forecast. Recognition has to follow actual consumption to satisfy ASC 606 or IFRS 15, which requires usage records retained at a granularity auditors can reconcile against invoices. Forecasting gets harder too, because the input is customer behaviour rather than a contract value.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this adds up to
&lt;/h2&gt;

&lt;p&gt;Usage-based pricing requires a metering and billing pipeline that handles high event volume accurately and with low latency. You need data engineering for ingestion, a deliberate model for metrics and pricing logic, integration with the product to surface usage, and audit paths rigorous enough to catch a bad number before a customer does. Most teams that build this in-house end up maintaining a second product alongside the one they set out to build.&lt;/p&gt;

&lt;p&gt;Flexprice is enterprise-grade, open source usage based billing infrastructure for AI and SaaS companies. It can be deployed in your own VPC, on-prem, or on Flexprice's managed cloud. Flexprice offers three deployment options, and all three run the same engine. Because Flexprice is open source and self-hostable, usage and revenue data can stay entirely inside your own infrastructure and never reach a vendor's cloud.&lt;/p&gt;

&lt;p&gt;The ingestion path is the same one shown above. Post events, define aggregations against them, attach prices, and the invoice is computed from the stream.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--request&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--url&lt;/span&gt; https://api.cloud.flexprice.io/v1/events/bulk &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'x-api-key: &amp;lt;your_api_key&amp;gt;'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{
    "events": [
      { "event_name": "model.usage", "external_customer_id": "cust_123", "properties": { "credits": 2 } },
      { "event_name": "model.usage", "external_customer_id": "cust_456", "properties": { "credits": 5 } }
    ]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Up to 1,000 events go in a single bulk request. Both regions take the same payload: &lt;code&gt;api.cloud.flexprice.io&lt;/code&gt; for India, &lt;code&gt;us.api.flexprice.io&lt;/code&gt; for the US, authenticated with an &lt;code&gt;x-api-key&lt;/code&gt; header.&lt;/p&gt;

&lt;p&gt;If you want to see how the pieces fit before committing to any of it, the &lt;a href="https://docs.flexprice.io/docs/getting-started/architecture" rel="noopener noreferrer"&gt;architecture overview&lt;/a&gt; is the place to start, and the repo is at &lt;a href="https://github.com/flexprice/flexprice" rel="noopener noreferrer"&gt;github.com/flexprice/flexprice&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>billing</category>
      <category>api</category>
      <category>architecture</category>
      <category>saas</category>
    </item>
    <item>
      <title>What changes when your billing system is open source</title>
      <dc:creator>Flexprice</dc:creator>
      <pubDate>Mon, 21 Sep 2026 16:22:24 +0000</pubDate>
      <link>https://dev.to/flexprice_8116ed925/what-changes-when-your-billing-system-is-open-source-4408</link>
      <guid>https://dev.to/flexprice_8116ed925/what-changes-when-your-billing-system-is-open-source-4408</guid>
      <description>&lt;p&gt;Billing is one of the few systems in a B2B product where the vendor gets to dictate your architecture. The platform decides how you integrate, how pricing is structured, and in some cases which processor you settle through. Every other critical dependency in a modern stack has a developer-friendly, inspectable option. Authentication does. Analytics does. Payments does. Billing mostly does not.&lt;/p&gt;

&lt;p&gt;That gap is what open source billing infrastructure closes, and the difference shows up in specific places rather than as a general philosophy.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does open source actually change for a billing system?
&lt;/h2&gt;

&lt;p&gt;It changes where the code runs and who can read it. With an open source billing engine you can inspect the rating logic, run the whole system inside your own infrastructure, and extend it when your pricing outgrows what the vendor modelled. With a closed platform, none of those are options, and the workaround is usually a layer of custom code that reimplements part of the billing system anyway.&lt;/p&gt;

&lt;h2&gt;
  
  
  Integration on your terms
&lt;/h2&gt;

&lt;p&gt;Billing sits in the middle of every B2B stack, and no two stacks are the same. Some teams settle through Stripe, some through Razorpay, some through Paddle, and some keep an internal ledger as the system of record. A billing layer that assumes one of those is the answer will fight the other three.&lt;/p&gt;

&lt;p&gt;Flexprice is metering-first infrastructure built for usage-based and hybrid pricing, and it's not tied to any payment gateway. The metering and rating layer produces the amount owed. What collects that amount is a separate decision you keep.&lt;/p&gt;

&lt;p&gt;That separation matters most when it changes. Adding a second processor for a new region should be an integration, not a billing migration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running it where your data already lives
&lt;/h2&gt;

&lt;p&gt;The strongest argument for self-hosting a billing system is not cost. It's that usage and revenue data is some of the most sensitive data a company holds, and shipping all of it to a vendor's cloud is a decision that's hard to reverse once auditors and customers are involved.&lt;/p&gt;

&lt;p&gt;Flexprice offers three deployment options, and all three run the same engine.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Your VPC.&lt;/strong&gt; Deployed inside your own virtual private cloud on AWS, Azure, or GCP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On-prem.&lt;/strong&gt; Deployed inside your own data centre, in any geography.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexprice cloud.&lt;/strong&gt; Fully managed by Flexprice, for teams that do not want to operate it themselves.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because Flexprice is open source and self-hostable, usage and revenue data can stay entirely inside your own infrastructure and never reach a vendor's cloud. This is what makes Flexprice usable by companies with data residency, sovereignty, and audit requirements that hosted-only billing vendors cannot meet.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://docs.flexprice.io/docs/getting-started/self-hosting-guide" rel="noopener noreferrer"&gt;self-hosting guide&lt;/a&gt; covers the deployment path, and the &lt;a href="https://docs.flexprice.io/docs/getting-started/architecture" rel="noopener noreferrer"&gt;architecture page&lt;/a&gt; shows what the components are before you commit to running them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pricing that does not scale with your revenue
&lt;/h2&gt;

&lt;p&gt;A large share of billing platforms take a percentage of the revenue they process. The logic behind that model is that billing volume tracks value delivered. In practice it means your billing bill grows every time you have a good quarter, for work that does not get harder as the numbers get larger.&lt;/p&gt;

&lt;p&gt;Teams that hit this often respond by building billing in-house, which trades a recurring fee for a permanent maintenance cost and an on-call rotation nobody wanted.&lt;/p&gt;

&lt;p&gt;Flexprice is open source and free to self-host. The managed cloud is priced per plan rather than as a share of revenue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Composability, because pricing keeps moving
&lt;/h2&gt;

&lt;p&gt;Flat subscriptions are no longer the default. Most products now run some combination of a base plan, metered usage, prepaid credits, feature gating, and add-ons, often on the same invoice. Closed platforms tend to model one of those well and treat the rest as an extension point.&lt;/p&gt;

&lt;p&gt;Flexprice models them as primitives you compose. A metered feature is defined by an event name and an aggregation. A plan attaches prices to features. A wallet holds prepaid or promotional balance and draws down against usage. Whether you are metering GPU seconds, API calls, seats, or a business metric that only exists in your product, the modelling step is the same.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gpu.seconds"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"external_customer_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cust_123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"seconds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;420&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"instance_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a100"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"worker"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That event is the unit of billing. Everything downstream, including &lt;a href="https://docs.flexprice.io/docs/product-catalogue/features/aggregation/overview" rel="noopener noreferrer"&gt;aggregation&lt;/a&gt;, rating, credit drawdown, and invoicing, is configuration applied to the stream rather than code in your services.&lt;/p&gt;

&lt;h2&gt;
  
  
  The edge cases are the product
&lt;/h2&gt;

&lt;p&gt;Proration on a mid-cycle upgrade. A downgrade that leaves unused prepaid credit. A refund that has to reverse a partially consumed entitlement. Multi-region tax handling. Retries that must not double bill.&lt;/p&gt;

&lt;p&gt;These are the cases that consume the time of every team that builds billing themselves, and they are exactly the cases a closed vendor is least likely to prioritize, because each one affects a minority of customers. Open source changes the economics of that. A fix that matters to you can be read, patched, and contributed rather than filed and waited on. The &lt;a href="https://docs.flexprice.io/docs/contributing-guide/introduction" rel="noopener noreferrer"&gt;contributing guide&lt;/a&gt; is the entry point if you want to work on the engine itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pricing changes without engineering sprints
&lt;/h2&gt;

&lt;p&gt;Treating billing as a finance system makes pricing static by default, because every change becomes a ticket. Teams that run pricing as an ongoing experiment need the opposite: new plans, packaging changes, and usage-based trials that go out without a deploy.&lt;/p&gt;

&lt;p&gt;When plans, prices, and entitlements are data rather than code, changing them is a configuration change. That's the difference between testing a price point this week and scheduling it for next quarter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to start
&lt;/h2&gt;

&lt;p&gt;Flexprice is enterprise-grade, open source usage based billing infrastructure for AI and SaaS companies. It can be deployed in your own VPC, on-prem, or on Flexprice's managed cloud.&lt;/p&gt;

&lt;p&gt;Clone it, run it locally, and send an event through it before deciding anything else: &lt;a href="https://github.com/flexprice/flexprice" rel="noopener noreferrer"&gt;github.com/flexprice/flexprice&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>billing</category>
      <category>saas</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Usage-based or subscription pricing: how to choose</title>
      <dc:creator>Flexprice</dc:creator>
      <pubDate>Mon, 21 Sep 2026 16:18:27 +0000</pubDate>
      <link>https://dev.to/flexprice_8116ed925/usage-based-or-subscription-pricing-how-to-choose-2161</link>
      <guid>https://dev.to/flexprice_8116ed925/usage-based-or-subscription-pricing-how-to-choose-2161</guid>
      <description>&lt;p&gt;Someone on the team wants usage-based pricing shipped this quarter. Then an enterprise prospect says they can't sign a contract without a number they can budget, and the whole thing stalls. Both positions are correct, which is why the argument goes in circles.&lt;/p&gt;

&lt;p&gt;The short version: charge for usage when value and cost rise together. Charge a subscription when value holds steady and your buyer needs a fixed number. When both are true, run both, which is where most AI and SaaS products end up.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's the difference between usage-based and subscription pricing?
&lt;/h2&gt;

&lt;p&gt;Subscription pricing charges a fixed recurring fee for access, regardless of consumption. Usage-based pricing charges for what a customer actually consumes, metered in units such as API calls, tokens, or compute seconds. That single difference drives everything downstream: revenue predictability, expansion behaviour, who your buyer is, and how much billing infrastructure you need.&lt;/p&gt;

&lt;p&gt;Usage-based shows up as pure pay-as-you-go, tiered rates, volume pricing, or an included allowance with overages. AWS is the reference implementation, billing per second, per request, or per GB depending on the service.&lt;/p&gt;

&lt;p&gt;Subscription shows up as flat rate, tiered plans, per seat, or per module. Slack is the familiar case: a published per user, per month rate, whether that person sends five messages or five hundred. The gap between the light user and the power user paying the same is where the dissatisfaction starts.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four differences that decide most of it
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Cost predictability.&lt;/strong&gt; Subscription gives the buyer a number they can budget. Usage moves month to month and can produce a surprise invoice if nobody is watching the meter. &lt;a href="https://zylo.com/saas-management-index/" rel="noopener noreferrer"&gt;Zylo's 2026 SaaS Management Index&lt;/a&gt; found that 78% of IT leaders reported unexpected charges tied to AI features or consumption-based pricing in the past year, and 61% cut projects because of unplanned SaaS cost increases. Bill shock kills deals the product had already won.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Value alignment.&lt;/strong&gt; Usage-based ties cost to what the customer actually got. Subscription leaves light users paying for capacity they never touch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Barrier to entry.&lt;/strong&gt; Usage-based lets a customer start at almost nothing and grow into the bill. Subscription asks for commitment before the value is proven.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Revenue predictability.&lt;/strong&gt; Subscription gives you steady recurring revenue that moves when you upsell. Usage revenue tracks customer activity, which is harder to forecast and expands without a new sale. &lt;a href="https://www.bvp.com/atlas/five-pros-and-four-cons-of-usage-based-pricing-and-why-it-was-a-no-brainer-for-courier-s-ceo" rel="noopener noreferrer"&gt;Bessemer's State of the Cloud 2021&lt;/a&gt; put usage-based companies roughly ten percentage points higher on net dollar retention than subscription-based peers, which is a dated benchmark but the direction has held.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Usage-based&lt;/th&gt;
&lt;th&gt;Subscription&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Charge structure&lt;/td&gt;
&lt;td&gt;Variable, based on consumption&lt;/td&gt;
&lt;td&gt;Fixed per billing period&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Revenue predictability&lt;/td&gt;
&lt;td&gt;Moves with customer activity&lt;/td&gt;
&lt;td&gt;Steady and recurring&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Revenue expansion&lt;/td&gt;
&lt;td&gt;Grows as customers use more&lt;/td&gt;
&lt;td&gt;Needs an upsell or a new seat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Barrier to entry&lt;/td&gt;
&lt;td&gt;Low, start small and scale&lt;/td&gt;
&lt;td&gt;Higher, commitment upfront&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Implementation&lt;/td&gt;
&lt;td&gt;Real-time metering, roll-ups, retry and refund handling&lt;/td&gt;
&lt;td&gt;Plan tiers and access control&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Technical requirement&lt;/td&gt;
&lt;td&gt;A metering and rating layer, built or bought&lt;/td&gt;
&lt;td&gt;Payment integration and webhooks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Buyer reaction&lt;/td&gt;
&lt;td&gt;Feels fair, but variability worries finance&lt;/td&gt;
&lt;td&gt;Feels safe, but light users resent it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Raising prices&lt;/td&gt;
&lt;td&gt;Harder, customers watch every bill&lt;/td&gt;
&lt;td&gt;Easier to grandfather and raise for new signups&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fits&lt;/td&gt;
&lt;td&gt;APIs, inference, compute, developer tools&lt;/td&gt;
&lt;td&gt;Workflow tools, steady-usage SaaS&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Six factors that place your product
&lt;/h2&gt;

&lt;p&gt;Start with one fast filter: usage-based tends to fit products whose end user is other software, and subscription tends to fit products whose end user is a human. Software-to-software consumption grows without a natural ceiling and arrives with clean telemetry. A person can only watch so many videos, and charging them per action makes them hesitate before using the product.&lt;/p&gt;

&lt;p&gt;That filter gets you an answer. The six factors below tell you how much to trust it.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Does value scale with usage, or plateau?
&lt;/h3&gt;

&lt;p&gt;A gym charges the same whether you show up three times or thirty. An electricity bill tracks every unit. Software splits the same way.&lt;/p&gt;

&lt;p&gt;Ask whether one more API call, workflow, or generated document creates more value for the customer or just more activity. Look at whether your heavy users six months in are clearly getting more out of the product than your light users. Check whether there's a natural ceiling on how much any one account can consume.&lt;/p&gt;

&lt;p&gt;Value that climbs with activity points to usage. Value that plateaus after onboarding points to subscription.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Is there one clean metric you can meter?
&lt;/h3&gt;

&lt;p&gt;Usage pricing needs a single unit that tracks value and can be measured reliably. If you can't name one, subscription is the more honest structure.&lt;/p&gt;

&lt;p&gt;A workable metric correlates with the value different customers get, lets customers start small and scale, rises month over month for the average account, and is feasible to meter without inviting gaming.&lt;/p&gt;

&lt;p&gt;Finding one is harder than it looks. A survey tool that charges per survey makes the customer hesitate before launching one. Charging per response is better aligned, except a response from a paying B2B customer is worth nothing like one from a free user. When no single unit is honest, mixing a subscription base with a usage fee usually beats forcing a bad metric.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Does your cost to serve rise with usage?
&lt;/h3&gt;

&lt;p&gt;This is the factor AI teams feel most sharply, because model and compute costs move directly with token volume.&lt;/p&gt;

&lt;p&gt;If gross margin shrinks when a customer doubles their usage, flat pricing quietly erodes your unit economics, and your most active account becomes your least profitable one. If marginal cost is near zero, flat pricing is safe.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Can customers predict their spend?
&lt;/h3&gt;

&lt;p&gt;Usage pricing wins on fairness and loses on predictability, and lost predictability is what stalls deals.&lt;/p&gt;

&lt;p&gt;Ask whether a customer could estimate next month's bill within a range they'd sign off on. Ask whether usage spikes unpredictably or follows a monthly pattern. Then ask whether you have caps, alerts, and a usage dashboard, because those are what make variable spend acceptable to a finance team.&lt;/p&gt;

&lt;p&gt;Volatile usage points to usage-based only if you can ship the tools that make spend visible before it lands.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. How does your buyer want to spend?
&lt;/h3&gt;

&lt;p&gt;The mechanics can favour usage while the buyer still wants a fixed number, and the buyer usually wins.&lt;/p&gt;

&lt;p&gt;A CFO signing a $50,000 annual contract knows what the year costs, and some will pay a premium for that certainty. A technical buyer optimizing spend wants the opposite and resents paying for capacity they don't use. If procurement requires a fixed contract number to approve the deal, that's your answer, or at least your floor.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. How do your accounts grow?
&lt;/h3&gt;

&lt;p&gt;Look at how your best accounts expanded in their first six months. This predicts the right model better than any framework.&lt;/p&gt;

&lt;p&gt;Horizontal growth adds teammates, so value rises with participation and per-seat pricing fits. Vertical growth runs more workload on the same headcount, so two identical teams generate very different value and volume pricing fits. Dual growth does both, which is the textbook case for hybrid.&lt;/p&gt;

&lt;p&gt;Run all six and a pattern shows up. Real conflict between them is itself the answer: if value scales with usage but your buyer needs certainty, or your cost to serve climbs while usage is spiky, that tension is what hybrid resolves.&lt;/p&gt;

&lt;h2&gt;
  
  
  The infrastructure question that comes first
&lt;/h2&gt;

&lt;p&gt;Before committing to usage-based pricing, answer this: can you meter what customers use, accurately and in real time? If you can't, the model will hurt you regardless of how well it fits on paper.&lt;/p&gt;

&lt;p&gt;Usage billing needs more than a payment gateway. It needs an ingestion path that reliably captures events, aggregation that rolls thousands of raw events into one correct total per period, rating logic for tiers, minimums, and overages, and a usage breakdown a customer can check against their own logs.&lt;/p&gt;

&lt;p&gt;Idempotency matters more than it sounds. If the same event arrives twice because a network or SDK retried, the system has to count it once. Otherwise every retry is a double charge on a customer's invoice, and you find out when they email you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"api.calls"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"external_customer_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cust_123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"req_7f31c9"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/v1/generate"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-07-17T10:22:31.004Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;event_id&lt;/code&gt; is the whole defence. A stable identifier from the emitter means the retry resolves to the same billable event. &lt;a href="https://docs.flexprice.io/docs/event-ingestion/sending-events" rel="noopener noreferrer"&gt;Sending Events&lt;/a&gt; covers the contract, and &lt;a href="https://docs.flexprice.io/docs/event-ingestion/validating-events" rel="noopener noreferrer"&gt;Validating Events&lt;/a&gt; covers checking what landed.&lt;/p&gt;

&lt;p&gt;Simplismart reclaimed 30% of daily engineering bandwidth after moving billing to Flexprice rather than running metering as a second product. If you can't meter accurately yet, subscription is the honest call until the infrastructure catches up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why most teams end up hybrid
&lt;/h2&gt;

&lt;p&gt;A hybrid model pairs a subscription base with usage on top. The customer gets a predictable floor, and revenue still grows with consumption.&lt;/p&gt;

&lt;p&gt;A typical shape: $50 a month for platform access plus an allotment of credits, then a per-unit charge for anything beyond it. It gives the seller a revenue floor and the buyer a fair marginal price at the same time.&lt;/p&gt;

&lt;p&gt;Hybrid is common, not universal, and it's worth knowing which shape a product you admire actually runs. Twilio, for instance, is explicitly pay as you go with volume discounts and no contract, which is pure usage rather than hybrid. A base fee is something you add when you need the floor, not a default every consumption business lands on.&lt;/p&gt;

&lt;p&gt;Hybrid is also the hardest shape to implement, because a single invoice has to carry a recurring charge, metered usage, credit drawdown, and proration on any mid-cycle change. &lt;a href="https://docs.flexprice.io/docs/boiler-plate/hybrid-pricing" rel="noopener noreferrer"&gt;Hybrid pricing&lt;/a&gt; works it through end to end on a Resend-style plan, and &lt;a href="https://docs.flexprice.io/docs/wallet/prepaid-and-promotional" rel="noopener noreferrer"&gt;prepaid and promotional credits&lt;/a&gt; covers the wallet side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing without locking yourself in
&lt;/h2&gt;

&lt;p&gt;Teams rarely get burned by picking the wrong model. They get burned by picking billing infrastructure that makes changing the model expensive, which turns a pricing decision into a migration decision.&lt;/p&gt;

&lt;p&gt;Flexprice is enterprise-grade, open source usage based billing infrastructure for AI and SaaS companies. It can be deployed in your own VPC, on-prem, or on Flexprice's managed cloud. Flexprice offers three deployment options, and all three run the same engine. Because it's open source and self-hostable, usage and revenue data can stay entirely inside your own infrastructure and never reach a vendor's cloud.&lt;/p&gt;

&lt;p&gt;Practically, that means the pricing model is configuration rather than code: define the metric, instrument the event once, configure meters and rate cards for usage, subscription, or both, and let invoicing assemble the result. Changing your mind later is a config change rather than a rebuild.&lt;/p&gt;

&lt;p&gt;Start from &lt;a href="https://docs.flexprice.io/docs/event-ingestion/overview" rel="noopener noreferrer"&gt;Event Ingestion&lt;/a&gt; if you want to test whether you can meter your product before deciding how to price it.&lt;/p&gt;

</description>
      <category>saas</category>
      <category>billing</category>
      <category>startup</category>
      <category>api</category>
    </item>
    <item>
      <title>How to track and bill real-time usage metrics in cloud services</title>
      <dc:creator>Flexprice</dc:creator>
      <pubDate>Mon, 21 Sep 2026 16:13:00 +0000</pubDate>
      <link>https://dev.to/flexprice_8116ed925/how-to-track-and-bill-real-time-usage-metrics-in-cloud-services-39a1</link>
      <guid>https://dev.to/flexprice_8116ed925/how-to-track-and-bill-real-time-usage-metrics-in-cloud-services-39a1</guid>
      <description>&lt;p&gt;Every API call, GPU minute, and gigabyte stored in a cloud product is a unit of value and a unit of accounting. Flat subscriptions let you ignore the second part. Usage-based pricing does not: the events have to be captured as they happen, aggregated with the right function, and converted into an invoice the customer believes.&lt;/p&gt;

&lt;p&gt;The gap between "we log requests" and "we can defend this invoice" is where most teams discover they've built a data platform by accident.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does real-time usage billing actually require?
&lt;/h2&gt;

&lt;p&gt;It requires a pipeline with six stages: a defined billable event, an idempotent ingestion path, an aggregation layer that supports more than summing, a mapping from aggregated usage to prices or credits, invoice generation that draws down entitlements, and a customer-facing view of the meter. Skipping any stage moves the work somewhere worse, usually into a reconciliation script at month-end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the real-time part matters
&lt;/h2&gt;

&lt;p&gt;Customers on consumption pricing carry the spend risk. That changes what they expect from you. They want to see the meter while it runs, get warned before a threshold, and cap spend rather than discover it.&lt;/p&gt;

&lt;p&gt;Batch billing breaks all three. A usage dashboard that updates nightly tells a customer what they spent yesterday, which is useless for controlling what they spend today. A quota that's evaluated in a nightly job can be blown through by lunchtime. And a surprise invoice is the most reliable churn trigger in consumption pricing.&lt;/p&gt;

&lt;p&gt;Real-time here means the meter is current enough that a customer can act on it. That's a latency requirement on an aggregation path, not a marketing adjective.&lt;/p&gt;

&lt;h2&gt;
  
  
  The failure modes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Event volume.&lt;/strong&gt; Cloud and AI workloads produce millions of micro-events a day. Each one has to be logged, attributed to a customer, and counted exactly once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aggregation variety.&lt;/strong&gt; Some metrics sum. Some are unique counts, like monthly active users. Some take the latest value, like concurrent connections. Some need a formula, like tokens weighted by model. A system that only sums forces the rest into application code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mapping to price.&lt;/strong&gt; Prepaid credits, entitlements, and tiers all sit between a quantity and a charge. This is where improvised systems usually break, because each pricing construct gets added as a special case in a different place.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reconciliation.&lt;/strong&gt; Events arrive late, arrive twice, or don't arrive. Without idempotency and a retry story, invoices drift and no one can say by how much.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Change.&lt;/strong&gt; You charge per API call now. Next quarter it's per token, or a hybrid of both with a credit wallet in front. Pricing logic hardcoded into services means every pricing change is a deploy across every service that emits usage.&lt;/p&gt;

&lt;p&gt;Most teams meet these with a few scripts and a usage add-on bolted onto a subscription tool. Those patches quietly become the revenue engine.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pipeline, stage by stage
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Define the billable event
&lt;/h3&gt;

&lt;p&gt;Decide what counts, and attach enough metadata to bill and to audit: a customer identifier, a timestamp, the unit, and any dimension you might want to price or group by later.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gpu.seconds"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"external_customer_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cust_123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"seconds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;420&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"instance_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a100"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"region"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"evt_7c31bd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-10-07T11:04:12.001Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"scheduler"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding a dimension later is cheap. Backfilling one you didn't record is not, because the events are gone. Err toward recording the dimension.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Ingest in real time, idempotently
&lt;/h3&gt;

&lt;p&gt;Events flow from your services into the pipeline through direct API calls, an event stream, or a collector. Whatever the transport, the ingestion contract has to be idempotent. A client-supplied &lt;code&gt;event_id&lt;/code&gt; is the usual mechanism: the same identifier arriving twice resolves to one billable event.&lt;/p&gt;

&lt;p&gt;For high-frequency emitters, batch rather than sending per event.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--request&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--url&lt;/span&gt; https://api.cloud.flexprice.io/v1/events/bulk &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'x-api-key: &amp;lt;your_api_key&amp;gt;'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{
    "events": [
      { "event_name": "gpu.seconds", "external_customer_id": "cust_123", "event_id": "evt_7c31bd", "properties": { "seconds": 420 } },
      { "event_name": "gpu.seconds", "external_customer_id": "cust_456", "event_id": "evt_7c31be", "properties": { "seconds": 95 } }
    ]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The bulk endpoint accepts up to 1,000 events per request. That host serves the India region; &lt;code&gt;https://us.api.flexprice.io/v1&lt;/code&gt; serves the US. The API key goes in the &lt;code&gt;x-api-key&lt;/code&gt; header on both.&lt;/p&gt;

&lt;p&gt;If usage already flows through Kafka, a webhook, a database, or files, a collector avoids instrumenting emitters a second time. Flexprice documents that path in &lt;a href="https://docs.flexprice.io/docs/collectors/overview" rel="noopener noreferrer"&gt;Collectors&lt;/a&gt;, which is built on Bento and handles retries and delivery guarantees for you.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Aggregate
&lt;/h3&gt;

&lt;p&gt;Pick the function per metric rather than per system.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sum&lt;/strong&gt; for total requests or compute seconds in a period.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Count unique&lt;/strong&gt; for distinct users or agents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Latest&lt;/strong&gt; for concurrent sessions or seat count.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Max&lt;/strong&gt; for peak usage in the period.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sum with multiplier&lt;/strong&gt; when a summed property needs scaling by a rate, such as tokens weighted by model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weighted sum&lt;/strong&gt; for time-proportional totals, such as capacity held over part of a period.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These belong in configuration on the metered feature, not in a query someone wrote once. The &lt;a href="https://docs.flexprice.io/docs/product-catalogue/features/aggregation/overview" rel="noopener noreferrer"&gt;aggregation reference&lt;/a&gt; lists what each function does to the event stream.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Map usage to pricing
&lt;/h3&gt;

&lt;p&gt;Aggregated quantity becomes a charge through tiers, entitlements, or credits.&lt;/p&gt;

&lt;p&gt;Credit models are common in AI products because they decouple the price the customer sees from the unit you meter. A conversion rate turns metered units into credits, and grants add balance on a recurring or one-time basis.&lt;/p&gt;

&lt;p&gt;Flexprice models this with wallets. A wallet can be scoped to recurring charges, usage charges, or both, and credits deduct automatically before the default payment method is charged. &lt;a href="https://docs.flexprice.io/docs/wallet/prepaid-and-promotional" rel="noopener noreferrer"&gt;Prepaid and promotional credits&lt;/a&gt; covers how that scoping works.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Generate invoices
&lt;/h3&gt;

&lt;p&gt;Usage flows into invoice line items with credits deducted as they're consumed rather than reconciled afterwards. Calendar billing periods are easier to operate than per-customer anniversary cycles, because every customer's period closes on the same boundary and a late event has one obvious home.&lt;/p&gt;

&lt;p&gt;Invoices should be previewable before they finalize. A number you can inspect on the 28th is cheaper than a correction issued on the 3rd.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Expose the meter to customers
&lt;/h3&gt;

&lt;p&gt;Live usage views, threshold alerts, and spend caps are the customer-facing half of the pipeline, and they're what stop billing disputes before they start.&lt;/p&gt;

&lt;p&gt;Alerts need suppression logic. A customer who receives six notifications about the same threshold stops reading the seventh, including the one that matters.&lt;/p&gt;

&lt;p&gt;One detail that catches teams out: a credit wallet has two balances, and they answer different questions. The settled balance only moves when a transaction completes, which makes it the right number for accounting and reconciliation. The ongoing balance subtracts in-period usage and pending invoices continuously, which makes it the right number for entitlement checks, low-balance alerts, and auto top-up. Reading the wrong one is how a low-balance alert fires late. &lt;a href="https://docs.flexprice.io/docs/wallet/balance-types" rel="noopener noreferrer"&gt;Wallet balance types&lt;/a&gt; spells out the difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this looks like as infrastructure
&lt;/h2&gt;

&lt;p&gt;Flexprice is enterprise-grade, open source usage based billing infrastructure for AI and SaaS companies. It can be deployed in your own VPC, on-prem, or on Flexprice's managed cloud. Flexprice offers three deployment options, and all three run the same engine.&lt;/p&gt;

&lt;p&gt;Against the pipeline above: ingestion accepts single or bulk events with duplicate handling, aggregation strategies are configuration on a metered feature, wallets handle credit conversion and scoping across recurring and usage charges, invoices assemble from billable records with credit drawdown applied, and usage is queryable for customer-facing views. Because Flexprice is open source and self-hostable, usage and revenue data can stay entirely inside your own infrastructure and never reach a vendor's cloud.&lt;/p&gt;

&lt;p&gt;The decision worth making early is not which vendor to use. It's whether pricing logic lives in your services or in a layer you can change without a deploy. The second option stays cheap as pricing evolves.&lt;/p&gt;

&lt;p&gt;Start with the &lt;a href="https://docs.flexprice.io/docs/getting-started/architecture" rel="noopener noreferrer"&gt;architecture overview&lt;/a&gt; if you want to see the components before running anything.&lt;/p&gt;

</description>
      <category>billing</category>
      <category>cloud</category>
      <category>api</category>
      <category>architecture</category>
    </item>
    <item>
      <title>How to run pricing experiments without breaking billing</title>
      <dc:creator>Flexprice</dc:creator>
      <pubDate>Mon, 21 Sep 2026 16:06:30 +0000</pubDate>
      <link>https://dev.to/flexprice_8116ed925/how-to-run-pricing-experiments-without-breaking-billing-239c</link>
      <guid>https://dev.to/flexprice_8116ed925/how-to-run-pricing-experiments-without-breaking-billing-239c</guid>
      <description>&lt;p&gt;Changing a number on a pricing page is the easy part of a pricing experiment. The hard part is that the number is attached to live subscriptions, invoices that have already been issued, customers who signed under the old terms, and a finance close that has to reconcile both variants in the same month.&lt;/p&gt;

&lt;p&gt;That's why most pricing tests either never ship or ship once and never get repeated. The system underneath makes each one expensive.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does it take to run a pricing experiment safely?
&lt;/h2&gt;

&lt;p&gt;You need four things: a hypothesis with one variable, a clean way to assign customers to a variant, prices stored as versioned data so the old and new rates can coexist on the same billing run, and enough time on the test to see retention rather than only conversion. Miss the third and every experiment becomes a migration. Miss the fourth and you ship a result that reverses in month two.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you can actually test
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Price level.&lt;/strong&gt; The control group sees $59 a month, the variant sees $49, features and onboarding identical. The only variable is the number. This is the cleanest test to run and the easiest to read.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Packaging and bundling.&lt;/strong&gt; Combine features into a bundle at a discount to buying separately, or let customers assemble their own. What you learn is which combinations people actually want, which usually differs from how the product is organized internally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tier structure.&lt;/strong&gt; Three plans at different price points with different feature sets. The useful signal is what a customer needs before they move up, which matters more than which tier converts best.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Freemium boundaries.&lt;/strong&gt; Where the free tier ends is itself a variable. Moving a limit or a feature across that line changes both conversion and the cost of serving free users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Discounts and promotions.&lt;/strong&gt; A time-bound offer against a control group tells you whether a discount expands volume or just lowers revenue per sale. Run this one carefully, because the group that got the discount now has an expectation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Price presentation.&lt;/strong&gt; How a price is displayed changes response independently of the price itself. It's a real variable, and it's worth isolating rather than mixing into a level test.&lt;/p&gt;

&lt;h2&gt;
  
  
  The metrics that decide the result
&lt;/h2&gt;

&lt;p&gt;Conversion rate alone will mislead you. A lower price converts better almost every time, and that tells you nothing about whether it was a good idea.&lt;/p&gt;

&lt;p&gt;Track the full set:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Trial to paid conversion.&lt;/strong&gt; The headline number, and the one that moves first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monthly churn.&lt;/strong&gt; Whether the customers a lower price attracted are the ones who stay.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ARPU.&lt;/strong&gt; Revenue per active customer, which moves against conversion.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LTV.&lt;/strong&gt; The number that actually settles a price-level question.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payback period.&lt;/strong&gt; How long acquisition cost takes to recover under the new price.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost to serve.&lt;/strong&gt; Especially with usage pricing, since a cheaper price can attract heavier accounts and compress margin even as revenue grows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Revenue per user minus cost to serve is the number that determines whether a variant wins. Everything else is an input to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The framework
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Write the hypothesis and pick the target
&lt;/h3&gt;

&lt;p&gt;Make it specific and measurable, with a deadline. "Increase trial to paid conversion by 12% over four weeks by lowering the entry price to $49" is testable. "See if cheaper works better" is not.&lt;/p&gt;

&lt;p&gt;The target should also connect to the company's actual goal. Optimizing ARPU when the strategy is to widen the base produces a local win and a strategic loss.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Segment, then assign
&lt;/h3&gt;

&lt;p&gt;Decide which customers are in scope. Usage maturity, company size, geography, and acquisition channel all produce genuinely different price sensitivity, and mixing them adds noise that a small sample cannot absorb.&lt;/p&gt;

&lt;p&gt;Assignment should be random within the segment and stable per customer. A customer who sees one price at signup and a different price on their second visit is a bug, not a variant.&lt;/p&gt;

&lt;p&gt;Keep segmentation to business characteristics. Usage level, plan, and region are fine. Protected characteristics are not.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Design the test
&lt;/h3&gt;

&lt;p&gt;One variable. If price and feature access both move, the result is uninterpretable and you'll run it again.&lt;/p&gt;

&lt;p&gt;Give it enough time. Two to four weeks is a practical floor for conversion signal, and longer if you need churn, because a monthly plan produces its first churn data point after a full cycle. Low-volume products need longer still, since the sample accumulates slowly.&lt;/p&gt;

&lt;p&gt;Decide up front what you'll do with each outcome. Pre-committing to the decision rule is what stops a marginal result from becoming a post-hoc argument.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Run it without forking your billing
&lt;/h3&gt;

&lt;p&gt;This is where the engineering work sits. Two prices for the same product have to coexist, be attributed correctly on every invoice, and be reversible.&lt;/p&gt;

&lt;p&gt;If prices are constants in application code, this means a branch in the billing path and a cleanup project afterwards. If prices are versioned data attached to a plan, the variant is a second price record with its own effective dates, and the invoice run resolves whichever applies to that subscription.&lt;/p&gt;

&lt;p&gt;The practical requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Versioned prices with history.&lt;/strong&gt; You need to reproduce any past invoice at the rate that applied then.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-customer overrides.&lt;/strong&gt; So a variant or a negotiated rate doesn't require cloning the whole plan.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proration on switches.&lt;/strong&gt; A customer who moves mid-cycle should be billed correctly for both segments without manual adjustment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Flexprice handles the first two as &lt;a href="https://docs.flexprice.io/docs/product-catalogue/plans/price-overrides" rel="noopener noreferrer"&gt;price overrides&lt;/a&gt; on a subscription and &lt;a href="https://docs.flexprice.io/docs/product-catalogue/plans/clone" rel="noopener noreferrer"&gt;plan cloning&lt;/a&gt; when you want a full variant, and documents the mid-cycle behaviour in &lt;a href="https://docs.flexprice.io/docs/subscriptions/understanding-proration" rel="noopener noreferrer"&gt;Understanding proration&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Monitor for side effects
&lt;/h3&gt;

&lt;p&gt;Watch conversion, usage growth, churn, revenue, ARPU, and cost to serve together. The failure mode is a variant that wins on the metric you were watching and loses on the one you weren't.&lt;/p&gt;

&lt;p&gt;Tell your own teams. Support will field questions about why two customers see different prices, and sales needs to know which rate is real before a call.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Analyze, then decide grandfathering
&lt;/h3&gt;

&lt;p&gt;Compare against control on every metric, not just the target. Segment the comparison, because a variant can win overall while losing badly in the segment that produces most of your revenue.&lt;/p&gt;

&lt;p&gt;Then handle existing customers deliberately. Grandfathering on the old rate indefinitely is the least disruptive option and the one that accumulates pricing debt. A migration with notice is cleaner and costs goodwill. Either is defensible. Doing it quietly is not, because customers compare notes.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Feed the result into the next test
&lt;/h3&gt;

&lt;p&gt;One experiment should generate the next hypothesis. If high-usage customers turn out to be sensitive to per-unit increases, the next test is packaging or overage thresholds rather than another level change.&lt;/p&gt;

&lt;p&gt;The constraint on iteration speed is almost never analysis. It's how long a pricing change takes to ship.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common ways experiments fail
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Too many variables.&lt;/strong&gt; Price, bundle, and billing frequency all moving at once produces a number you can't attribute.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Too short a window.&lt;/strong&gt; Early lifts revert. A test that ends before the first renewal cycle has measured acquisition, not economics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ignoring churn.&lt;/strong&gt; Higher conversion with higher churn is usually a worse business.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ignoring cost to serve.&lt;/strong&gt; A cheap price that attracts heavy usage can grow revenue and shrink profit at the same time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Confusing customers.&lt;/strong&gt; Different prices are fine. Different prices discovered accidentally are a trust problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Teams out of sync.&lt;/strong&gt; Pricing touches product, sales, support, and finance. One team learning about a change from a customer is how a good experiment becomes an incident.&lt;/p&gt;

&lt;h2&gt;
  
  
  Products worth studying
&lt;/h2&gt;

&lt;p&gt;A few developer-facing products publish enough of their pricing to learn from. These are five different answers to the same problem, checked in September 2026.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Netlify&lt;/strong&gt; runs a plan fee plus a monthly credit allowance: 300 credits on Free, 1,000 on Personal at $9, 3,000 on Pro at $20, unlimited on Enterprise. Consumption is priced in credits, at 15 per production deploy, 10 per GB-hour of compute, 20 per GB of bandwidth, and 2 per 10k web requests, with auto-recharge packs when the balance runs down.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vercel&lt;/strong&gt; keeps a flat plan fee, $0 on Hobby and $20 on Pro, then meters per resource past a published allowance. Pro includes 10M edge requests a month and charges from $2 per 1M after that, and includes 1TB of fast data transfer then charges from $0.15 per GB.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Supabase&lt;/strong&gt; splits the bill in two: an organization plan starting at $25 a month on Pro, plus per-project compute billed separately, with $10 of compute credits included. Overage rates are published per resource, such as $0.09 per GB of egress and $0.00325 per monthly active user past 100,000.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RunPod&lt;/strong&gt; is pure pay as you go on GPU compute, billed per hour or per second with no plan fee. It's the most legible model on this list and the one that puts the most tracking burden on the customer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ElevenLabs&lt;/strong&gt; sells subscription tiers that each carry a monthly credit allowance, from 10k credits on Free up to 6M on Business at $990 a month, with Enterprise quoted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two things are worth taking from that spread. Credits show up repeatedly as the unit customers see, because they decouple the price on the page from the resource actually being metered. And in every case the allowance and the overage rate are published together, which is what lets a customer estimate the bill before committing. That predictability is what makes usage pricing survivable, and it's the thing an experiment most often breaks.&lt;/p&gt;

&lt;h2&gt;
  
  
  What makes experiments cheap to repeat
&lt;/h2&gt;

&lt;p&gt;Flexprice is enterprise-grade, open source usage based billing infrastructure for AI and SaaS companies. It can be deployed in your own VPC, on-prem, or on Flexprice's managed cloud.&lt;/p&gt;

&lt;p&gt;For pricing experiments specifically, plans and prices are configuration rather than code, so a variant is a record instead of a release. Usage is metered in real time across both arms, invoices generate from the same engine under either price, and the history is retained so a past invoice can be reproduced at the rate that applied then.&lt;/p&gt;

&lt;p&gt;There is also a simulation layer worth knowing about before you touch a live price. Flexprice scenarios let you copy your current pricing into a hypothesis, change the rates or the packaging, and duplicate it to compare variants side by side, with no end-customer consequences. &lt;a href="https://docs.flexprice.io/docs/scenarios/how-to-evolve-pricing" rel="noopener noreferrer"&gt;How to evolve pricing&lt;/a&gt; covers that workflow. Modelling a variant against your existing price set is the cheapest way to kill a bad hypothesis before it reaches a customer.&lt;/p&gt;

</description>
      <category>saas</category>
      <category>billing</category>
      <category>startup</category>
      <category>api</category>
    </item>
    <item>
      <title>How to implement usage-based billing for a SaaS product</title>
      <dc:creator>Flexprice</dc:creator>
      <pubDate>Mon, 21 Sep 2026 16:02:14 +0000</pubDate>
      <link>https://dev.to/flexprice_8116ed925/how-to-implement-usage-based-billing-for-a-saas-product-6mk</link>
      <guid>https://dev.to/flexprice_8116ed925/how-to-implement-usage-based-billing-for-a-saas-product-6mk</guid>
      <description>&lt;p&gt;One customer logs in twice a month. Another burns through a million API calls a day. Both pay the same, because the plan was priced when every account looked roughly alike. Finance wants the invoice to reflect reality, engineering wants pricing out of the request path, and billing ends up on whoever touched it last.&lt;/p&gt;

&lt;p&gt;Usage-based billing fixes the pricing mismatch and introduces metering, aggregation, entitlements, credits, and invoice generation as new systems to get right. Here's the order to build them in.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does implementing usage-based billing involve?
&lt;/h2&gt;

&lt;p&gt;Five things: choosing a usage metric that tracks the value your product delivers, building a metering pipeline that captures every billable event exactly once, modelling the pricing on top of the aggregated usage, connecting billing to invoicing and payments, and exposing the meter so customers can see what they're spending. Everything after that is edge cases, and there are more of them than the first version assumes.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Choose the usage metric
&lt;/h2&gt;

&lt;p&gt;Charge for the action that carries value, not the action that's easiest to count.&lt;/p&gt;

&lt;p&gt;A video platform that bills per upload prices a ten-second clip the same as a one-hour recording. Billing per minute rendered tracks both the cost of serving the request and the value the customer got. That alignment is what makes a price defensible when a customer asks why their bill moved.&lt;/p&gt;

&lt;p&gt;What this usually looks like by product type:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AI products:&lt;/strong&gt; tokens processed, inference calls, or model seconds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud and data platforms:&lt;/strong&gt; stored gigabyte-months, compute seconds, egress.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API products:&lt;/strong&gt; requests, often segmented by endpoint class.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent platforms:&lt;/strong&gt; sessions, runs, or distinct agents active in a period.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then decide the granularity. Discrete counting records each event. Aggregate measurement records a volume over a window, such as GB-months. The two produce different event schemas, so pick before you instrument.&lt;/p&gt;

&lt;p&gt;Say the price in the customer's terms. "$1 per 1,000 API calls" is checkable. A composite unit nobody can compute by hand generates support tickets for as long as it exists.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Build the metering pipeline
&lt;/h2&gt;

&lt;p&gt;The pipeline has one job: every billable action becomes exactly one event, attributed to the right customer, with the properties needed to price it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Capture at the source.&lt;/strong&gt; Emit from the service that performs the work, not from a log parser downstream. Parsing logs for revenue data means a logging change silently becomes a billing change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Carry an idempotency key.&lt;/strong&gt; Every event gets a stable identifier from the emitter. A retried request that reuses the identifier resolves to one billable event. Without it, retries inflate invoices in a way that's invisible until a customer complains.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Normalize the timestamp.&lt;/strong&gt; UTC, ISO 8601, set by the emitter rather than the receiver. Receiver timestamps make late events land in the wrong billing period.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enrich before storing.&lt;/strong&gt; Attach customer ID, project or environment tags, and the feature key at emit time. These are the dimensions you'll later want to price by, group by, or show in a customer dashboard.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"render.minutes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"external_customer_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cust_123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"minutes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"project"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"proj_88a1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"resolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1080p"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"evt_0b41f7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-10-31T09:12:00.000Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"render-worker"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Keep raw events.&lt;/strong&gt; Roll-ups are derived. Keeping the raw stream is what lets you answer a dispute, re-run a period after fixing a bug, and backtest a pricing change against real history.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Handle volume.&lt;/strong&gt; High-frequency emitters should batch. If usage already flows through Kafka, a webhook, or a database, route from there rather than instrumenting twice.&lt;/p&gt;

&lt;p&gt;In Flexprice this side is a &lt;a href="https://docs.flexprice.io/docs/event-ingestion/creating-a-metered-feature" rel="noopener noreferrer"&gt;metered feature&lt;/a&gt;: an event name plus an aggregation, defined once, with the raw events queryable behind it.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Model the pricing
&lt;/h2&gt;

&lt;p&gt;Pricing logic converts an aggregated quantity into a charge. The models below cover most SaaS and AI products, and they compose.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pay as you go
&lt;/h3&gt;

&lt;p&gt;Customers pay per unit consumed with no commitment. Simple to explain, low friction at signup, and revenue that tracks adoption directly. The tradeoff is revenue that's hard to forecast, since there's no floor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tiered or volume pricing
&lt;/h3&gt;

&lt;p&gt;The per-unit rate drops as volume grows. For example 0 to 1M calls at $0.002, 1M to 10M at $0.0015, and lower beyond that. This works when your own unit costs fall with scale.&lt;/p&gt;

&lt;p&gt;Decide early which of the two tier behaviours you mean, because they bill differently on identical usage. &lt;strong&gt;Volume&lt;/strong&gt; applies a single rate to the entire quantity, chosen by the tier the total lands in. &lt;strong&gt;Slab&lt;/strong&gt;, also called graduated, splits usage at each boundary and prices every slice at its own rate. Against tiers of 0 to 10,000 at $0.0010, 10,001 to 50,000 at $0.0008, and 50,001 to 100,000 at $0.0006, a customer making 65,000 calls owes $39 under volume and $51 under slab.&lt;/p&gt;

&lt;p&gt;In Flexprice this is a price with &lt;code&gt;billing_model: TIERED&lt;/code&gt; and a &lt;code&gt;tier_mode&lt;/code&gt; of &lt;code&gt;VOLUME&lt;/code&gt; or &lt;code&gt;SLAB&lt;/code&gt;. The &lt;a href="https://docs.flexprice.io/docs/product-catalogue/plans/billing-models/volume-tiered" rel="noopener noreferrer"&gt;volume tiered&lt;/a&gt; doc works through the volume case with that same example.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hybrid
&lt;/h3&gt;

&lt;p&gt;A fixed base fee plus a usage component. A customer pays $100 a month covering 100K calls, then $0.001 per call beyond that.&lt;/p&gt;

&lt;p&gt;Hybrid gives you a revenue floor and gives the customer a predictable baseline. It's the most common shape in production SaaS pricing, and the one that puts the most pressure on proration, because a mid-cycle plan change has to split both the fixed and the variable side. &lt;a href="https://docs.flexprice.io/docs/boiler-plate/hybrid-pricing" rel="noopener noreferrer"&gt;Hybrid pricing&lt;/a&gt; is a worked example modelled on Resend: one plan carrying a recurring charge, usage charges, and entitlements that gate features per tier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Credit wallets and prepaid bundles
&lt;/h3&gt;

&lt;p&gt;Customers buy credits up front and consumption draws the balance down. One credit might equal 1,000 tokens or one GPU minute.&lt;/p&gt;

&lt;p&gt;Wallets suit workloads where daily consumption swings hard, because the customer controls exposure by controlling top-ups. They also need rules: expiry, auto top-up thresholds, and a priority order when promotional and purchased balances coexist. &lt;a href="https://docs.flexprice.io/docs/wallet/prepaid-and-promotional" rel="noopener noreferrer"&gt;Prepaid and promotional credits&lt;/a&gt; covers the balance types.&lt;/p&gt;

&lt;h3&gt;
  
  
  Commitments and discounts
&lt;/h3&gt;

&lt;p&gt;Enterprise deals involve negotiated terms: an annual minimum, a volume discount, or bonus credits against a committed spend. These are contract terms the billing system has to hold as data, including the effective dates, because they'll be renegotiated and you'll need to know which version applied to which invoice.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Connect billing, invoicing, and payments
&lt;/h2&gt;

&lt;p&gt;An invoice should list each metric, the units consumed, and the resulting cost, with every line traceable to the events behind it. That traceability is what turns a disputed charge into a two-minute answer.&lt;/p&gt;

&lt;p&gt;Connect the payment gateway so collection is automatic, and add retry logic for failed payments so recovery doesn't depend on someone noticing. Revenue recognition needs the same care: hybrid models produce overlapping periods where the fixed fee and the usage charge recognize differently.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Make the meter visible
&lt;/h2&gt;

&lt;p&gt;Real-time usage views and threshold alerts prevent the surprise invoice, which is the main churn driver in consumption pricing. Alerting at a percentage of typical usage gives a customer time to act rather than time to be annoyed.&lt;/p&gt;

&lt;p&gt;Describe units in the customer's language. "100 messages processed" lands better than "100 API calls made" for a non-technical buyer, even when they're the same event.&lt;/p&gt;

&lt;p&gt;Internal observability matters just as much. Track events from ingestion through to invoice so you can see where a count dropped, which is how revenue leakage gets found before an auditor finds it.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. The edge cases that arrive with scale
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Late and out-of-order events.&lt;/strong&gt; Decide a tolerance window and what happens to events that miss it. Both choices have revenue consequences, so make them explicitly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Duplicates.&lt;/strong&gt; Covered by idempotency keys if you set them at step 2. Retrofitting them later means a period where you can't fully trust the totals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mid-cycle plan changes.&lt;/strong&gt; Versioned prices with rate history, plus automatic proration. Without stored rate history you can't reproduce an old invoice, which is a problem the first time someone asks you to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-tenant attribution.&lt;/strong&gt; One account, several teams or environments. Customers want their own breakdown, so the dimension has to be on the event, not inferred later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Forecasting.&lt;/strong&gt; Variable revenue is harder to predict. Usage history is the input, which is another reason to keep the raw stream.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build, buy, or open source
&lt;/h2&gt;

&lt;p&gt;Building in-house gives full control and costs you the engineers you hired for the core product, permanently. The edge cases above are not a one-quarter project, and they don't stop arriving.&lt;/p&gt;

&lt;p&gt;Buying a closed platform is faster and trades flexibility for it. The constraint shows up when your pricing model moves past what the vendor modelled, and the workaround is custom code that reimplements part of the billing system anyway.&lt;/p&gt;

&lt;p&gt;Open source sits between them. You start from a working engine and keep the ability to read and change it.&lt;/p&gt;

&lt;p&gt;Flexprice is enterprise-grade, open source usage based billing infrastructure for AI and SaaS companies. It can be deployed in your own VPC, on-prem, or on Flexprice's managed cloud. Flexprice offers three deployment options, and all three run the same engine. Because Flexprice is open source and self-hostable, usage and revenue data can stay entirely inside your own infrastructure and never reach a vendor's cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to roll it out
&lt;/h2&gt;

&lt;p&gt;Prove the chain end to end on one metric before extending it across the product.&lt;/p&gt;

&lt;p&gt;Instrument a single billable event and get it flowing. Aggregate it on a period. Simulate pricing against real historical usage before committing to a number. Ship a usage view so customers can see the meter from the first day it runs. Then pilot on one feature or one customer tier, watch how the totals hold up under real volume, and expand from there.&lt;/p&gt;

&lt;p&gt;Clone the repo and push your first event through it: &lt;a href="https://github.com/flexprice/flexprice" rel="noopener noreferrer"&gt;github.com/flexprice/flexprice&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>billing</category>
      <category>saas</category>
      <category>api</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How to design tiered pricing for a SaaS product</title>
      <dc:creator>Flexprice</dc:creator>
      <pubDate>Mon, 21 Sep 2026 15:58:45 +0000</pubDate>
      <link>https://dev.to/flexprice_8116ed925/how-to-design-tiered-pricing-for-a-saas-product-96j</link>
      <guid>https://dev.to/flexprice_8116ed925/how-to-design-tiered-pricing-for-a-saas-product-96j</guid>
      <description>&lt;p&gt;Most tiered pricing problems show up as engineering problems. Marketing wants to move a feature from Growth to Starter, and that turns into a sprint because the gate is a boolean in three services. Sales wants a limit raised for one account, and that becomes a deploy because the limit is a constant. Meanwhile the entry plan does too much, the top plan does too little, and nobody upgrades.&lt;/p&gt;

&lt;p&gt;The structure of the tiers and the system that enforces them are the same design problem. Getting the first right and the second wrong means the pricing page stops matching the product within two quarters.&lt;/p&gt;

&lt;h2&gt;
  
  
  What makes a tiered pricing model work?
&lt;/h2&gt;

&lt;p&gt;A tier model works when each tier maps to a real customer segment, limits are set from observed usage rather than invented, features are placed by value rather than by what's easy to gate, and the whole thing is stored as data so changing it doesn't require a release. The pricing page is the visible half. The entitlement system is the half that decides whether you can iterate.&lt;/p&gt;

&lt;h2&gt;
  
  
  The design constraints
&lt;/h2&gt;

&lt;h3&gt;
  
  
  A value metric that tracks customer outcomes
&lt;/h3&gt;

&lt;p&gt;The number that separates tiers should be something a customer can predict and something that grows as they get more value from the product. API calls, active users, projects, or messages processed all work. Anything a customer can't estimate before signing up will be estimated wrong, and the correction arrives as a support ticket.&lt;/p&gt;

&lt;h3&gt;
  
  
  Feature placement that doesn't feel punitive
&lt;/h3&gt;

&lt;p&gt;Do not gate things customers expect at any paid level. Locking a basic capability behind an upgrade reads as a tax rather than a feature, and it produces complaints instead of conversions. Reserve gating for capabilities that genuinely cost more to deliver or that only matter at scale.&lt;/p&gt;

&lt;p&gt;A useful split:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Table stakes.&lt;/strong&gt; Available on every paid plan. Gating these costs more goodwill than it earns revenue.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High impact.&lt;/strong&gt; Capabilities that matter once a customer is scaling. These belong to the middle and top tiers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security, control, and integrations.&lt;/strong&gt; SSO, audit logs, role-based access, private deployment. These map to the buyer at the top tier and are the usual reason they're there.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Limits derived from actual usage
&lt;/h3&gt;

&lt;p&gt;Set limits from your usage distribution, not from round numbers. A limit that sits where real customers naturally cross it produces upgrades that feel earned. A limit set arbitrarily below where people work produces churn and a reputation for nickel-and-diming.&lt;/p&gt;

&lt;p&gt;Whatever you pick, warn before the wall. A customer who gets told at 80% has time to decide. A customer who finds out at 100% has an outage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tiers that mirror segments
&lt;/h3&gt;

&lt;p&gt;Three tiers covers most products, because each one should answer a different buyer.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free or Starter.&lt;/strong&gt; Limited but genuinely functional. Its job is to let someone succeed once.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Growth or Pro.&lt;/strong&gt; The default choice and the main revenue line. Priced and packaged for the segment you actually serve.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advanced or Enterprise.&lt;/strong&gt; High scale, negotiated terms, security and control requirements.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If a tier can't be described in one sentence with a named buyer, it's an internal artifact rather than a plan.&lt;/p&gt;

&lt;h3&gt;
  
  
  Price ratios that read at a glance
&lt;/h3&gt;

&lt;p&gt;Simple multiples make progression legible. Starter at 1x, Growth at 2x to 3x, Advanced at 4x to 5x is a common shape because a buyer can compare the steps without doing arithmetic. Random gaps make the page feel arbitrary even when the numbers are well reasoned.&lt;/p&gt;

&lt;h3&gt;
  
  
  Support as part of the package
&lt;/h3&gt;

&lt;p&gt;Response times and support channels are frequently the reason a larger customer moves up a tier, and they're cheaper to differentiate than features are. Make the difference explicit on the page rather than implied.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building it: seven steps
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Name the objective.&lt;/strong&gt; Higher ARPU, cleaner segmentation, or less sales friction. These pull in different directions, so pick one to optimize. Vague goals produce tiers that are defensible in a meeting and confusing on a pricing page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Segment, then pick the metric.&lt;/strong&gt; Three or four segments based on real usage maturity. Talk to customers in each about what they rely on and what they'd pay more for.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Design three tiers with clear roles.&lt;/strong&gt; Each needs a target user, a purpose, and an upgrade trigger you can point at in the data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Place features and limits deliberately.&lt;/strong&gt; Map every feature to table stakes, high impact, or control. Tie limits to the value metric so customers graduate by growing rather than by hitting a wall.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Price from value, bounded by cost.&lt;/strong&gt; Your floor is the unit cost plus the margin you need. Your ceiling is the value the product delivers to your largest customers. Pick inside that range and validate against current accounts before publishing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Ship it as configuration.&lt;/strong&gt; This is the step that decides how much the next five changes cost. More below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Watch behaviour and iterate.&lt;/strong&gt; Track signups, upgrades, downgrades, limit hits, and support volume per tier. If Growth takes every upgrade and Advanced sits unused, the feature split is wrong. If customers hit a limit in week one, the limit is wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  The implementation that decides whether you can iterate
&lt;/h2&gt;

&lt;p&gt;A tier is two things in the system: a set of prices, and a set of entitlements that the product checks at runtime.&lt;/p&gt;

&lt;p&gt;The prices are the easy half. The entitlements are where teams paint themselves into a corner, usually by encoding the plan in application code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# The version that guarantees a sprint per pricing change
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plan&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pro&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;max_projects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plan&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;enterprise&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;max_projects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;max_projects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every limit change is a deploy. Every new plan touches every service holding one of these blocks. A one-off limit for a negotiated deal is either a hardcoded special case or a fourth plan nobody wanted.&lt;/p&gt;

&lt;p&gt;The alternative is to treat entitlements as data the product reads:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--request&lt;/span&gt; GET &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--url&lt;/span&gt; &lt;span class="s1"&gt;'https://api.cloud.flexprice.io/v1/customers/external/cust_123/entitlements'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'x-api-key: &amp;lt;your_api_key&amp;gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the &lt;a href="https://docs.flexprice.io/api-reference/customers/get-customer-entitlements-by-external-id" rel="noopener noreferrer"&gt;customer entitlements endpoint&lt;/a&gt;, keyed by your own customer identifier so the gate can run at the edge. Swap the host for &lt;code&gt;us.api.flexprice.io&lt;/code&gt; on the US region. The plan defines the grant, the customer's subscription resolves to a set of entitlements, and the product asks what this customer is allowed to do rather than inferring it from a plan name. Changing a limit becomes a configuration change that takes effect without a release, and raising a limit for one account is an override rather than a new SKU.&lt;/p&gt;

&lt;p&gt;In Flexprice the primitive is an entitlement: a feature linked to a plan with its usage limit configured there rather than in your services. &lt;a href="https://docs.flexprice.io/docs/product-catalogue/features/linking-to-plans" rel="noopener noreferrer"&gt;Linking features to plans&lt;/a&gt; covers how a tier gets assembled that way, and &lt;a href="https://docs.flexprice.io/docs/product-catalogue/plans/price-overrides" rel="noopener noreferrer"&gt;price overrides&lt;/a&gt; handle a negotiated deal at subscription creation without cloning the plan.&lt;/p&gt;

&lt;p&gt;If a per-billing-period limit is too coarse, &lt;a href="https://docs.flexprice.io/docs/product-catalogue/features/entitlement-grants" rel="noopener noreferrer"&gt;entitlement grants&lt;/a&gt; turn it into a quota per window, something like 1M tokens per 5 hours, independent of the billing cycle. Windows can stack, a webhook fires when a quota is exhausted, and usage past it bills as overage.&lt;/p&gt;

&lt;p&gt;Usage limits also need real-time enforcement to be worth anything. A quota evaluated by a nightly job can be exceeded all day. That means the check sits in the request path with a latency budget, which is a reason to keep the entitlement lookup a cached read rather than a computation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why tiered pricing changed SaaS monetization
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Revenue tracks customer growth.&lt;/strong&gt; Flat pricing charges the same whether a customer barely logs in or runs your product as core infrastructure. Once usage varies widely across the base, one price is wrong for almost everyone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One model serves both ends.&lt;/strong&gt; Self-serve buyers want predictability and no surprises. Enterprise buyers want flexibility, control, and security. Tiers serve both without splitting the product into two.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Expansion happens without a sales motion.&lt;/strong&gt; When tiers match customer maturity, the upgrade happens because the product got more important to their workflow. That's a very different conversation from an upgrade triggered by hitting a wall.&lt;/p&gt;

&lt;p&gt;All three depend on the same thing: the ability to change the model without a release cycle. If moving a feature between plans requires engineering time, the pricing stops evolving and the packaging drifts away from the product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Flexprice fits
&lt;/h2&gt;

&lt;p&gt;Flexprice is enterprise-grade, open source usage based billing infrastructure for AI and SaaS companies. It can be deployed in your own VPC, on-prem, or on Flexprice's managed cloud.&lt;/p&gt;

&lt;p&gt;For tiered pricing specifically, that means plans, prices, limits, and entitlements live as configuration the product queries, so a packaging change doesn't touch your services. Tiers also compose with usage-based charges, credit wallets, and negotiated enterprise terms on the same subscription, which matters when the three-tier page stops being enough.&lt;/p&gt;

&lt;p&gt;Read &lt;a href="https://docs.flexprice.io/docs/product-catalogue/plans/create" rel="noopener noreferrer"&gt;Creating a plan&lt;/a&gt; to see the shape of a tier before deciding how to model yours.&lt;/p&gt;

</description>
      <category>saas</category>
      <category>billing</category>
      <category>api</category>
      <category>startup</category>
    </item>
    <item>
      <title>How to choose enterprise billing software</title>
      <dc:creator>Flexprice</dc:creator>
      <pubDate>Mon, 21 Sep 2026 15:31:05 +0000</pubDate>
      <link>https://dev.to/flexprice_8116ed925/how-to-choose-enterprise-billing-software-4b7</link>
      <guid>https://dev.to/flexprice_8116ed925/how-to-choose-enterprise-billing-software-4b7</guid>
      <description>&lt;p&gt;A billing setup built for self-serve SaaS usually survives until the first real enterprise contract. Then a deal arrives with a multi-period ramp, a custom credit grant, a committed usage floor, and a quarterly true-up, and a clean subscription setup turns into scripts, spreadsheets, and engineering tickets.&lt;/p&gt;

&lt;p&gt;The compounding is the problem. Finance ends up in Excel, engineering writes more billing code than product code, and by year two the question stops being whether to switch platforms and becomes how to switch without breaking revenue recognition.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is enterprise billing software?
&lt;/h2&gt;

&lt;p&gt;Enterprise billing software is a cloud or self-hosted platform that handles invoicing, contract management, usage metering, subscription lifecycle, and revenue recognition at enterprise scale. It's the system of record for every dollar invoiced, every event consumed, and every line item an auditor will read at close.&lt;/p&gt;

&lt;p&gt;The difference from a standard billing tool shows up the moment you sign a contract that doesn't look like a credit card checkout. Enterprise billing has to handle high-volume event processing, negotiated contracts with ramps and commitments, audit trails that satisfy ASC 606, IFRS 15, and SOC 2, and role-based access for finance, sales, engineering, and external auditors at the same time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The features your shortlist has to clear
&lt;/h2&gt;

&lt;p&gt;Skip any of these and your engineers write the missing piece while finance backfills the rest in spreadsheets.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phased contracts
&lt;/h3&gt;

&lt;p&gt;Enterprise deals aren't monthly subscriptions. The platform has to model ramps across periods, free months at the start, step-up commitments tied to fiscal milestones, mid-term escalators, and scheduled price changes that roll automatically.&lt;/p&gt;

&lt;p&gt;A concrete test for any vendor: ask them to model a 24-month contract at $50K in year one, $100K in year two, with the first month free. If that needs a custom script or a professional services engagement, it will need one for every enterprise customer you close afterwards.&lt;/p&gt;

&lt;h3&gt;
  
  
  Real-time event metering
&lt;/h3&gt;

&lt;p&gt;If you charge for usage, metering is where revenue is either captured or lost. What matters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ingestion with a documented throughput profile.&lt;/li&gt;
&lt;li&gt;Idempotent event APIs, so retries don't double count.&lt;/li&gt;
&lt;li&gt;Deduplication by event ID.&lt;/li&gt;
&lt;li&gt;Configurable aggregation including sum, count, max, average, and unique values.&lt;/li&gt;
&lt;li&gt;Defined handling for late-arriving events, retroactive corrections, and replay.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Throughput is the easy question and the one every vendor is ready for. The edge cases matter more: if a late event or a replay needs a support ticket each time, you've hired a full-time engineer to babysit billing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dunning workflows
&lt;/h3&gt;

&lt;p&gt;Failed payments are a meaningful share of churn at most subscription businesses, and the recoverable portion depends almost entirely on the retry logic.&lt;/p&gt;

&lt;p&gt;A real dunning engine lets you configure retry schedules, commonly day 0, 3, 7, and 14, with a tighter cadence for high-value accounts. Smart retries adapt to the decline code, so insufficient funds and a fraud block get handled differently.&lt;/p&gt;

&lt;p&gt;Beyond retries, look for pre-dunning notifications such as card-expiring and low-balance warnings, branded sequences segmented by customer tier, account-state thresholds that decide when a failure triggers a pause or a suspension, and webhook events at every state transition so customer success can intervene on the accounts worth intervening on.&lt;/p&gt;

&lt;p&gt;The red flag is a global-only setup. If you can't run different recovery flows for a $500K account and a $5K account, you're leaving money on the table every month.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compliance and security
&lt;/h3&gt;

&lt;p&gt;Your billing platform holds payment details, contract values, usage records, and revenue numbers. Treat security as a first-order buying criterion rather than a procurement checkbox at the end of the cycle.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SOC 2 Type II.&lt;/strong&gt; A current report, not Type I and not "in progress". Type I confirms the policies exist. Type II confirms an auditor verified the controls operated over a period.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ISO 27001.&lt;/strong&gt; Often required by EU and APAC procurement alongside SOC 2.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PCI DSS Level 1.&lt;/strong&gt; Required if the platform touches card data anywhere, including through a tokenization handoff.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HIPAA.&lt;/strong&gt; Required for healthcare, with a signed BAA rather than a claim of alignment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GDPR and CCPA.&lt;/strong&gt; Required for European or California customers, with a DPA available without an enterprise upsell.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most useful question in a security conversation: can you see the most recent SOC 2 Type II report and the latest pen test executive summary under NDA? Hesitation, a redirect to a marketing page, or a stall until the order form is signed all answer the question.&lt;/p&gt;

&lt;h3&gt;
  
  
  Audit trails
&lt;/h3&gt;

&lt;p&gt;Every change to a price, plan, invoice, contract, or customer record should leave a timestamped, immutable record of who changed what and when. This is the floor for SOC 2 and the first artifact you reach for when someone asks why a customer was billed $40K more than expected.&lt;/p&gt;

&lt;p&gt;Look for separation of duties between price setters and approvers, approval workflows on high-value changes, and log storage that platform admins can't edit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Entitlements
&lt;/h3&gt;

&lt;p&gt;Pricing decides what a customer pays. Entitlements decide what they can use. They're the same decision, and a platform should treat them that way, with real-time checks the product calls directly rather than the same logic maintained across three services.&lt;/p&gt;

&lt;p&gt;Questions worth asking during evaluation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What happens when a customer hits a hard limit mid-period: block, throttle, queue, or convert to overage?&lt;/li&gt;
&lt;li&gt;Can entitlements aggregate across multiple subscriptions under one parent customer?&lt;/li&gt;
&lt;li&gt;Can sales grant a per-customer entitlement bump without modifying the plan?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  APIs, webhooks, and SDKs
&lt;/h3&gt;

&lt;p&gt;Treat the developer surface as a buying criterion. Every action available in the UI should exist in a versioned, documented API.&lt;/p&gt;

&lt;p&gt;Webhooks specifically need at-least-once delivery with retries, signed payloads, documented event schemas, and a test mode that mirrors production. Flexprice documents its &lt;a href="https://docs.flexprice.io/docs/webhook/webhooks" rel="noopener noreferrer"&gt;webhook behaviour&lt;/a&gt;, and also exposes the API through an &lt;a href="https://docs.flexprice.io/docs/connect/mcp-server" rel="noopener noreferrer"&gt;MCP server&lt;/a&gt; if your team works from an editor or agent.&lt;/p&gt;

&lt;p&gt;A rate-limited API with partial coverage is the clearest signal that the UI is the real product, and you'll hit that wall within six months of building on it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-currency
&lt;/h3&gt;

&lt;p&gt;Native multi-currency means the pricing table maps each tier to amounts per currency, version controlled and dated. Enterprise deals usually lock a negotiated currency while self-serve runs on rates that refresh on a schedule.&lt;/p&gt;

&lt;p&gt;At the accounting layer, the platform should load FX rates from a trusted source, revalue foreign-currency balances at close, and post unrealized gain or loss automatically. If revaluation isn't part of the close workflow, finance is doing it in Excel and the errors compound quarterly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-entity
&lt;/h3&gt;

&lt;p&gt;Billing the same customers from a US, UK, and APAC entity means each needs its own tax profile, invoice number sequence, revenue recognition schedule, payment processor, and permissions.&lt;/p&gt;

&lt;p&gt;Intercompany is the harder half. Ask for a live demo of one parent customer with subscriptions billed by two entities, with intercompany allocation and a consolidated view. If it can't be shown live, it doesn't exist.&lt;/p&gt;

&lt;h3&gt;
  
  
  Transparent metering for customers
&lt;/h3&gt;

&lt;p&gt;Surprise invoices are the main escalation trigger on usage-priced products. A metering UI that shows the customer how the bill was calculated is the cheapest support investment available.&lt;/p&gt;

&lt;p&gt;Look for a live consumption view with projected end-of-period totals, drill-down from a line item back to the underlying events, alerts at configurable thresholds, and a usage API so you can render the same data inside your own product.&lt;/p&gt;

&lt;h3&gt;
  
  
  Contract overrides
&lt;/h3&gt;

&lt;p&gt;No two enterprise contracts are identical, so prices, commitments, credits, payment terms, and billing cycles all need contract-level overrides. Cloning an entire plan for every slightly different deal produces a plan catalogue nobody can reason about within a year. &lt;a href="https://docs.flexprice.io/docs/product-catalogue/plans/price-overrides" rel="noopener noreferrer"&gt;Price overrides&lt;/a&gt; should be something sales can apply for standard cases without engineering.&lt;/p&gt;

&lt;h3&gt;
  
  
  Correct invoices
&lt;/h3&gt;

&lt;p&gt;The minimum set: branded templates with multi-language and multi-currency support, attached usage breakdowns, PDF generation tied to the billing cycle, configurable payment terms, sequential numbering with legal integrity, and clean credit note and reissue flows.&lt;/p&gt;

&lt;p&gt;For global rollouts, e-invoicing formats matter more every quarter. UBL, Factur-X, Peppol, and country-specific mandates such as Italy's SDI, Mexico's CFDI, and India's IRP are increasingly required by tax authorities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Integrations
&lt;/h3&gt;

&lt;p&gt;Billing data has to reach the CRM, ERP, warehouse, close tools, and product analytics. The minimum connector list for an enterprise shortlist covers Salesforce and HubSpot, NetSuite, QuickBooks and Sage Intacct, Stripe and other processors, a tax engine, and Snowflake or BigQuery.&lt;/p&gt;

&lt;h3&gt;
  
  
  Support
&lt;/h3&gt;

&lt;p&gt;At the enterprise tier, expect a named contact, a shared channel, a defined P0 response time, a documented escalation path, and post-incident root cause documents you can forward to finance.&lt;/p&gt;

&lt;p&gt;Don't ask whether enterprise support is offered. Ask what happens at 11pm when the automated invoice run fails for 800 customers. The specificity of the answer tells you what you're buying.&lt;/p&gt;

&lt;h3&gt;
  
  
  Grandfathered pricing
&lt;/h3&gt;

&lt;p&gt;When public pricing rises, existing customers stay on their old terms, and that has to be a first-class concept rather than tags and a spreadsheet. Look for explicit price versioning, the ability to lock a subscription to its start-date pricing, and a clean migration path when you decide to move legacy customers forward.&lt;/p&gt;

&lt;h3&gt;
  
  
  Credits and wallets
&lt;/h3&gt;

&lt;p&gt;AI and agentic products need first-class credit handling: one-off and recurring grants, scheduled refresh, rollover with caps, auto top-up below a threshold, expiration tied to time or usage, and a unified balance across credit types. This is the largest gap in legacy enterprise billing systems, so it deserves a live demo rather than a slide. &lt;a href="https://docs.flexprice.io/docs/wallet/prepaid-and-promotional" rel="noopener noreferrer"&gt;Prepaid and promotional credits&lt;/a&gt; covers the model.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parent-child accounts
&lt;/h3&gt;

&lt;p&gt;One parent account with sub-accounts beneath it, shared credits, pooled usage, and a roll-up invoice at the top. This becomes necessary the moment a customer expands across departments, which healthy accounts do inside the first year.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quotes and renewals
&lt;/h3&gt;

&lt;p&gt;Enterprise sales doesn't start at a checkout page. Built-in quoting needs pricing lock-in from quote to subscription, approval workflows for non-standard terms, and automatic sync from an accepted quote to an active subscription.&lt;/p&gt;

&lt;h2&gt;
  
  
  Five lenses for evaluating vendors
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Stability.&lt;/strong&gt; Migrating between billing platforms is a multi-quarter project, so vendor longevity is a real risk. Check funding, product velocity, and current reviews rather than the case studies on the homepage. An acquisition also counts here, because a roadmap inside a larger company answers to different priorities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Regulatory posture.&lt;/strong&gt; Certifications are the floor. The real test is whether they'll share a pen test summary under NDA, sign your DPA without an upsell, and let your security team talk to theirs before you sign.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your customers' billing experience.&lt;/strong&gt; Ask to see a real invoice and a live customer portal in the demo. If your customer can't self-serve usage, payments, and seats without filing a ticket, that cost lands on your support team.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pricing transparency and total cost.&lt;/strong&gt; Insist on public tiers, model a month-12 invoice against your projected volume, and build a multi-year total that includes implementation fees, connector add-ons, support tier upgrades, and the engineering hours your team will spend filling product gaps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data ownership and extensibility.&lt;/strong&gt; Self-hosting and open source are the strongest forms of data ownership, and the option has value at renewal even if you never exercise it. Check whether your team can write custom pricing or dunning logic without waiting two quarters for a feature request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Flexprice fits
&lt;/h2&gt;

&lt;p&gt;Flexprice is enterprise-grade, open source usage based billing infrastructure for AI and SaaS companies. It can be deployed in your own VPC, on-prem, or on Flexprice's managed cloud. Flexprice offers three deployment options, and all three run the same engine.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Your VPC.&lt;/strong&gt; Deployed inside your own virtual private cloud on AWS, Azure, or GCP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On-prem.&lt;/strong&gt; Deployed inside your own data centre, in any geography.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexprice cloud.&lt;/strong&gt; Fully managed by Flexprice, for teams that do not want to operate it themselves.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because Flexprice is open source and self-hostable, usage and revenue data can stay entirely inside your own infrastructure and never reach a vendor's cloud. This is what makes Flexprice usable by companies with data residency, sovereignty, and audit requirements that hosted-only billing vendors cannot meet.&lt;/p&gt;

&lt;p&gt;On the evaluation lenses above, here is the specific detail rather than the claim.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data ownership.&lt;/strong&gt; The metering, pricing, and invoicing logic is readable on GitHub before you deploy anything. Self-hosting that build is free, and the stack it runs on is PostgreSQL as the system of record, Kafka as the event backbone, ClickHouse as the event store, and Temporal for durable billing workflows, all inside your own environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pricing transparency.&lt;/strong&gt; Three tiers carry published prices and one is quoted: Basic is free at 100K events a month, Build is $500 a month at 1M events, Scale is $1,000 a month at 5M events, and Mission Critical is custom. Yearly billing takes 20% off the paid plans. Pricing is flat per plan rather than a share of your revenue, with a separate mechanism worth reading closely: each tier carries a cumulative billing revenue cap, $100K on Basic, $250K or $20K monthly on Build, $1.2M or $100K monthly on Scale, and unlimited on Mission Critical. Model where your own volume lands against both the event count and the revenue cap, because they bind independently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compliance.&lt;/strong&gt; Flexprice holds SOC 2 Type II, GDPR, and ISO 27001 as a company. Read the plan detail before you quote it internally: SOC 2 Type 2, SAML SSO and SCIM, multi-role permissions, and managed VPC or on-premise deployment sit on the Mission Critical tier. A SOC 2 report also certifies Flexprice as an operator, so a build you self-host is not covered by it, and your own auditors will treat that deployment as yours. The contractual SLA is 99.9% with 99.99% HA options from Build upward.&lt;/p&gt;

&lt;p&gt;The comparison that matters most at this stage is against closed, vendor-hosted platforms. Metronome, Orb, and m3ter are closed source and vendor-hosted. Flexprice is open source and deploys inside your own VPC or on-prem, so usage and revenue data never has to leave your infrastructure.&lt;/p&gt;

&lt;p&gt;Read the &lt;a href="https://docs.flexprice.io/docs/getting-started/self-hosting-guide" rel="noopener noreferrer"&gt;self-hosting guide&lt;/a&gt; if you want to run it against your own contract structures before talking to anyone.&lt;/p&gt;

</description>
      <category>billing</category>
      <category>saas</category>
      <category>architecture</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How to calculate customer usage for billing</title>
      <dc:creator>Flexprice</dc:creator>
      <pubDate>Mon, 21 Sep 2026 15:21:23 +0000</pubDate>
      <link>https://dev.to/flexprice_8116ed925/how-to-calculate-customer-usage-for-billing-2ej6</link>
      <guid>https://dev.to/flexprice_8116ed925/how-to-calculate-customer-usage-for-billing-2ej6</guid>
      <description>&lt;p&gt;A customer opens their invoice and asks why it's higher than last month. Answering that question requires tracing a number on a PDF back through pricing rules, entitlement deductions, an aggregation window, and a stream of raw events your product emitted days ago. If any step in that chain is undocumented or non-deterministic, the honest answer is that you don't know.&lt;/p&gt;

&lt;p&gt;Usage calculation is the chain that makes that question answerable. It runs from a raw event to a priced line item, and each step changes the number.&lt;/p&gt;

&lt;h2&gt;
  
  
  How is customer usage calculated for billing?
&lt;/h2&gt;

&lt;p&gt;Usage is calculated by defining a billable unit, cleaning the raw event stream, aggregating events into a quantity per customer per period, applying plan pricing to that quantity, and writing a billable record that shows the quantity, the rate, and the resulting charge. The invoice is assembled from those records.&lt;/p&gt;

&lt;p&gt;Seven steps, in order.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Define the billable unit
&lt;/h2&gt;

&lt;p&gt;The billable unit is the thing you count. It decides your pricing, your customer's mental model of the product, and how much explaining an invoice needs.&lt;/p&gt;

&lt;p&gt;Common units in AI and infrastructure products:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;API calls.&lt;/strong&gt; One request, one unit. Easy to measure and easy to explain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tokens.&lt;/strong&gt; Works for language model products, but only if customers understand what a token is. If they don't, you inherit that explanation in every support thread.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compute minutes or GPU hours.&lt;/strong&gt; Reasonable when cost tracks time on hardware.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unique agents or sessions.&lt;/strong&gt; Counts distinct things active in a period rather than total volume.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pick a unit your team can measure precisely and a customer can predict. A unit that's cheap to compute but abstract to the buyer will cost you more in support than it saves in engineering.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Pre-process the raw usage data
&lt;/h2&gt;

&lt;p&gt;Products emit logs, traces, and request records, not billing summaries. Before anything is counted, the stream has to be shaped.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attribute every event.&lt;/strong&gt; Group by customer, and tag with product, feature, or SKU so pricing can be applied selectively later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resolve account hierarchies.&lt;/strong&gt; If one contract covers several teams or subsidiaries, usage may need to pool to a parent for billing while still reporting separately per child.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Filter what should not be billed.&lt;/strong&gt; Internal test traffic, sandbox environments, and failed requests usually shouldn't count. Write those rules down, because they'll be questioned during an audit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Subtract included allowances.&lt;/strong&gt; A plan that includes 100,000 tokens a month removes those before charging begins, and the allowance usually resets on the billing period.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Normalize units.&lt;/strong&gt; You may meter in seconds and bill in minutes, or meter per event and bill in blocks of 10,000. Rounding direction is a pricing decision, so make it explicit rather than inheriting whatever the language does.&lt;/p&gt;

&lt;p&gt;This step is unglamorous and it's where most silent revenue leakage starts.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Aggregate usage
&lt;/h2&gt;

&lt;p&gt;Aggregation converts many events into one quantity. The function you choose has to match how the product delivers value.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Strategy&lt;/th&gt;
&lt;th&gt;Produces&lt;/th&gt;
&lt;th&gt;Fits&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Sum&lt;/td&gt;
&lt;td&gt;Total of a property across events&lt;/td&gt;
&lt;td&gt;API calls, tokens, compute seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Count&lt;/td&gt;
&lt;td&gt;Number of events&lt;/td&gt;
&lt;td&gt;Requests, jobs run&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Count unique&lt;/td&gt;
&lt;td&gt;Distinct values of a property&lt;/td&gt;
&lt;td&gt;Active users, agents deployed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Latest&lt;/td&gt;
&lt;td&gt;Most recent value in the period&lt;/td&gt;
&lt;td&gt;Seat count, concurrent sessions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Max&lt;/td&gt;
&lt;td&gt;Highest value seen&lt;/td&gt;
&lt;td&gt;Peak concurrency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sum with multiplier&lt;/td&gt;
&lt;td&gt;Summed property scaled by a rate&lt;/td&gt;
&lt;td&gt;Tokens weighted by model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Weighted sum&lt;/td&gt;
&lt;td&gt;Time-proportional total&lt;/td&gt;
&lt;td&gt;Capacity held over a period&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Defaulting to sum because it's easy will show up later as a pricing model that doesn't match what customers think they're buying. Flexprice exposes these as configuration on a metered feature rather than code, and the &lt;a href="https://docs.flexprice.io/docs/product-catalogue/features/aggregation/overview" rel="noopener noreferrer"&gt;aggregation reference&lt;/a&gt; covers the behaviour of each one.&lt;/p&gt;

&lt;p&gt;The event carries whatever the aggregation needs to read:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"model.usage"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"external_customer_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cust_123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1840&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gpt-4"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"evt_9f2c1a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-08-22T07:05:49.441Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;event_id&lt;/code&gt; is optional in the payload and worth setting anyway. It's what lets a retried request resolve to one billable event instead of two.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Apply pricing logic
&lt;/h2&gt;

&lt;p&gt;Pricing is not quantity times rate. It's quantity evaluated against the rules attached to that customer's plan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Plan rules first.&lt;/strong&gt; Check what plan the customer is on and what it includes before pricing anything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tiers.&lt;/strong&gt; Say the rate is $0.002 for the first million units and $0.001 after that. There are two legitimate ways to read those tiers, and they produce different invoices.&lt;/p&gt;

&lt;p&gt;Under &lt;strong&gt;slab&lt;/strong&gt; (also called graduated) pricing, usage is split at the boundary and each slice is priced at its own rate. Under &lt;strong&gt;volume&lt;/strong&gt; pricing, the total lands in one tier and the whole quantity is priced at that tier's rate. For 1.5M units, slab gives $2,500 and volume gives $1,500. Neither is wrong, but picking one by accident is, and this is where hand-rolled billing code tends to disagree with the pricing page.&lt;/p&gt;

&lt;p&gt;Flexprice makes this an explicit flag rather than an assumption. A price with &lt;code&gt;billing_model: TIERED&lt;/code&gt; carries a &lt;code&gt;tier_mode&lt;/code&gt; of either &lt;code&gt;SLAB&lt;/code&gt; or &lt;code&gt;VOLUME&lt;/code&gt;. The &lt;a href="https://docs.flexprice.io/docs/product-catalogue/plans/billing-models/volume-tiered" rel="noopener noreferrer"&gt;volume tiered&lt;/a&gt; doc walks through the volume case, where 65,000 calls priced against a tier ending at 100,000 at $0.0006 bills as 65,000 x $0.0006 = $39 rather than accumulating the cheaper earlier tiers.&lt;/p&gt;

&lt;p&gt;Slab is the mode the function below implements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;price_tiered&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tiers&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Slab/graduated: each slice priced at its own rate.
    tiers: list of (up_to, rate); up_to=None means unbounded.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;
    &lt;span class="n"&gt;remaining&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;
    &lt;span class="n"&gt;previous&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;up_to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rate&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tiers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;remaining&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;up_to&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;remaining&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;up_to&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;previous&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;
        &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;rate&lt;/span&gt;
        &lt;span class="n"&gt;remaining&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;span&lt;/span&gt;
        &lt;span class="n"&gt;previous&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;up_to&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;up_to&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;previous&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;

&lt;span class="nf"&gt;price_tiered&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1_500_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="mi"&gt;1_000_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.002&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.001&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;
&lt;span class="c1"&gt;# 2500.0
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whichever mode you pick, state it on the pricing page in the customer's terms. "You pay $0.001 on everything once you pass a million" and "the first million stays at $0.002" describe different bills.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Minimums and caps.&lt;/strong&gt; Some contracts carry a monthly minimum or a spend ceiling. Both are applied after usage is priced, and both change the total.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time splits.&lt;/strong&gt; If the plan changed mid-period, the period splits and each segment prices at the rate in effect then. Upgrades, downgrades, and price changes all land here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Currency and tax.&lt;/strong&gt; Both belong inside the pricing step. Treating them as post-processing on a finished total tends to produce rounding that doesn't reconcile.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Generate billable records
&lt;/h2&gt;

&lt;p&gt;A billable record is the row that explains a line on the invoice. It's what you show a customer who disputes a charge.&lt;/p&gt;

&lt;p&gt;Each record should carry the customer identifier, the product or feature, the billing period, the billable quantity after entitlements, the rate or rates applied, and the final charge.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"customer_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cust_123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"feature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"model.usage"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"period"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-08-01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-08-31"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"billable_quantity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1500000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"unit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tokens"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tier_mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SLAB"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rates"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"up_to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1000000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"rate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.002&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"up_to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"rate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.001&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2500.00&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the record can't reproduce the charge on its own, invoicing, collections, and revenue recognition all become brittle downstream.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Store and sync the records
&lt;/h2&gt;

&lt;p&gt;Billable records are ledger data, not scratch output.&lt;/p&gt;

&lt;p&gt;Keep them in a durable, auditable store that acts as the single source of truth for usage charges. Invoicing reads from it rather than recomputing. Finance systems sync from it so month-end reconciliation is a comparison rather than an investigation. Customer dashboards read from it so a user can trace a charge to their own activity without opening a ticket. Every adjustment, whether a credit, a correction, or a late-arriving event, gets logged so the number is explainable a year later.&lt;/p&gt;

&lt;p&gt;Flexprice documents the order in which credits, discounts, and taxes are applied in &lt;a href="https://docs.flexprice.io/docs/invoices/calculation" rel="noopener noreferrer"&gt;Invoice Calculation Order&lt;/a&gt;, which is the part most often reverse-engineered from an invoice.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Backtest and iterate
&lt;/h2&gt;

&lt;p&gt;A billing cycle closing is the start of the feedback loop, not the end of it.&lt;/p&gt;

&lt;p&gt;Re-run past usage against a proposed pricing change before shipping it. You'll see where revenue would have moved and which customers would have been surprised. Investigate invoices that spiked, because those usually expose an aggregation edge case rather than a customer behaviour change. Look for events you're emitting but not billing, which is revenue leakage that no alert will tell you about. Then feed usage patterns back to the people making pricing decisions, since high usage and high revenue are frequently not the same customers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Flexprice fits
&lt;/h2&gt;

&lt;p&gt;Flexprice is enterprise-grade, open source usage based billing infrastructure for AI and SaaS companies. It can be deployed in your own VPC, on-prem, or on Flexprice's managed cloud.&lt;/p&gt;

&lt;p&gt;It implements the chain above as configuration: a &lt;a href="https://docs.flexprice.io/docs/event-ingestion/creating-a-metered-feature" rel="noopener noreferrer"&gt;metered feature&lt;/a&gt; defines the event name and aggregation, prices attach to that feature on a plan, wallets and credit grants draw down against the result, and invoices assemble from the billable records. Because it's open source and self-hostable, usage and revenue data can stay entirely inside your own infrastructure and never reach a vendor's cloud.&lt;/p&gt;

&lt;p&gt;Run it locally and push a few events through the chain before deciding whether to build it yourself: &lt;a href="https://github.com/flexprice/flexprice" rel="noopener noreferrer"&gt;github.com/flexprice/flexprice&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>billing</category>
      <category>api</category>
      <category>saas</category>
      <category>architecture</category>
    </item>
    <item>
      <title>How to automate subscription billing workflows</title>
      <dc:creator>Flexprice</dc:creator>
      <pubDate>Mon, 21 Sep 2026 15:14:51 +0000</pubDate>
      <link>https://dev.to/flexprice_8116ed925/how-to-automate-subscription-billing-workflows-3dh6</link>
      <guid>https://dev.to/flexprice_8116ed925/how-to-automate-subscription-billing-workflows-3dh6</guid>
      <description>&lt;p&gt;Most billing systems start as a cron job that reads a table and creates invoices. That works until usage enters the picture, then credits, then mid-cycle plan changes, then a webhook that silently fails on a Friday and takes two people a day to unwind.&lt;/p&gt;

&lt;p&gt;The fix is not a better cron job. It's making billing deterministic: every state change emits an event, every event is idempotent, and every number on an invoice traces back to a stored record rather than a recomputation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does automating subscription billing actually mean?
&lt;/h2&gt;

&lt;p&gt;It means every billing event triggers the next step without a person in the loop, across six layers that each do one job. Subscription management holds plan state and renewal schedules. Metering records consumption. Rating converts usage into money. Invoicing assembles and posts documents. Payments collect and retry. Entitlements keep product access matched to what was paid for.&lt;/p&gt;

&lt;p&gt;Each layer runs independently and communicates through events. That separation is what lets you change pricing without touching product code, and replay a bad day without hand-editing invoices.&lt;/p&gt;

&lt;p&gt;Here are the thirteen steps, in build order.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Map the workflow from signup to renewal
&lt;/h2&gt;

&lt;p&gt;Before building anything, draw the path a customer takes and mark every point where money or access changes.&lt;/p&gt;

&lt;p&gt;The events that matter: signup, trial start, plan activation, upgrade, downgrade, pause, cancel at period end, renewal at the anchor, usage thresholds crossed, credit grant, top-up, expiry, invoice finalized, payment succeeded, payment failed, refund, credit note.&lt;/p&gt;

&lt;p&gt;Then document where each piece of data originates and where it goes. The product and data pipeline produce usage events. The billing service turns usage into rated lines. Invoicing creates posted documents. The payment provider returns success or failure. Tax and accounting receive posted invoices and settlements.&lt;/p&gt;

&lt;p&gt;Two policy decisions save arguments later. Pick your billing anchor, calendar or anniversary. And pick a finalization window for late usage, so invoices close after a short grace period and anything later becomes an adjustment next cycle.&lt;/p&gt;

&lt;p&gt;Come out of this step with three artifacts: a swimlane diagram of the event flow, an event catalogue with schemas and sample payloads, and a policy sheet covering anchors, proration, late usage, dunning, refunds, and credit notes.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Build on an event-driven backbone
&lt;/h2&gt;

&lt;p&gt;Every meaningful subscription change emits a domain event that other services react to. Flexprice publishes this set for subscriptions: &lt;code&gt;subscription.created&lt;/code&gt;, &lt;code&gt;subscription.updated&lt;/code&gt;, &lt;code&gt;subscription.paused&lt;/code&gt;, &lt;code&gt;subscription.resumed&lt;/code&gt;, and &lt;code&gt;subscription.cancelled&lt;/code&gt;, alongside invoice events such as &lt;code&gt;invoice.create.drafted&lt;/code&gt; and &lt;code&gt;invoice.update.finalized&lt;/code&gt;, and payment events such as &lt;code&gt;payment.success&lt;/code&gt; and &lt;code&gt;payment.failed&lt;/code&gt;. The full list is in the &lt;a href="https://docs.flexprice.io/docs/webhook/webhooks" rel="noopener noreferrer"&gt;webhooks reference&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Whether you consume those or emit your own, each internal event should carry a globally unique idempotency key, event and delivery timestamps in UTC, resource identifiers, and version metadata so consumers know how to parse it. An internal envelope might look like this. It is your own schema, not a provider's payload format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"subscription.updated"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"evt_01HQ8K3M"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"occurred_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-10-27T08:14:02.118Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"customer_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cust_123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"subscription_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sub_998"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"change"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"plan_upgrade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"effective_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-10-27T08:14:02.118Z"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Internally, publish to a queue or stream so consumers get replay and backpressure. Use webhooks for external systems, but do not make an external webhook the only path for anything that affects revenue. A webhook that silently fails is an invoice that silently doesn't exist.&lt;/p&gt;

&lt;p&gt;Every consumer guards against duplicates with an idempotency store keyed on event ID, and handlers are written to be safely reentrant. Store events durably so you can replay a window after an outage, backfill a downstream system, or reconstruct what happened during an incident. When schemas change, version them and support both formats through a migration window rather than breaking consumers.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Meter usage into an append-only ledger
&lt;/h2&gt;

&lt;p&gt;Decide what a unit is: API calls, minutes, storage, messages, GPU seconds. Then define the unit name, the conversion to billing currency, rounding and precision rules, and the measurement window.&lt;/p&gt;

&lt;p&gt;Every usage record carries a unique event identifier, customer and subscription IDs, the metric name and quantity, an event timestamp and a received timestamp, and any properties you might price or group by later.&lt;/p&gt;

&lt;p&gt;Store it append-only. Never overwrite or delete a usage row. Corrections become compensating entries, which is what makes the ledger auditable and what lets you explain a number six months later.&lt;/p&gt;

&lt;p&gt;Late and duplicate data are the two failure modes worth designing for explicitly. Late data is handled by the finalization window from step 1: close the invoice when the window passes and push delayed usage into the next cycle as an adjustment. Duplicates are handled by an idempotency constraint on the event ID.&lt;/p&gt;

&lt;p&gt;Validate on the way in. Drop impossible values, flag missing identifiers, and alert on ingestion lag and abnormal spikes. Preventing a missing event is cheaper than rebuilding trust after an overcharge. &lt;a href="https://docs.flexprice.io/docs/event-ingestion/overview" rel="noopener noreferrer"&gt;Event ingestion&lt;/a&gt; covers the contract and the debugging path.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Rate usage against a versioned price book
&lt;/h2&gt;

&lt;p&gt;Pricing should change without a deploy, which means rates live in data rather than constants.&lt;/p&gt;

&lt;p&gt;A price book entry holds the metric and unit, the rate per unit or per tier, currency and region, any discounts or commitments, and a version ID with effective dates.&lt;/p&gt;

&lt;p&gt;Rating then matches each usage record to the price book version that was in effect at the event's timestamp. Treat rating as a pure function: the same usage and the same price version always produce the same amount. That property is what prevents billing drift after a price change, and it's what makes a disputed invoice reproducible.&lt;/p&gt;

&lt;p&gt;Hybrid pricing runs through the same path. A fixed access fee, metered usage, and credit drawdown all become rated lines, so the invoice assembly logic does not need a special case per pricing model. Apply minimums before overages and deduct credits in a defined order, recording each adjustment in the rated ledger rather than computing it inline.&lt;/p&gt;

&lt;p&gt;Keep rated results in their own store, separate from raw usage: customer ID, metric, applied rate, price version, and subtotal. Invoices regenerate from that without touching the usage ledger.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Automate recurring billing and proration
&lt;/h2&gt;

&lt;p&gt;Each subscription stores its anchor date, renewal type, and next period. That's the trigger for the bill run.&lt;/p&gt;

&lt;p&gt;A scheduled bill run finalizes invoices for every subscription reaching its renewal date, pulling fixed charges, rated usage, and credits within the period. It also handles draft generation, tax and currency calculation, posting the finalized invoice, and creating the payment intent.&lt;/p&gt;

&lt;p&gt;Mid-cycle changes need a proration policy, and there are two workable options. Immediate proration bills the adjustment right away. Deferred proration reflects it on the next invoice. Deferred tends to produce fewer refund requests on usage-priced products, because the customer sees one number instead of three. Pick one and apply it consistently. &lt;a href="https://docs.flexprice.io/docs/subscriptions/understanding-proration" rel="noopener noreferrer"&gt;Understanding proration&lt;/a&gt; covers the mechanics.&lt;/p&gt;

&lt;p&gt;Minimums and overages belong inside the bill run, comparing rated totals against the commitment before finalizing rather than correcting afterwards.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Add a credit system customers can follow
&lt;/h2&gt;

&lt;p&gt;Decide what a credit represents and keep the definition stable across plans: money, units, or access. One credit might be one API call or one minute of processing.&lt;/p&gt;

&lt;p&gt;Track credits like currency, in an append-only ledger. Every grant, spend, and expiry is its own entry carrying the customer and subscription ID, the credit type, quantity, remaining balance, and a reference to the usage event or invoice that caused it.&lt;/p&gt;

&lt;p&gt;Automate the lifecycle: top up when the balance drops below a threshold, expire unused credits on a defined schedule, and notify before expiry rather than after. When an invoice is assembled, credits deduct before usage and recurring fees are charged.&lt;/p&gt;

&lt;p&gt;Then show the balance. Customers who can see what they have left open fewer tickets and get fewer surprises. &lt;a href="https://docs.flexprice.io/docs/wallet/auto-top-up" rel="noopener noreferrer"&gt;Auto top-up&lt;/a&gt; and the wallet balance types cover the configuration side.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Generate invoices from the rated ledger
&lt;/h2&gt;

&lt;p&gt;Invoices read from the rated ledger. They do not run live queries and they do not recalculate, because a recalculation at invoice time is a second implementation of your pricing logic that will eventually disagree with the first.&lt;/p&gt;

&lt;p&gt;For each cycle, assembly fetches fixed charges and add-ons, aggregates rated usage lines in the window, applies credits, discounts, and minimums, then adds tax and totals. Grouping lines by category keeps the document readable during an audit or a customer review.&lt;/p&gt;

&lt;p&gt;Once posted, an invoice is immutable. Corrections appear as credit notes or adjustment lines in the next cycle. Editing a posted invoice is how phantom balances appear in accounting.&lt;/p&gt;

&lt;p&gt;Store enough metadata to reconcile later: invoice and customer IDs, period start and end, currency, tax region and exchange rate, payment status and reference, and the price book version used. &lt;a href="https://docs.flexprice.io/docs/invoices/overview" rel="noopener noreferrer"&gt;Invoices&lt;/a&gt; covers generation, status handling, and payment tracking.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Collect payments with a retry ladder
&lt;/h2&gt;

&lt;p&gt;A finalized invoice creates a payment intent. The system attempts the charge, records success or failure as events, and updates the invoice and customer balance.&lt;/p&gt;

&lt;p&gt;Payment failures are not an edge case, so the retry schedule is part of the design. A common ladder retries after 24 hours, again after 72 hours, and a final attempt at day 7, with access paused or downgraded if it's still unpaid.&lt;/p&gt;

&lt;p&gt;Pair each retry with a message. First failure is a reminder with the retry schedule. Second includes a link to update the payment method. Final attempt warns about the access change. When a retry succeeds, restore access, mark the invoice paid, and confirm, all automatically, so there's no window where a customer has paid and is still blocked.&lt;/p&gt;

&lt;p&gt;Store every payment attempt, gateway reference, and status against the invoice ID. Manual reconciliation stops being feasible somewhere in the low hundreds of accounts.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Sync entitlements the moment money or plan state changes
&lt;/h2&gt;

&lt;p&gt;Entitlements are what the customer can use: features, usage caps, and credit-backed access. They have to move the instant billing state moves, or product access and billing data drift apart.&lt;/p&gt;

&lt;p&gt;Keep entitlements in their own layer rather than inside billing or product code. That layer subscribes to billing events, maintains the current state per customer, and exposes a fast check the product calls in the request path.&lt;/p&gt;

&lt;p&gt;The transitions to automate: payment succeeded activates or extends access, payment failed restricts or pauses, upgrade expands immediately, downgrade or cancellation reduces or revokes. Keep a history of every entitlement change with the triggering event, because that's what you'll need when someone asks why a customer lost access on a Tuesday.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Automate lifecycle communication
&lt;/h2&gt;

&lt;p&gt;Billing that works silently still generates support tickets if customers can't see what's happening.&lt;/p&gt;

&lt;p&gt;Trigger messages on subscription start and renewal, upcoming renewal, invoice issued, payment receipt, payment failure and retry, low or expiring credit balance, plan change confirmation, and trial expiry.&lt;/p&gt;

&lt;p&gt;Send through the channel that fits: email for invoices and receipts, in-app for credit and usage warnings, webhooks for enterprise accounts that want to ingest billing events into their own systems. Keep templates versioned and log delivery status so you can answer what a customer actually received. &lt;a href="https://docs.flexprice.io/docs/webhook/webhooks" rel="noopener noreferrer"&gt;Webhooks&lt;/a&gt; covers the outbound event contract.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Close the loop with tax, accounting, and audit
&lt;/h2&gt;

&lt;p&gt;Automate tax calculation so every invoice carries the jurisdiction and rate, the customer's tax ID and exemption status, and the evidence used to determine location.&lt;/p&gt;

&lt;p&gt;Push every posted invoice and payment to accounting with totals, taxes, status, and recognition schedule. Recognize revenue progressively against the billing period to stay aligned with ASC 606 and IFRS 15.&lt;/p&gt;

&lt;p&gt;Keep immutable logs for every invoice, refund, and adjustment, with timestamps and actor. Reconcile against payment providers on a schedule, matching by invoice ID and posting adjustments for mismatches.&lt;/p&gt;

&lt;h2&gt;
  
  
  12. Monitor and rehearse failure
&lt;/h2&gt;

&lt;p&gt;Automation without observability is a system that fails quietly.&lt;/p&gt;

&lt;p&gt;Track event ingestion lag, rating latency, invoice finalization time, payment success and failure rates, and dunning recovery. Alert on every job failure, retry with exponential backoff, and keep dead-letter queues so failed events can be replayed rather than lost.&lt;/p&gt;

&lt;p&gt;Then rehearse. Disable a webhook on purpose, inject a duplicate event, and confirm that idempotency and reconciliation behave the way the design says they do. A billing system that has never been tested under failure is a billing system whose failure behaviour is unknown.&lt;/p&gt;

&lt;h2&gt;
  
  
  13. Run a shadow bill before going live
&lt;/h2&gt;

&lt;p&gt;Generate invoices as if billing were live, without charging anyone. Compare totals, credits, and taxes against what you expect.&lt;/p&gt;

&lt;p&gt;Mismatched totals, missing usage, and double-rated events all show up here. Fix them in metering or rating, not by patching invoice data, because patched data means the bug is still there for next cycle.&lt;/p&gt;

&lt;p&gt;Run at least one full cycle in shadow mode, confirm the finalization window behaves correctly, and document the flow for the teams who will operate it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Flexprice fits
&lt;/h2&gt;

&lt;p&gt;Building all thirteen steps yourself is a platform project, and the failures usually come from coordination between layers rather than from any single layer's logic. One missing webhook, one duplicate usage event, or one late credit update breaks the chain.&lt;/p&gt;

&lt;p&gt;Flexprice is enterprise-grade, open source usage based billing infrastructure for AI and SaaS companies. It can be deployed in your own VPC, on-prem, or on Flexprice's managed cloud. Flexprice offers three deployment options, and all three run the same engine.&lt;/p&gt;

&lt;p&gt;Against the steps above, it provides real-time event ingestion with deduplication, an append-only usage ledger, rating against versioned prices, recurring billing with proration, credit wallets with grants and expiry, invoices generated from rated records, payment retries, and entitlement state the product can query directly. Because it's open source and self-hostable, usage and revenue data can stay entirely inside your own infrastructure and never reach a vendor's cloud.&lt;/p&gt;

&lt;p&gt;Clone it and run a shadow cycle against your own event stream: &lt;a href="https://github.com/flexprice/flexprice" rel="noopener noreferrer"&gt;github.com/flexprice/flexprice&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>billing</category>
      <category>saas</category>
      <category>architecture</category>
      <category>api</category>
    </item>
    <item>
      <title>What Is Metered Billing and How Does It Actually Work?</title>
      <dc:creator>Flexprice</dc:creator>
      <pubDate>Tue, 15 Sep 2026 08:20:18 +0000</pubDate>
      <link>https://dev.to/flexprice_8116ed925/what-is-metered-billing-and-how-does-it-actually-work-4b82</link>
      <guid>https://dev.to/flexprice_8116ed925/what-is-metered-billing-and-how-does-it-actually-work-4b82</guid>
      <description>&lt;p&gt;Metered billing and usage-based billing get used as synonyms. They are two layers of the same system, and separating them makes the architecture much easier to reason about.&lt;/p&gt;

&lt;p&gt;Metering is measurement. It counts API calls, GPU seconds, or tokens processed. Usage-based billing is the layer above it that turns those numbers into money. Most billing bugs live at the seam between the two, where an aggregation window disagrees with a billing period or a retried request gets counted twice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Short answer
&lt;/h2&gt;

&lt;p&gt;Metered billing measures actual product usage as discrete events, then a rating layer converts that measured usage into charges. It runs in four stages: event ingestion with idempotency, aggregation into billable metrics, rating against pricing rules, and invoicing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four layers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Event ingestion
&lt;/h3&gt;

&lt;p&gt;Every billable action emits an event. An API call, a token generation, a completed workflow. These flow into the metering pipeline through a queue or an ingest endpoint, and each carries an idempotency key so a retry cannot become a second charge.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"event_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"evt_9f2c41ba7d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"event_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tokens_processed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"external_customer_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cust_4812"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-09-11T14:22:05Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gpt-4o"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nl"&gt;"input_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1840&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nl"&gt;"output_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;612&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nl"&gt;"region"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eu-west-1"&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two things make this layer survivable. The event_id is generated by the caller, not the receiver, so the same event submitted twice collapses into one. And the pipeline needs replay and backfill, because a consumer will eventually fall over and has to resume from the last committed offset rather than from now.&lt;/p&gt;

&lt;p&gt;The Flexprice &lt;a href="https://docs.flexprice.io/docs/event-ingestion/overview" rel="noopener noreferrer"&gt;event ingestion overview&lt;/a&gt; covers the ingest contract, and there is an event debugger for inspecting what actually arrived, which is the question you want answered when an invoice looks wrong.&lt;/p&gt;

&lt;h3&gt;
  
  
  Aggregation
&lt;/h3&gt;

&lt;p&gt;Raw events are not billable. A billable metric is an aggregation over a window, and the function you choose changes what the customer sees on the invoice.&lt;/p&gt;

&lt;p&gt;-**Sum **totals a numeric property. Total tokens processed in a period.&lt;/p&gt;

&lt;p&gt;-**Count **counts events. Number of API requests.&lt;/p&gt;

&lt;p&gt;-&lt;strong&gt;Count unique&lt;/strong&gt; counts distinct values of a property. Active users, distinct documents touched.&lt;/p&gt;

&lt;p&gt;**Max **takes the highest value in the window. Peak concurrent seats.&lt;/p&gt;

&lt;p&gt;-&lt;strong&gt;Latest&lt;/strong&gt; takes the most recent recorded value. Current storage allocated.&lt;/p&gt;

&lt;p&gt;-&lt;strong&gt;Average&lt;/strong&gt; takes the mean of a property across events.&lt;/p&gt;

&lt;p&gt;-&lt;strong&gt;Sum with multiplier&lt;/strong&gt; sums a property and applies one configured rate to the total, which is how a raw count becomes a currency amount.&lt;/p&gt;

&lt;p&gt;-&lt;strong&gt;Weighted sum&lt;/strong&gt; is time-proportional, prorating values by how long they were held. This is the one for capacity billing such as reserved storage measured in GB-hours.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://docs.flexprice.io/docs/product-catalogue/features/aggregation/overview" rel="noopener noreferrer"&gt;aggregation reference&lt;/a&gt; documents each of these. The window matters as much as the function: hourly, daily, and per billing period each produce different numbers from the same event stream, and a mismatch between the aggregation window and the invoice period is one of the most common sources of disputed charges.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rating
&lt;/h3&gt;

&lt;p&gt;Rating converts aggregated usage into currency. The standard shapes:&lt;/p&gt;

&lt;p&gt;-&lt;strong&gt;Per unit&lt;/strong&gt;. A flat rate for every unit consumed. Easy to predict, easy to explain.&lt;/p&gt;

&lt;p&gt;-&lt;strong&gt;Tiered&lt;/strong&gt;. The rate changes as consumption crosses thresholds, with each tier priced separately.&lt;/p&gt;

&lt;p&gt;-&lt;strong&gt;Volume&lt;/strong&gt;. The whole quantity is priced at the rate the total volume qualifies for, so unit price falls as volume rises.&lt;/p&gt;

&lt;p&gt;-&lt;strong&gt;Overage&lt;/strong&gt;. A quota is included, then per-unit charges apply above it.&lt;/p&gt;

&lt;p&gt;-&lt;strong&gt;Minimum commitment&lt;/strong&gt;. A floor the customer pays regardless of consumption, with usage charged above it.&lt;/p&gt;

&lt;p&gt;Tiered and volume are frequently confused and produce different invoices for the same usage. Under tiered, the first 10,000 units keep their original rate when the customer reaches 50,000. Under volume, all 50,000 reprice at the higher-volume rate. Flexprice documents &lt;a href="https://docs.flexprice.io/docs/product-catalogue/plans/billing-models/volume-tiered" rel="noopener noreferrer"&gt;volume tiered pricing&lt;/a&gt; separately for exactly this reason.&lt;/p&gt;

&lt;h3&gt;
  
  
  Invoicing
&lt;/h3&gt;

&lt;p&gt;Rated usage becomes line items. This stage combines usage charges with subscription fees and one-off charges, applies credits and discounts, handles proration for mid-cycle changes, and calculates tax and currency conversion.&lt;/p&gt;

&lt;p&gt;The requirement that gets underestimated is traceability. Every line item should resolve back to the events that produced it, because the first question on a disputed invoice is always "which requests are these". &lt;a href="https://docs.flexprice.io/docs/invoices/calculation" rel="noopener noreferrer"&gt;Invoice calculation&lt;/a&gt; describes how charges are assembled.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI-specific metering choices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Tokens, requests, or GPU time?
&lt;/h3&gt;

&lt;p&gt;Three metrics, three tradeoffs.&lt;/p&gt;

&lt;p&gt;**Tokens **are precise and map closely to provider cost. They also confuse buyers who have no intuition for how many tokens a conversation consumes, and they punish the user for iterating on a prompt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Requests&lt;/strong&gt; are the easiest to understand and the easiest to forecast. They also hide the fact that one request can be a hundred times more expensive to serve than another.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GPU time&lt;/strong&gt; tracks actual resource consumption, which lines up with cost for training runs and heavy analysis. It is opaque to a customer who only sees a task complete.&lt;/p&gt;

&lt;p&gt;The right choice depends on who reads the invoice. Precision that the buyer cannot interpret creates support tickets, and simplicity that ignores cost variance creates margin problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Composite metrics
&lt;/h2&gt;

&lt;p&gt;A composite metric multiplies a base count by coefficients that reflect real cost. Requests times a model coefficient times a latency bucket, for example, so a slow query on a larger model costs more than a fast one on a small model.&lt;/p&gt;

&lt;p&gt;This is fairer than a flat per-request rate and it is closer to the underlying cost curve. The tradeoff is that every coefficient has to travel with the event, because the aggregation can only use what the event carries, and a coefficient change has to be versioned so historical invoices stay reproducible.&lt;/p&gt;

&lt;p&gt;The primitive for this is a &lt;a href="https://docs.flexprice.io/docs/product-catalogue/features/custom-expression" rel="noopener noreferrer"&gt;custom expression&lt;/a&gt;, a CEL formula evaluated per event that computes the quantity to aggregate. input_tokens + output_tokens combines two fields, ceil(duration_ms / 1000) converts and rounds, and gpu_seconds * device_weight applies a coefficient sent as a property. It works with Sum, Average, Max, and Latest. Missing properties evaluate to zero and nested paths are not supported, so flatten anything the formula reads to a top-level property.&lt;/p&gt;

&lt;h2&gt;
  
  
  What customers need to see
&lt;/h2&gt;

&lt;p&gt;Live usage visibility has moved from a differentiator to an expectation. Customers want current-period consumption, remaining quota, and enough history to predict next month.&lt;/p&gt;

&lt;p&gt;Alerts do the rest of the work. A notification at 75% of quota costs nothing and prevents the support conversation that starts with a surprise invoice. Flexprice supports spend alerts at the subscription and line item level.&lt;/p&gt;

&lt;p&gt;Prepaid credits and postpaid billing solve the predictability problem from opposite directions. Credits are bought up front and drawn down, with optional auto top-up and rollover, which caps exposure by construction. Postpaid gives full flexibility and defers the number to the end of the cycle, which is where bill shock comes from.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finance alignment
&lt;/h2&gt;

&lt;p&gt;Raw meters become unit economics when usage per customer is joined against cost to serve. That is what tells you which accounts are profitable and which are subsidised, and it is the number that decides whether a pricing model works.&lt;/p&gt;

&lt;p&gt;Inside organisations, two patterns handle internal accountability. Showback gives teams visibility into their consumption and its cost without moving money. Chargeback bills internal teams for what they consume. Both depend on consistent resource tagging and normalised unit costs, which is standard FinOps practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reliability and reconciliation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Design for failure&lt;/strong&gt;. Queues, retries, and dead-letter queues for events that cannot be processed. A dropped event is unbilled revenue and a duplicated event is an angry customer, so the pipeline needs both directions covered.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep usage logs immutable&lt;/strong&gt;. Once recorded, a usage event should never be altered or deleted. That gives both sides a single source of truth during a dispute, and it is what makes an audit possible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let customers export raw usage&lt;/strong&gt;. A customer who can check the arithmetic themselves stops needing to trust the invoice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common failure modes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Silent overages&lt;/strong&gt;. Usage passes the limit with no warning and the invoice arrives at four times the expected amount. Alerts and spending caps fix this, and they have to exist before the pricing launches, not after the first complaint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aggregation mismatches&lt;/strong&gt;. One meter rolls up in minutes, another in hours, timezones differ between the ingest layer and the billing period. The result is double counting or missed charges. Standardise the window and the timezone across every meter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Meter drift and duplicate events&lt;/strong&gt;. Without idempotency keys and deduplication before the pipeline, retries inflate bills. This is the failure that erodes trust fastest, because it is invisible until a customer audits their own logs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build or integrate
&lt;/h2&gt;

&lt;p&gt;Four questions decide it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scale&lt;/strong&gt;. Events per second at peak, not average. High volume changes the storage and aggregation architecture completely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Metric complexity&lt;/strong&gt;. Counting API calls is straightforward. Combining model type, duration, and latency into a composite metric with versioned coefficients is a system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Financial alignment&lt;/strong&gt;. If billing has to reconcile against CRM, ERP, tax, and accounting systems, most of the work is integration rather than metering.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Visibility&lt;/strong&gt;. Dashboards and exports for both developers and finance are a product in themselves.&lt;/p&gt;

&lt;p&gt;The integration pattern splits into four components that can be one stack or separate services: a metering pipeline for ingestion, a rating engine for pricing logic, a billing engine for invoices, and a payment gateway for collection. Keeping them separable is what lets you replace one without replacing all four.&lt;/p&gt;

&lt;p&gt;Flexprice is enterprise-grade, open source usage based billing infrastructure for AI and SaaS companies. It can be deployed in your own VPC, on-prem, or on Flexprice's managed cloud, so usage and revenue data can stay entirely inside your own infrastructure and never reach a vendor's cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  A starting checklist
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Choose the value metric&lt;/strong&gt;. It should represent value to the customer and correlate with your cost. These are not always the same unit, and the customer's version usually wins.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix the windows and aggregation functions&lt;/strong&gt;. Pick them once and apply them consistently across every meter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prevent bill shock before launch&lt;/strong&gt;. Invoice previews, threshold alerts, and either credit wallets or capped plans.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Plan reconciliation up front&lt;/strong&gt;. Immutable logs, export tooling, and a documented dispute workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;Ingest is the layer to prove first. The &lt;a href="https://docs.flexprice.io/docs/event-ingestion/sending-events" rel="noopener noreferrer"&gt;sending events guide&lt;/a&gt; covers the payload contract and idempotency handling, and the implementation is on &lt;a href="https://github.com/flexprice/flexprice" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;if you want to read how aggregation and rating are wired together.&lt;/p&gt;

</description>
      <category>billing</category>
      <category>api</category>
      <category>architecture</category>
      <category>saas</category>
    </item>
    <item>
      <title>What a No-Code Usage-Based Pricing Layer Actually Has to Do</title>
      <dc:creator>Flexprice</dc:creator>
      <pubDate>Tue, 15 Sep 2026 07:53:29 +0000</pubDate>
      <link>https://dev.to/flexprice_8116ed925/what-a-no-code-usage-based-pricing-layer-actually-has-to-do-eif</link>
      <guid>https://dev.to/flexprice_8116ed925/what-a-no-code-usage-based-pricing-layer-actually-has-to-do-eif</guid>
      <description>&lt;p&gt;Pricing that depends on API calls, tokens, compute minutes, or storage consumed breaks the assumption every subscription billing system is built on: that a customer's charge is knowable at the start of the period. Once that assumption goes, the billing system has to meter, aggregate, price, apply credits, enforce quotas, and produce an invoice a customer will believe.&lt;/p&gt;

&lt;p&gt;Teams usually discover this after the fact, when a product engineer is maintaining a spreadsheet reconciliation and pricing changes need a deploy.&lt;/p&gt;

&lt;p&gt;This is what the layer between your product and your payment provider has to do, and how to evaluate whether a given platform actually does it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Short answer
&lt;/h2&gt;

&lt;p&gt;A no-code usage-based pricing tool meters consumption events, applies pricing rules, tracks credits and entitlements, and generates invoices without billing logic living in application code. The capabilities that matter are real-time metering, a credit wallet with expiry and top-up rules, entitlement enforcement tied to that metering, gateway independence, and configuration that product and finance can change without a deploy.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a no-code usage-based pricing tool?
&lt;/h2&gt;

&lt;p&gt;It is a billing infrastructure layer that sits between the product and the payment provider. The application emits usage events. The platform meters them, applies pricing logic, accounts for credits and discounts, and generates an invoice. The payment provider only collects the money.&lt;/p&gt;

&lt;p&gt;The no-code part means product and finance configure plans, tiers, entitlements, and experiments through an interface rather than by writing queries or shipping code. The distinction matters more than it sounds, because it decides whether a pricing change takes an afternoon or a sprint.&lt;/p&gt;

&lt;h2&gt;
  
  
  The six capabilities that decide the choice
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Real-time metering that holds under volatile load
&lt;/h3&gt;

&lt;p&gt;AI workloads are not smooth. A customer processes 100 API calls today and 100,000 tomorrow, and the metering path has to absorb that without dropping events or falling behind. Batch-based billing systems that aggregate nightly cannot support mid-cycle usage reporting, quota enforcement, or a dashboard the customer trusts.&lt;/p&gt;

&lt;p&gt;What to check: how usage is ingested (API, SDK, stream, warehouse), whether aggregation happens continuously or on a schedule, and which &lt;a href="https://docs.flexprice.io/docs/product-catalogue/features/aggregation/overview" rel="noopener noreferrer"&gt;aggregation functions&lt;/a&gt; are available. Count, sum, unique count, max, and weighted sum cover most metering patterns. If the platform only counts, complex metrics end up back in your code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Credit wallets as a primitive, not an add-on
&lt;/h3&gt;

&lt;p&gt;Credits solve a specific problem for AI products: normalising several capabilities with very different unit costs into one number the customer can reason about. Image generation, text summarisation, and data analysis all cost different amounts to serve, and no customer wants three meters.&lt;/p&gt;

&lt;p&gt;A real wallet implementation has a ledger per customer recording issuance, consumption, expiry, and every balance change. It supports prepaid, promotional, and subscription-included balances with different priorities, expiry rules per grant, and automatic top-ups when the balance crosses a threshold. Flexprice supports &lt;a href="https://docs.flexprice.io/docs/wallet/prepaid-and-promotional" rel="noopener noreferrer"&gt;prepaid and promotional balances&lt;/a&gt; with per-grant expiry and &lt;a href="https://docs.flexprice.io/docs/wallet/auto-top-up" rel="noopener noreferrer"&gt;auto top-up&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Credits bolted on top of subscription logic tend to fail at the edges: mid-cycle grants, partial expiry, and refunds against consumed credits.&lt;/p&gt;

&lt;h3&gt;
  
  
  Entitlements wired to the meter
&lt;/h3&gt;

&lt;p&gt;Entitlement management is what stops usage rather than what records it. Three kinds are needed. Boolean entitlements are on or off by plan, like SSO or priority support. Metered entitlements track consumption against a quota. Static entitlements define what is included without counting, such as which models or regions are available.&lt;/p&gt;

&lt;p&gt;The part that gets missed is enforcement. When a customer hits 100% of quota, the system has to do something specific: continue and bill the overage, block, throttle, or prompt for a top-up. If enforcement lives in application code, every pricing change becomes a product change. Flexprice keeps this in &lt;a href="https://docs.flexprice.io/docs/product-catalogue/features/entitlement-grants" rel="noopener noreferrer"&gt;entitlement grants&lt;/a&gt; linked to plans.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hybrid pricing without SKU explosion
&lt;/h3&gt;

&lt;p&gt;Very few companies run pure pay as you go. The common shapes are a base fee with included usage and overages, prepaid credit drawdown, minimum commitments with true-up, and per-seat charges combined with consumption. A platform that models these as separate plan duplicates rather than composable charges will produce a catalogue nobody can maintain after the third experiment.&lt;/p&gt;

&lt;p&gt;Check whether &lt;a href="https://docs.flexprice.io/docs/product-catalogue/plans/billing-models/volume-tiered" rel="noopener noreferrer"&gt;billing models&lt;/a&gt; like volume tiering, package pricing, and flat fees can coexist on one subscription and whether prices can be overridden per customer without cloning the plan.&lt;/p&gt;

&lt;h3&gt;
  
  
  Environment isolation
&lt;/h3&gt;

&lt;p&gt;Pricing changes are financial changes, and a mistake is a customer-visible one. Being able to configure and replay pricing in a sandbox before promoting it to production is the difference between an iteration cadence you can sustain and one you avoid.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gateway and deployment independence
&lt;/h3&gt;

&lt;p&gt;Two forms of lock-in matter here. The first is payment gateway coupling: if the billing layer only settles through one processor, you inherit that processor's fees, regional coverage, and roadmap. The second is data location: whether usage and revenue records have to sit in a vendor's cloud.&lt;/p&gt;

&lt;p&gt;Flexprice is enterprise-grade, open source usage based billing infrastructure for AI and SaaS companies. It can be deployed in your own VPC, on-prem, or on Flexprice's managed cloud. All three run the same engine, so the deployment decision is not also a feature decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the landscape splits
&lt;/h2&gt;

&lt;p&gt;The tools in this category are solving related but different problems, and the useful way to read them is by which problem they lead with.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Metering-first infrastructure&lt;/strong&gt;. Flexprice and Lago both sit in this group, and both are open source and self-hostable. The difference is enterprise scale: Flexprice is built for real-time metering at high event volume, with deployment across any VPC and any geography.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Merchant of record platforms&lt;/strong&gt;. Polar handles global tax compliance by acting as the seller, which removes VAT and GST work for teams selling internationally. Transaction pricing at 4% plus $0.40 with no monthly fee is straightforward, and the tradeoff is depth: card payments through Stripe Connect only, and no hierarchical billing or contract management for enterprise workflows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Metering inside a payments company&lt;/strong&gt;. Metronome is now part of Stripe. The metering itself is strong and proven on large AI and infrastructure workloads. The consideration is scope: the billing layer and the payment layer are now the same vendor, so payment strategy and billing strategy stop being separable decisions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Order to cash platforms&lt;/strong&gt;. Zenskar extends past billing into revenue recognition, collections, and financial reporting, with contract ingestion and ASC 606 support built in. That suits finance-led enterprises with complex sales contracts. It is sales-led with no self-serve entry, so evaluation starts with a demo rather than an integration.&lt;/p&gt;

&lt;p&gt;Compared with Chargebee, Recurly, and Maxio, which are subscription management software built for plan-based and per-seat billing, hosted only, Flexprice is metering-first infrastructure built for usage-based and hybrid pricing. Compared with Stripe Billing, which is built around subscriptions and payments and is usually paired with a separate metering vendor for usage-based products, Flexprice is the metering and billing layer itself, and is not tied to any payment gateway.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to evaluate one for your case
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Start from pricing complexity, not feature lists&lt;/strong&gt;. Subscription with usage overages is a solved problem and most platforms handle it. Credits, multi-tier usage, and entitlement enforcement narrow the field quickly. Enterprise commits with minimums and custom terms narrow it again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Price the lock-in explicitly&lt;/strong&gt;. Ask whether the platform forces a payment provider, whether usage data and billing history can be exported in full, and what happens to your roadmap if the vendor is acquired. Open source answers the first two by construction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Match the tool to who will operate it&lt;/strong&gt;. A platform that needs SQL to define a billable metric will route every pricing question through engineering, whatever the marketing says. If finance and product are meant to own pricing, verify they can define a metric and launch a plan without a ticket.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Count how often pricing will change&lt;/strong&gt;. AI products adjust pricing as models and costs move, sometimes several times a year. That cadence is the real requirement, and it is the one that decides whether a platform is workable in eighteen months.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check the compliance gap&lt;/strong&gt;. Metering-only tools leave ASC 606 and IFRS 15 revenue recognition to you or to your accounting system. That is fine if the integration exists and unpleasant if it does not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this shift happened
&lt;/h2&gt;

&lt;p&gt;63% of SaaS companies now use or are actively testing usage-based pricing, up from 45% in 2021. The drivers are structural rather than fashionable.&lt;/p&gt;

&lt;p&gt;AI workloads are non-linear, so seat counts stopped correlating with cost or value. Product-led motions need a single billing path that carries a user from free trial through team usage to an enterprise contract without a migration. Finance teams need consumption and margin visible during the month rather than after it. And engineering teams that built billing in-house discovered the maintenance cost compounds, which is why several well-known companies later replaced their internal systems with dedicated ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;The fastest way to evaluate a metering layer is to send it real events and see what the invoice looks like. The &lt;a href="https://docs.flexprice.io/docs/event-ingestion/overview" rel="noopener noreferrer"&gt;event ingestion overview&lt;/a&gt; covers the ingestion path, and the &lt;a href="https://docs.flexprice.io/docs/connect/mcp-server" rel="noopener noreferrer"&gt;MCP server&lt;/a&gt; exposes the same operations to an editor if you would rather drive the setup from there. The source is on &lt;a href="https://github.com/flexprice/flexprice" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>billing</category>
      <category>saas</category>
      <category>api</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
