Education
12 min read

Chargebee Analytics in BigQuery: MRR, Retention, and Dunning Without a Reporting Silo

Build a Chargebee to BigQuery pipeline with open-source Bruin and ingestr. Model MRR, retention, plan mix, revenue concentration, and failed-payment risk in SQL your team can review.

Arsalan Noorafkan

Developer Advocate

Quick answer: Chargebee is good at billing. It is not meant to be your warehouse, your account model, or the place where every team agrees on MRR. A Chargebee analytics pipeline copies the source data into BigQuery, turns it into typed SQL models, records daily MRR, and publishes reports your finance, revenue, and product teams can join to the rest of the business. The open-source Chargebee to BigQuery template gives you the first version without building a connector and a reporting project from scratch.

The trigger is usually a revenue meeting. Someone has Chargebee's MRR, someone else has a board spreadsheet, and a third person has an answer from the CRM. The figures are close enough to be awkward and far enough apart to stop the conversation.

That is not a Chargebee bug. Chargebee is doing what a billing platform should do. The problem is that billing questions become company questions as soon as a SaaS team grows: which accounts are expanding, which plans create concentration risk, and whether failed payments are recoverable before they become churn.

What Chargebee gives you, and where it stops

Chargebee's built-in reporting is useful for operating Chargebee. The boundary appears when you need a metric that combines billing with the rest of your business.

Chargebee surfaceGood forWhere it stops
Billing and subscription viewsCurrent subscription state, invoices, transactions, and customer activityA fixed product boundary and current-state questions
RevenueStory reportsStandard recurring-revenue and retention viewsDefinitions and dimensions that do not match your finance or board policy
Chargebee APIsExtracting source objects for a warehouse or custom processPagination, retries, schema handling, history, models, and checks become your job
Chargebee plus a warehouseJoining billing to CRM, product, support, or marketing dataYou still need ingestion, modelling, schedules, metric policy, and quality checks

The last row is the right destination for most growing SaaS teams. It is also where the work tends to sprawl. A connector loads data. A transformation tool defines models. An orchestrator runs them. A dashboard tool holds the definitions everyone is debating. The data may be correct, but nobody can explain which version of MRR they are looking at.

The Chargebee metrics worth owning

The useful part of a warehouse model is not copying every API field. It is making the questions explicit.

MRR by customer

Monthly recurring revenue is a run rate, not recognized revenue and not cash collected. A useful model tells you the customer, currency, active subscription count, MRR in native minor units, and the fields you will use to segment the account.

Chargebee subscriptions are mutable. If a customer changes from a $500 plan to a $300 plan, querying the subscription today does not reconstruct the $500 state from three months ago. The template addresses this with customer_currency_daily_mrr_snapshot, an insert-only history by customer, currency, and pipeline date. A rerun replaces only that date.

The trade-off is straightforward: history starts when the snapshot starts. You can backfill lifecycle episodes from dates on the subscription, but you cannot recreate every historical price without observations from when that price was active.

MRR movements and retention

Once you have monthly snapshots, you can classify the change for each customer:

  • new MRR when a customer appears with MRR for the first time
  • expansion when its MRR increases
  • contraction when its MRR decreases but remains above zero
  • churn when MRR reaches zero
  • reactivation when MRR returns after a previous zero period

The important detail is the grain. Sum a customer's subscriptions before classifying the movement. Otherwise a plan swap can look like churn plus new business in the same month.

The template also keeps currencies separate. There is no honest way to calculate a consolidated MRR or NRR number until you choose an FX source, a conversion date, and a policy for rate changes. Keeping the currency column in every report makes that missing decision visible instead of silently wrong.

Billings versus MRR

Finance will ask why billed revenue does not equal MRR. That is a good question. They are different measurements.

MRR is a normalized run rate for eligible recurring items. Billings come from invoices and depend on invoice state, finalization date, credits, payment timing, and one-off charges. The template has a monthly_invoice_billings report so those questions do not get forced into the MRR model.

Plan mix and concentration

Chargebee can tell you what a plan costs. A warehouse model can tell you how much of your current MRR depends on that plan, which add-ons are growing, and how much revenue comes from the top one, five, or ten customers.

This is the difference between a billing report and a planning input. Packaging decisions need plan-level MRR. Enterprise risk needs concentration. Neither should be a manual export that gets updated before the board meeting.

Failed payments and dunning risk

A failed payment is not automatically churn. Some failures recover during the retry window. Others become involuntary churn risk after retries are exhausted.

The failed_payment_dunning report separates recoverable and at-risk failed amounts using a configurable dunning_retry_window_days variable. The default is 30 days. Your policy may be different, but it should live in pipeline.yml, not in somebody's memory.

