How hard is it to build subscription metrics yourself?
The code is easy now. The billing data isn't, because every workaround in it affects how your metrics are calculated.
Can AI write your metrics queries?
Yes. Writing code has never been easier. Connect Claude or Codex to Stripe, describe how metrics should be calculated, and it will produce working queries, charts, and something deployable in a weekend.
What it produces is a calculation over whatever your billing data says. Whether that data reflects the actual value of each customer's subscription is a separate question, and it's the one that decides whether your metrics are accurate.
Why is subscription data harder than it looks?
A billing system is built to invoice customers and collect payment, and the people using it are focused on getting paid, not on reporting. So they make reasonable changes that happen to break the numbers: voiding an invoice and sending a new one, invoicing a large customer by hand, or moving to a new billing system. Other problems are side effects of how the tool is set up, like a subscription that stays open after its payments stop because nothing was configured to cancel it. None of these look wrong in the billing system, and a model reading the data has no way to tell.
The billing situations that quietly break reporting.
Billing setup
- Multiple billing systems
- Auto vs. manual collection rules
- Payment method changes
- Billing system migrations
- Delinquent and past-due subscribers
- Mobile app stores
- Accounting integrations
Plans and pricing
- Multiple products
- Multi-component subscriptions
- Add-ons and overages
- Pro-rated adjustments
- Free subscriptions
- Free and paid trials
Currencies and regions
- Multiple currencies
- Multiple geographies
- Forex fluctuations
Billing exceptions
- Recurring charged as one-time
- Custom contract terms
- Paused subscriptions
- Pending invoice items
- Refunds and credits
- Written-off and voided invoices
Here's a closer look at seven of them.
Customers billed outside your main billing system
Stripe might bill 98% of your customers while the other 2% are invoiced manually. Those customers never appear in Stripe, and as your largest accounts, they might represent 10% of revenue. A build connected only to Stripe can't see them at all.
ChartMogul includes a manual data source for customers invoiced outside your billing system, with its own data settings.
More than one billing system
Many subscription businesses bill through more than one system, such as Stripe on the web, with the App Store and Google Play on mobile. Each defines its own subscription logic. For example, in Recurly, a "canceled" subscription is one that won't renew but stays active until the end of its term. In Stripe, a scheduled cancellation stays "active," and "canceled" means the subscription has already ended. So an annual Recurly customer who turns off renewal in month two shows as canceled immediately, and a model counting canceled subscriptions as churn records them ten months early. The app stores add their own retry windows, grace periods, and states like Google Play's account hold, none of which map cleanly onto Stripe's past-due status.
Connecting each system to a model makes those customers visible, but not consistent. Every question means reconciling different data models and matching the same customer across systems.
ChartMogul connects to more than 30 billing systems and normalizes their data into one model, so the definition of churn is consistent, and duplicates across systems can be merged into one customer.
A billing system migration
Every subscription in Chargebee is cancelled and recreated in Stripe on the same day. A build that reads both shows a wave of churn matched by a wave of new business. Merge the customers and it becomes false churn and false reactivation instead, and that assumes you can trace which Chargebee customer is which Stripe customer.
ChartMogul matches duplicates across billing systems on fields like domain, external ID, or email, merges them, and connects old and new subscriptions into one history.
Unpaid subscriptions nobody cancelled
In large Stripe accounts, it's common to find customers still counted as active years after they stopped paying, because an invoice was voided or payment retries ended without anyone cancelling the subscription. Each one quietly inflates MRR, and a model has no way to know the customer churned.
ChartMogul can auto-churn subscriptions after a delinquency window you set and exclude voided and refunded invoices, so none of them keep counting without anyone having to find them first.
Revenue in a second currency
A customer in Europe pays the equivalent of $59 one month and $63 the next. They didn't expand. The exchange rate moved. Without a way to separate currency movement from real changes in what customers pay, a build reports FX fluctuation as expansion and contraction.
ChartMogul reports currency fluctuation as a separate category, so it doesn't show up as expansion or contraction.
Usage charges alongside subscription revenue
If you bill a platform fee plus usage, you need a rule for whether usage counts toward MRR, and it has to be applied to every invoice, past and future. A model will pick an answer each time it calculates, and it may not pick the same one next time.
In ChartMogul, invoice line items can be classified as recurring or non-recurring, so usage counts the way you've decided.
Recurring revenue charged as a one-time invoice
A customer upgrades from monthly to annual. Instead of letting Stripe's prorated invoice go through, someone voids it and sends a manual one-time invoice. The customer pays, and Stripe is still doing its job. But a build that reads invoices now sees a one-time payment and leaves that revenue out of MRR. If the voided invoice was the renewal, the subscription can also drift into past due while the customer has actually paid.
In ChartMogul, you reclassify that line item as recurring once, and every report reflects it.
Why can't you tell when the number is wrong?
Because a wrong metric looks exactly like a right one. A voided invoice or a forgotten subscription throws no error and fails no test. It returns a plausible number that ends up in a board deck.
Bugs in a checkout flow surface in hours, because customers complain. Bugs in an MRR calculation surface in months, usually from outside: someone in diligence pulls your billing export, recomputes, and gets a different answer than your deck.
What do you take on when you build it yourself?
Most estimates cover the initial build. They rarely cover what comes after it: setting the rules your metrics depend on, re-verifying them as your billing changes, and maintaining consistency.
Which rules do you have to set?
Every metric rests on rules about your billing data, and building means writing all of them yourself:
- What happens when a customer is refunded, including a refund of their very first invoice
- Whether voided invoices count
- How many days past due before a customer counts as churned
- Whether MRR is reported when an invoice is issued, or only once it's paid
- When churn is recognized: at the time of cancellation, or at the end of the paid period
- Whether the same rules apply to every customer, or differ for customers invoiced manually
A model can write any of these rules. What it can't do is decide which one is right for your business, apply it identically every time, or tell you when changing it rewrote your history. In ChartMogul, each is a data setting applied to every customer in a data source, so a Stripe account and a manually invoiced enterprise segment can follow different rules, with data editing for individual exceptions.
What does maintaining it involve?
The old argument was that someone has to update the code. That matters less now that AI can update code reliably.
The problem that remains is that every change to metric logic raises two questions code can't answer: is the new number right, and does the change apply to past months, or only to numbers calculated from now on? If the change only applies from now on, your historical and current numbers are calculated two different ways, so trends over time stop being reliable. If it's applied to history, the numbers you've already reported change, and some of them were wrong.
Who else needs to read the numbers?
With a good AI build, anyone on the team can ask for the numbers. The harder part is making sure they all get the same ones. When finance, customer success, and your CEO each ask their own question, each answer is calculated on the spot, and small differences in phrasing or in how an edge case gets resolved turn into numbers that don't match. Reconciling them routes back to whoever built it.
A company can rely on its metrics when everyone works from the same saved segments, shared dashboards, and definitions.
Can't you just connect Claude to Stripe?
This is how many teams build it now. Stripe's MCP server gives Claude access to customers, subscriptions, invoices, and payments, and a prompt describes how metrics should be calculated, sometimes by pointing the model at a published definition.
It works for one question at a time. The problems show up across questions:
- It recalculates from scratch every time. The model re-derives each answer from raw billing objects, so the same edge case can be resolved differently from one conversation to the next.
- A definition isn't clean data. Pointing the model at a metric definition, even ChartMogul's own help center, gives it the rules but not the corrections. Customers billed outside Stripe still don't exist, and the unpaid subscription nobody cancelled still counts.
- Nothing gets fixed at the source. Every answer inherits the same errors, because nobody has corrected the underlying records.
You don't have to choose between the two. ChartMogul's remote MCP server connects to Claude and ChatGPT, so the model answers questions from data that's already cleaned, normalized across billing systems, and consistent over time. The model does the analysis, and ChartMogul keeps the data and the rules it's calculated by. If you also run a data warehouse, the same data syncs to Snowflake, BigQuery, or Redshift.
Can you automate actions when a subscription changes?
In ChartMogul, yes. It's also the part a homegrown build rarely reaches. A dashboard, or a conversation with Claude, answers questions when someone asks them. A workflow acts the moment something changes in a customer's subscription, whether or not anyone is looking.
ChartMogul triggers workflows from subscription events. When a customer schedules a cancellation, the account manager can be assigned a task and the customer can receive an email while the decision is still fresh. When an account's MRR crosses a threshold, it can be assigned to a different account manager automatically. These are only two examples. Workflows can start from many other changes to a customer's subscription, from a new trial to a subscription going past due, and each can combine tasks, emails, and email sequences to match how your team works.
Rebuilding that in-house means more than calculating metrics. It means listening to billing webhooks, keeping trigger logic correct as your plans and billing change, and connecting the results to wherever your team works. As AI makes dashboards cheap to build, acting on subscription changes is the part that still takes a product to do well.
When is building your own the right call?
Less often than it seems, and mainly for one reason that will still be true in two years: your revenue isn't subscription-shaped. Marketplace take rates, pure usage billing, and transactional revenue often need a different instrument, and a subscription analytics tool might be the wrong one.
Needing a metric nobody models used to be a second reason. With ChartMogul's MCP server, Claude or ChatGPT can calculate it your way, on data that's already cleaned.
Two common reasons expire. "Our billing is simple" and "we can eyeball the number" are true for many early companies, though this changes with time. The exit is the cost: a script that works at 40 customers gets replaced around 400, and two years of homegrown history has to be reconciled against whatever you adopt, usually with a discontinuity someone has to explain in a board meeting.
If you want to test the comparison, start a 14-day trial with your own billing data connected. When the trial ends, you can keep using ChartMogul on the free plan if your revenue is within its limit, or move to a paid plan. See pricing for the current limits.