Use CasesAISQL

How to Calculate MRR and ARR Directly from Your Database

Every SaaS founder has been there: the board meeting is in two hours, someone asks for "current MRR by plan tier," and you're opening a spreadsheet you updat...

Priya Sharma· Product LeadApril 12, 20266 min read

Every SaaS founder has been there: the board meeting is in two hours, someone asks for "current MRR by plan tier," and you're opening a spreadsheet you updated three weeks ago and hoping nothing has changed. The real numbers are in your database. Getting them out, traditionally, means asking an engineer to write a query or waiting until the next sprint.

This guide walks through exactly how MRR and ARR are calculated from raw subscription data, what queries look like, and how tools like AI for Database let you pull live numbers in plain English no SQL, no engineering queue.

What MRR and ARR Actually Measure

Monthly Recurring Revenue (MRR) is the predictable monthly revenue from active subscriptions. Annual Recurring Revenue (ARR) is simply MRR × 12. These are the north-star metrics for any subscription business because they strip out one-time payments, refunds, and noise leaving only the revenue you can count on.

The tricky part is that "active subscriptions" is not a static list. Customers upgrade, downgrade, pause, churn, and reactivate constantly. Any MRR figure more than a day old is potentially stale. That's why you want to calculate it directly from your database, not from a snapshot in a spreadsheet.