What the open-source template contains

The Chargebee BigQuery template is a three-layer Bruin project.

chargebee_raw uses ingestr to load customers, subscriptions, invoices, transactions, and events. The raw boundary preserves what Chargebee sent so you can investigate a model without making the source API your only evidence.

chargebee_stage types timestamps, normalizes customer fields, unnests subscription items, calculates a monthly run rate, flags MRR eligibility, and writes the daily snapshot. Amounts stay in NUMERIC minor units with a _minor suffix.

chargebee_reports publishes:

ReportQuestion
monthly_mrr_by_customerWhich accounts pay what, by month and currency?
monthly_mrr_movementsWhy did MRR change?
monthly_subscription_kpisWhat are MRR, ARR, GRR, NRR, logo churn, and ARPA?
monthly_invoice_billingsWhat was billed and collected?
mrr_by_planWhich plans and add-ons drive MRR?
revenue_concentrationHow dependent are we on the largest accounts?
failed_payment_dunningWhich failed payments are recoverable or at risk?

It also ships dashboards/chargebee-billing-analytics.yml, a DAC dashboard with Overview, Retention & Expansion, Monetization & Portfolio, and Collections & Risk tabs. The dashboard is YAML in the same repository as the pipeline. That matters when a metric changes because the review is a pull request, not a hunt through a UI's revision history.

A practical setup path

The fastest way to evaluate this is not to design a perfect data platform. It is to run a small, real pipeline against a test site and see whether the reports answer the questions that keep coming up.

bruin init chargebee-bigquery
cd chargebee-bigquery
bruin validate .
bruin run --full-refresh .

Set CHARGEBEE_SITE to the site name only, configure CHARGEBEE_API_KEY, and give the gcp-default connection a BigQuery project and service account. The first full refresh loads the available history. The daily schedule then keeps raw tables current and records a new MRR snapshot.

The template includes pipeline variables for the decisions most likely to differ between companies:

bruin run --var concentration_top_n=5 \
  --var 'mrr_active_statuses=["active","non_renewing","in_trial"]' \
  --var dunning_retry_window_days=45 .

Change the policy deliberately. If trials are not committed revenue for your company, do not count them as MRR because a dashboard made the option easy to turn on.

Chargebee analytics versus a managed connector

There is no prize for writing your own Chargebee API client. Pagination, retries, incremental keys, and schema changes are boring work, which is precisely why they are easy to get subtly wrong.

The question is where you want the ownership to sit:

ApproachFits whenTrade-off
Chargebee reports onlyThe question stays inside billingLimited joins, fixed definitions, and current-state history
Managed connector plus BIYou want someone else to operate extractionModels, checks, metric policy, and warehouse cost remain separate
Custom API scriptsThe extraction is genuinely unusualYou own pagination, retries, backfills, and schema drift
Bruin templateYou want ingestion, SQL, checks, lineage, and scheduling as filesYou need a team comfortable reviewing Git and SQL

Bruin's case is simple. The CLI and ingestr are open source, the project runs locally, and the definitions are visible. Bruin Cloud is the managed step when you want scheduling, run history, catalog, lineage, access controls, and audit logs without operating all of that yourself.

That split is useful for startups. You can prove the reports on your own machine, deploy them to your VPC or a small runner, and add managed governance when the workflow has earned it.

The limits belong in the model

A few caveats are worth keeping close to the SQL:

MRR is not revenue. It is a normalized recurring run rate. It does not replace revenue recognition, bookings, or cash reporting.

The first month is a baseline. Movement and retention need two contiguous monthly snapshots. Empty movement fields at the start are expected.

Currencies do not add themselves. Native minor units are safer than a fake global total. Add FX when you have a policy, not because the dashboard wants one number.

Snapshots do not recover history you never observed. Start the daily schedule before you need a clean churn trend. Future you will be grateful, which is not always a phrase I trust, but it applies here.

What to build next

Once the first reports are useful, join chargebee_stage.customers to your CRM with a declared account crosswalk. Prefer an explicit CRM foreign key, then billing email, then a normalized company domain. Add product usage or support data after that.

The next reports usually become obvious: MRR by acquisition channel, expansion risk by account owner, CAC payback, trial conversion, or product usage before a failed payment. They are not generic dashboard widgets. They are the questions your team already asks, now backed by a model you can inspect.

Start with the Chargebee Billing Analytics guide for the commands, or read the template README if you want to inspect the assets first.

Sign up to our newsletter

Practical updates on open-source data pipelines, AI analysts, governance, and what we are shipping at Bruin.

The signup form is hosted by Brevo. Allow marketing cookies to load it.