You've integrated RevenueCat, subscriptions are flowing, and you open the dashboard. Then you open App Store Connect. Then your Stripe dashboard. Three different revenue numbers stare back at you. Which one is right?
This guide cuts through that confusion. It covers every major chart type, explains precisely what each metric measures, flags the gotchas that silently corrupt automated reports, and shows how to extract raw data for custom analytics.
1. Why Your RevenueCat Numbers Never Match App Store Connect or Stripe
Before you trust any chart, you need to understand why discrepancies are expected, not bugs.
RevenueCat operates on transaction dates. Apple's financial reports operate on settlement dates.
A subscription renewal due November 29th that fails and retries successfully on December 4th during the grace period will appear in RevenueCat on November 29th (when the payment was due) and in Apple's financial report in December (when it settled). Same transaction, different month. Source
Apple uses fiscal months. RevenueCat uses calendar months.
Apple's January 2025 fiscal month ran from December 29, 2024 to February 1, 2025. Comparing a calendar-month Revenue chart against an Apple fiscal-month financial report will always produce a discrepancy. To align them, you must set a custom date range in the RevenueCat Revenue chart that matches Apple's fiscal period exactly. Source
Tax and commission calculations are estimates in RevenueCat.
RevenueCat estimates taxes by looking up the proceeds Apple quotes for a given price in a given country, then back-calculates the implied tax rate. Apple's actual financial reports are anonymized, meaning RevenueCat cannot connect store report data to individual transactions. For authoritative tax figures, always use the payment processor's (Apple, Google, Stripe) own reports, not RevenueCat data. Source
Three additional root causes of discrepancies:
- You migrated to RevenueCat — receipts must be sent through the SDK or API to appear in Charts.
- Definition disagreements — Google considers trials active subscriptions; RevenueCat does not.
- Missed SDK events — Charts are generated from purchase receipts saved in RevenueCat, not client-side event logs. If a receipt wasn't sent, the transaction doesn't exist in Charts. Source
Revenue chart terminology you must understand:
| Measure | What it means |
|---|---|
| Revenue | Total revenue generated in a period, minus refunds from transactions in that period |
| Revenue (net of taxes) | Revenue minus estimated store tax deductions (VAT, DST, etc.) |
| Proceeds | Revenue minus estimated taxes and store commission |
When reconciling against App Store financial reports, compare RevenueCat's Proceeds against Apple's Extended Partner Share (Quantity × Partner Share). Source
2. The Three Revenue Metrics You Must Understand
MRR — The Velocity Metric
Monthly Recurring Revenue (MRR) measures the normalized revenue of your active paid subscriptions, converted to a monthly value. It does not map directly to cash received in a given month.
The normalization works like this:
- A $8/month subscription contributes $8 to MRR
- A $120/year subscription contributes $10 to MRR ($120 × 1/12)
- A $9.99/week subscription contributes $39.96 to MRR ($9.99 × 4)
MRR is a snapshot metric, calculated at the end of each period based on the count of active subscriptions at that moment. It does not count cancelled subscriptions whose access hasn't expired yet. Source
When to use MRR: Tracking business velocity and comparing growth across periods when you have a mix of monthly and annual subscribers. Use the MRR Movement chart alongside it to see which segments are driving growth or churn.
Revenue — The Actual Cash Metric
Revenue is the total revenue from actual transactions in a period, minus refunds. Unlike MRR, an annual subscriber's $120 payment appears all in the month the transaction occurred, not spread across twelve months.
This means Revenue fluctuates more than MRR — a spike in annual upgrades will show a revenue jump with no corresponding MRR change of the same magnitude. The Revenue chart also includes non-subscription revenue: consumables, one-time purchases, and non-renewing subscriptions. Source
When to use Revenue: Daily and monthly health monitoring, trend analysis, and reconciliation attempts with financial reports.
ARR — The Forward-Looking Projection
Annual Recurring Revenue (ARR) is simply MRR × 12. It is an annualized estimate of recurring revenue, not a count of actual transactions. Because it inherits from MRR, ARR includes all active paid subscriptions — even those with auto-renewal disabled. If churning subscriptions aren't replaced by new ones, ARR will overstate what you'll actually collect over the next twelve months. Source
When to use ARR: Benchmarking business scale, investor reporting, and comparing against SaaS industry benchmarks. Do not use ARR as a revenue forecast without accounting for expected churn.
3. Churn vs. Retention — They Measure Different Things
Churn Rate: A Point-in-Time Ratio
Churn rate = (Churned Actives / Actives at start of period) × 100
- Actives: Paid, active (unexpired) subscriptions at the beginning of the period.
- Churned Actives: Paid subscriptions that expired within the period, minus those that resubscribed.
- A cancelled subscription (auto-renewal disabled) is not churned until the subscription actually expires.
- Churn can be negative: if resubscriptions outnumber expirations in a period, the churn rate goes negative, meaning the active base grew even without new subscribers. Source
Where churn misleads you: Churn rate is a ratio across all active subscriptions at a point in time. If you acquired a large cohort of annual subscribers eight months ago, your current churn rate tells you nothing about how that specific cohort is renewing when their first year ends. Churn rate also doesn't distinguish between a subscriber who churned after 30 days versus one who churned after 24 months.
Subscription Retention: Cohort-Based Renewal Tracking
Subscription Retention tracks how paying subscriptions in a cohort (grouped by subscription start date) renew over successive billing periods.
Formula (by subscription start date):
Retained Subscriptions at period X / Total Subscriptions in cohort = Retention Rate
Retention is always calculated relative to the initial cohort size — not relative to the prior period. Period 3 retention means the percentage of the original cohort that was still active after 3 renewal periods, not the percentage that survived from period 2 to period 3. Source
Where retention misleads you: Retention tables look great until you realize that recent cohorts have had fewer opportunities to churn. A cohort from last month showing 95% retention at Period 1 is mathematically almost guaranteed — they've only had one renewal opportunity. Compare only mature cohorts (6+ months old for monthly subscribers, 2+ years for annual subscribers) when drawing conclusions.
Practical rule: Use churn rate for weekly health monitoring. Use subscription retention for product decisions — whether a pricing change, feature update, or onboarding change actually improves long-term subscriber loyalty.
4. LTV: Three Flavors, Three Use Cases
Realized LTV per Customer (ARPU)
Formula: Total Revenue from cohort (minus refunds) / New Customers in cohort
Cohorted by the earliest of: first seen date (first app open) or first purchase date. A user who first opened your app in April but paid in May is in the April cohort.
The Customer Lifetime selector controls how far post-first-seen revenue is counted. Setting it to 30 days means only revenue generated within the customer's first 30 days is included. Setting it longer pushes the "incomplete period" boundary further back. Source
When to use: Evaluating total acquisition value across all customers — paying and non-paying. Comparing against Customer Acquisition Cost (CAC) to assess payback period.
Realized LTV per Paying Customer (ARPPU)
Formula: Total Revenue from cohort (minus refunds) / New Paying Customers in cohort
Same cohorting by first seen date, but the denominator only includes customers who actually made a payment. This will always be higher than Realized LTV per Customer.
Critical detail: Paying customers are still cohorted by first seen date, not first payment date. If your app has a 7-day trial and you set Customer Lifetime to 7 days, the cohort will show zero paying customers — every trial conversion happens on day 7 or later. Set Customer Lifetime to at least trial length + some buffer. Source
When to use: Assessing the revenue quality of customers who do convert — useful for measuring impact of pricing changes on paying subscriber value.
Predicted LTV
The Prediction Explorer extends beyond realized revenue by adding ML-based forward projections. RevenueCat builds survival curves from its dataset of 50k+ apps and 450M+ subscriptions, fits statistical distributions to subscription data for each product, and projects renewal probability over 24 months.
As of January 2026: LTV predictions now include trial (non-paying) subscriptions, weighted by their historical conversion probability. If a product has a 40% trial-to-paid conversion rate and a predicted $100 LTV for converted subscribers, the trial subscription contributes $40 to predicted LTV. This reduces prediction volatility in early cohort periods where trial outcomes are still uncertain. Source
Predictions are made for: - Active paid subscriptions that are not cancelled or expired - Active trial subscriptions weighted by historical conversion probability
Predictions run up to 24 months from a subscription's first purchase date. Data shown in light green or yellow indicates predicted (not yet realized) revenue. Source
When to use: Quarterly strategic reviews. Comparing the predicted 12-month LTV of monthly vs. annual subscribers to optimize your paywall's default offering. Do not use Predicted LTV for financial commitments — it is a probabilistic estimate, not a guarantee.
5. Charts v3: Real-Time Analytics and New Dimensions
Charts v3 (currently in beta) rebuilds the underlying data model with several practical changes:
Real-time updates: Previously, charts refreshed every 2–12 hours depending on the dataset. In Charts v3, almost all charts update in real-time. This matters for monitoring a new paywall, a pricing experiment, or an acquisition campaign on launch day. Source
Improved dimensions: - Platform now reports a customer's first seen platform (not last seen), making acquisition channel analysis stable over time. - Country now reports the country associated with the customer's app store account when available, falling back to IP-based location. - New dimensions: Custom Attributes and Ad Attribution (Apple Search Ads and other sources).
Refund behavior change: In Charts v3, refunds no longer retroactively modify historical periods. Instead, the refund's revenue impact is recorded on the date the refund occurred, keeping historical data stable.
Supported stores: App Store, Play Store, Stripe, and RevenueCat Web Billing. Amazon, Roku, and Paddle support is planned. Source
Unified subscription definition: Product changes and resubscriptions are now modeled as distinct events (a product change terminates the old subscription and creates a new one), which improves consistency across charts that previously handled these cases differently.
6. Programmatic Access: Scheduled Data Exports
For developers who need to run custom SQL, feed a data warehouse, or build dashboards with business-specific logic, Scheduled Data Exports deliver daily gzip-compressed CSV files to your cloud storage. Source
Destinations: Amazon S3, Google Cloud Storage, Azure Blob Storage. Enterprise plans can receive exports more frequently than once per day for new and updated transactions only.
Current schema: Data Export Version 5 (latest). Key additions in v5:
- first_seen_time: First date RevenueCat saw the customer (used in all LTV and Conversion Rate chart cohorting).
- offer and offer_type: Track promotional offer usage per transaction.
- auto_resume_time: For paused Play Store subscriptions.
Key fields for retention analysis:
| Field | Description |
|---|---|
rc_original_app_user_id |
Stable customer identifier |
product_identifier |
Product purchased |
product_duration |
Standard product duration (e.g., P1M, P1Y) |
purchased_at |
Transaction date (UTC) |
expiration_at |
Subscription expiry date (UTC) |
is_trial_period |
true if this transaction is a trial |
price_in_usd |
Price at time of transaction (set to 0 if refunded) |
tax_percentage |
Estimated tax rate |
commission_percentage |
Estimated store commission rate |
first_seen_time |
Date customer was first seen (v5+) |
Python: Monthly Cohort Retention from Exported Data
The following script reads a RevenueCat Data Export v5 CSV (e.g., from S3) and calculates monthly cohort retention, mimicking the logic from the Subscription Retention chart.
import pandas as pd
from datetime import datetime
# Load the export — replace with s3fs, gcsfs, or local path as needed
df = pd.read_csv("revenuecat_export.csv.gz", compression="gzip", low_memory=False)
# Work only with paid (non-trial) transactions
paid = df[df["is_trial_period"] == False].copy()
# Parse dates — RevenueCat exports timestamps in UTC ISO format
paid["purchased_at"] = pd.to_datetime(paid["purchased_at"], utc=True)
paid["expiration_at"] = pd.to_datetime(paid["expiration_at"], utc=True)
# Identify the first paid transaction per subscription (rc_original_app_user_id + product)
first_paid = (
paid.sort_values("purchased_at")
.groupby(["rc_original_app_user_id", "product_identifier"])
.first()
.reset_index()
)
# Cohort = the calendar month of the subscription's first paid transaction
first_paid["cohort_month"] = first_paid["purchased_at"].dt.to_period("M")
# For each subsequent transaction, calculate which renewal period it represents
# by comparing its purchase date to the subscription's start date
paid = paid.merge(
first_paid[["rc_original_app_user_id", "product_identifier", "purchased_at", "cohort_month"]],
on=["rc_original_app_user_id", "product_identifier"],
suffixes=("", "_first"),
)
paid["months_since_start"] = (
(paid["purchased_at"].dt.to_period("M") - paid["cohort_month"])
.apply(lambda x: x.n)
)
# Cohort size = distinct subscribers in each cohort month
cohort_sizes = first_paid.groupby("cohort_month")["rc_original_app_user_id"].nunique()
# Count retained subscribers per cohort per renewal period
retention = (
paid[paid["months_since_start"] > 0] # exclude the initial purchase
.groupby(["cohort_month", "months_since_start"])["rc_original_app_user_id"]
.nunique()
.reset_index(name="retained")
)
# Calculate retention rate: retained / cohort size (not relative to prior period)
retention["cohort_size"] = retention["cohort_month"].map(cohort_sizes)
retention["retention_rate"] = retention["retained"] / retention["cohort_size"]
# Pivot to a readable cohort table
cohort_table = retention.pivot(
index="cohort_month",
columns="months_since_start",
values="retention_rate",
)
print(cohort_table.to_string(float_format="{:.1%}".format))
Note: This script approximates RevenueCat's Subscription Retention chart. For products with billing retry periods, grace period transactions are excluded from RevenueCat's retention count (as of July 2024). The export's
is_in_grace_periodfield can be used to replicate that exclusion. For full sample queries matching each chart's exact definition, see the Scheduled Data Exports sample queries.
7. Incomplete Periods: The Gotcha That Breaks Dashboards
This is the single most common mistake developers make when building automated reports off RevenueCat Charts.
How Incomplete Periods Work
Event-date charts (Revenue, MRR, Active Subscriptions): The current period is always incomplete. If you pull today's Revenue in a monthly view, you are reading a partial month. A monthly Revenue report in week 2 will show roughly half of what the final value will be — reading it as "complete" data will make month-over-month trends look like dramatic declines that don't exist. Source
First-seen-date cohort charts (Realized LTV, Initial Conversion): The incomplete period is not just "today" — it is a rolling window equal to the Customer Lifetime or Conversion Timeframe setting. If you set Customer Lifetime to 90 days, then every cohort from the last 90 days is incomplete. Changing the Customer Lifetime to 180 days doubles the incomplete window. Source
Example: You have an automated Slack report that fires every Monday morning and reads the "previous month" Realized LTV per Customer with a 30-day Customer Lifetime. On the first Monday of the month, last month's cohort is only 7–10 days into its 30-day maturation window. The LTV value you're reading is wildly incomplete. The cohort won't be mature enough to read reliably until 30 days after the last customer in that cohort was first seen.
Rules for Automated Reports
- Never read the current period as complete for any event-date chart.
- For LTV charts, only read cohorts where
current_date - cohort_end_date > Customer Lifetimein days. - For Conversion charts, only read cohorts where
current_date - cohort_end_date > Conversion Timeframein days. - Add explicit staleness guards to your pipeline: if the latest exportable period is less than
Customer Lifetimedays old, skip it and emit a warning rather than writing a misleading value.
The RevenueCat UI renders incomplete periods in a visually distinct style (greyed out or flagged). Replicate that logic in your own dashboards — mark any period that can't yet be mature as [INCOMPLETE] rather than displaying the partial number as final.
8. Actionable Monitoring Checklist
Based on the metric definitions above, here is a structured monitoring cadence:
Daily
- Revenue: Is today's transaction volume tracking in line with the same weekday from prior weeks? Sudden drops may indicate a store outage, a broken payment flow, or an SDK issue.
- Active Subscriptions: Is the count moving in the expected direction? Use the Active Subscriptions Movement chart (new vs. churned) to distinguish acquisition growth from churn improvement.
Weekly
- MRR movement: Has MRR increased or decreased this week? Segment by Store and Product Duration to identify whether a specific product or platform is driving movement.
- Churn rate: Is churn rate stable, rising, or falling? Segment by country and product duration to find the subscriber segments with the weakest retention. Source
Monthly
- Subscription Retention cohorts: Read the cohort table for subscriptions started 3–12 months ago (avoid incomplete recent cohorts). Are renewal rates holding steady at Period 2, 3, and 6? A decline in Period 2 retention (the first renewal after the initial billing cycle) is the earliest signal of product-market fit problems. Source
- Realized LTV per Customer: Compare 30-day LTV for cohorts that are now at least 30 days old. Is LTV per customer increasing across acquisition cohorts, or flattening? Connect changes to what was different in your product or marketing during those months.
Quarterly
- Predicted LTV: Review the 12-month and 24-month predicted LTV from the Prediction Explorer. Are the model's survival curves for your monthly product deteriorating or improving relative to last quarter? Source
- Paywall LTV: If you're using RevenueCat Paywalls, review the Paywall LTV chart to compare realized LTV per viewer across different paywall designs. This chart cohorts by first paywall impression and attributes all subsequent revenue from customers who converted within 3 days. Source
Sources
- Charts Overview
- Reconciling with App Store Financial Reports
- Taxes and Commissions
- Monthly Recurring Revenue (MRR) Chart
- Revenue Chart
- Annual Recurring Revenue (ARR) Chart
- Churn Chart
- Subscription Retention Chart
- Realized LTV per Customer Chart
- Realized LTV per Paying Customer Chart
- Prediction Explorer
- Charts v3 (Real-Time Charts)
- Scheduled Data Exports
- Data Export Version 5
- Charts Feature: Incomplete Periods
- Paywall LTV Chart