The key components of MRR are:

  • New MRR revenue from brand-new subscribers this month
  • Expansion MRR revenue increases from upgrades or seat additions
  • Contraction MRR revenue lost from downgrades
  • Churned MRR revenue lost from cancellations
  • Net New MRR New + Expansion − Contraction − Churned
  • What Your Database Schema Typically Looks Like

    Most subscription businesses store billing data in one of two patterns: a subscriptions table with current state, or an invoices / payments table that records every billing event. Often you have both.

    A typical subscriptions table might look like this:

    CREATE TABLE subscriptions (
      id           UUID PRIMARY KEY,
      customer_id  UUID NOT NULL,
      plan_id      VARCHAR(50),
      status       VARCHAR(20), , 'active', 'canceled', 'paused', 'trialing'
      mrr_cents    INTEGER,     , current monthly value in cents
      started_at   TIMESTAMP,
      canceled_at  TIMESTAMP,
      updated_at   TIMESTAMP
    );

    And a subscription_events table that logs state changes:

    CREATE TABLE subscription_events (
      id              UUID PRIMARY KEY,
      subscription_id UUID,
      event_type      VARCHAR(50), , 'created', 'upgraded', 'downgraded', 'canceled'
      mrr_before      INTEGER,
      mrr_after       INTEGER,
      occurred_at     TIMESTAMP
    );

    If you use Stripe, most of these fields map directly to their API objects. If you use a custom billing system, the names differ but the structure is similar.

    Calculating Current MRR with SQL

    Here is the core query for current MRR from a subscriptions table:

    SELECT
      plan_id,
      COUNT(*) AS active_subscribers,
      SUM(mrr_cents) / 100.0 AS mrr_usd
    FROM subscriptions
    WHERE status = 'active'
    GROUP BY plan_id
    ORDER BY mrr_usd DESC;

    For total MRR across all plans:

    SELECT
      SUM(mrr_cents) / 100.0 AS total_mrr_usd,
      SUM(mrr_cents) / 100.0 * 12 AS arr_usd
    FROM subscriptions
    WHERE status = 'active';

    If your billing is annual, make sure you normalize annual subscriptions to a monthly value before summing. A customer paying $1,200/year contributes $100/month to MRR.

    SELECT
      SUM(
        CASE
          WHEN billing_interval = 'year' THEN annual_amount_cents / 12.0
          WHEN billing_interval = 'month' THEN monthly_amount_cents
          ELSE 0
        END
      ) / 100.0 AS mrr_usd
    FROM subscriptions
    WHERE status = 'active';

    Calculating MRR Movement (New, Expansion, Churned)

    This is where things get more interesting and where most spreadsheet-based tracking falls apart. To calculate MRR movements for a given month, you compare subscription states at the start and end of the period.

    WITH start_of_month AS (
      SELECT subscription_id, SUM(mrr_after) AS mrr
      FROM subscription_events
      WHERE occurred_at < '2026-03-01'
      GROUP BY subscription_id
    ),
    end_of_month AS (
      SELECT subscription_id, SUM(mrr_after) AS mrr
      FROM subscription_events
      WHERE occurred_at < '2026-04-01'
      GROUP BY subscription_id
    ),
    movement AS (
      SELECT
        COALESCE(e.subscription_id, s.subscription_id) AS subscription_id,
        COALESCE(s.mrr, 0) AS mrr_start,
        COALESCE(e.mrr, 0) AS mrr_end
      FROM start_of_month s
      FULL OUTER JOIN end_of_month e ON s.subscription_id = e.subscription_id
    )
    SELECT
      SUM(CASE WHEN mrr_start = 0 AND mrr_end > 0 THEN mrr_end ELSE 0 END) / 100.0 AS new_mrr,
      SUM(CASE WHEN mrr_start > 0 AND mrr_end > mrr_start THEN mrr_end - mrr_start ELSE 0 END) / 100.0 AS expansion_mrr,
      SUM(CASE WHEN mrr_start > 0 AND mrr_end < mrr_start AND mrr_end > 0 THEN mrr_start - mrr_end ELSE 0 END) / 100.0 AS contraction_mrr,
      SUM(CASE WHEN mrr_start > 0 AND mrr_end = 0 THEN mrr_start ELSE 0 END) / 100.0 AS churned_mrr
    FROM movement;

    These queries work, but they take time to write, test, and maintain. Every time your schema changes, someone has to update the SQL.

    Asking Your Database in Plain English

    This is where a tool like AI for Database changes the workflow entirely. Instead of writing those queries from scratch, you connect your database and type questions like:

  • "What is our current MRR broken down by plan?"
  • "Show me MRR movement for March new, expansion, and churned"
  • "Which customers upgraded in the last 30 days and what did their MRR change by?"
  • "What's our ARR if we only count monthly plans?"
  • The tool translates each question into SQL, runs it against your live database, and returns the answer as a table or chart. You don't need to know the table names or figure out the join logic.

    For recurring metrics like this, you can also set up a self-refreshing dashboard. Pin the MRR breakdown query to a dashboard, and it recalculates automatically every hour or every morning before your standup. No more "let me pull the latest numbers" before every meeting.

    Common MRR Calculation Mistakes to Avoid

    Including trials in MRR. Trial users aren't paying yet. Filter them out with WHERE status = 'active' and make sure "active" in your system means "paying."

    Counting annual subscriptions at face value. If a customer pays $2,400 upfront for a year, booking it all as one month's MRR makes your chart look like a roller coaster. Normalize to monthly.

    Double-counting upgrades. If a customer upgrades mid-month, some billing systems create a new subscription record rather than updating the existing one. You may need to deduplicate by customer before summing.

    Not accounting for paused subscriptions. If your product lets users pause billing, they're not churned but they're also not contributing to MRR. Most SaaS metrics definitions exclude them from active MRR.

    Using invoice data instead of subscription data. Invoices reflect when you bill, not what the customer is currently paying. A customer who paid annually in January won't have an invoice in March, but they're still contributing to MRR.

    Treating MRR as a Live Metric

    The biggest shift in how founders think about MRR is treating it as a live metric rather than a monthly exercise. When your database is the source of truth and you can query it in plain English, MRR goes from a report you prepare to a number you just know.

    A dashboard that shows current MRR, MRR by plan, and last 30 days of movement refreshed automatically, visible to your whole leadership team creates a shared understanding of the business that no spreadsheet can replicate.

    Try AI for Database free at aifordatabase.com. Connect your billing database, ask for your current MRR, and have a live dashboard running before your next team meeting.

    Ready to try AI for Database?

    Query your database in plain English. No SQL required. Start free today.