← Back to Metrics

Subscription Renewal Rate

Also known as: Renewal Rate, Subscription Retention Rate, Subscription Continuation Rate, Term Renewal Rate

RetentionmetricE-commerce: Customer Retention, Loyalty & LTVSubscription CommerceE-commerce

Subscription Renewal Rate is the percentage of paid subscription terms due for renewal in a period that were successfully charged for the next billing term, including renewals recovered within the payment grace (dunning) window. It is the leading retention signal for subscription commerce (replenishment, subscribe-and-save and paid membership programmes): a decline isolates voluntary cancellations or failed payments before they surface as lost recurring revenue.

Business Use Case

1️⃣ The Retention Marketing team reviews the monthly rate by plan and billing frequency and, when a cohort drops more than 3 points month over month, launches pre-renewal reminder and save-offer campaigns for the terms due in the next 30 days. 2️⃣ The Finance team applies the trailing 3-month rate to the terms due in the next quarter to forecast renewal revenue and recurring revenue in the budget. 3️⃣ The Payments / Revenue Operations team watches the involuntary non-renewal share and, when it rises, tunes dunning retry schedules and card-updater settings. 4️⃣ The Merchandising team compares the rate across subscription products and pack sizes and changes delivery cadence or default quantities for products with below-average renewal.

Business Criticality

High

Journey / Navigation Area

Monetization

Owning Function

Marketing

Scope

User

Formula

(Subscription Terms Renewed and Paid within the Grace Window / All Paid Subscription Terms Due for Renewal in the Period) × 100

Calculation Notes

1️⃣ Denominator = every paid subscription term whose end (renewal due) date falls in the reporting period, including subscriptions the customer cancelled before the due date; those count as non-renewals and are never removed from the base. 2️⃣ Numerator = due terms with a paid renewal invoice (billing_reason = subscription_cycle or subscription_update) covering the next term (invoice period start = due date), paid from 1 day before the due date up to the end of the 7-day payment grace (dunning) window. 3️⃣ Report a period only after its last due date plus the grace window has passed; otherwise late recoveries are missing and the rate is understated. 4️⃣ Exclude free-trial terms (trial-to-paid conversion is a separate metric), test subscriptions and merchant-initiated terminations (fraud, policy); keep paused subscriptions out of the base until they resume. 5️⃣ Plan upgrades, downgrades and billing-interval switches at renewal count as renewed; count each subscription term once, even when a customer holds several subscriptions. The metric is term-weighted; revenue-weighted renewal (renewed recurring revenue / recurring revenue due) is reported separately and never blended into this figure. 6️⃣ Break out voluntary non-renewals (customer cancellation) and involuntary ones (payment failure after dunning) because they need different fixes; do not compare billing frequencies in one blended number, since a monthly and an annual rate describe very different exposure windows. 7️⃣ Value action by industry: E-commerce / Retail = paid replenishment or subscribe-and-save order invoice for the next cycle; Membership retail = paid annual or monthly membership fee; SaaS = paid invoice for the next contract or billing term; Media = successful recurring charge for the next access period.

Technical Details

Measure TypePercentage
Aggregation WindowMonthly, Quarterly, Yearly

Events

SQL Queries

Google Analytics 4 (BigQuery)
-- ==========================================
-- 1. GOOGLE BIGQUERY SQL
-- ==========================================
-- Subscription Renewal Rate by renewal month from native billing tables.
-- Base: every paid term due in the month (cancelled-before-due terms stay in as non-renewals).
-- Table and column names (subscription_periods, subscriptions, invoices; is_trial, is_paused, is_test,
-- termination_reason, billing_reason, period_start, paid_at) are a normalized billing schema: map them to your source (e.g. Stripe, Recharge).
WITH due_terms AS (
  SELECT
    p.subscription_id,
    p.period_end,
    DATE_TRUNC(DATE(p.period_end), MONTH) AS renewal_month
  FROM `your-project.billing.subscription_periods` AS p
  JOIN `your-project.billing.subscriptions` AS s
    ON s.subscription_id = p.subscription_id
  WHERE p.is_trial = FALSE
    AND COALESCE(p.is_paused, FALSE) = FALSE  -- paused at the due date: out of the base until it resumes
    AND s.is_test = FALSE
    AND COALESCE(s.termination_reason, '') NOT IN ('fraud', 'merchant_terminated')
    AND p.period_end >= TIMESTAMP(DATE_TRUNC(DATE_SUB(CURRENT_DATE(), INTERVAL 12 MONTH), MONTH))
    -- whole renewal months only, reported once the last due date plus the 7-day grace window has passed
    AND DATE(p.period_end) < DATE_TRUNC(DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY), MONTH)
),
renewed_terms AS (
  SELECT DISTINCT d.subscription_id, d.period_end
  FROM due_terms AS d
  JOIN `your-project.billing.invoices` AS i
    ON i.subscription_id = d.subscription_id
   AND i.billing_reason IN ('subscription_cycle', 'subscription_update')  -- plan / interval changes at renewal count as renewed
   AND i.period_start = d.period_end  -- invoice covers the next term
   AND i.status = 'paid'
   AND i.paid_at >= TIMESTAMP_SUB(d.period_end, INTERVAL 1 DAY)
   AND i.paid_at < TIMESTAMP_ADD(d.period_end, INTERVAL 7 DAY)
)
SELECT
  d.renewal_month,
  COUNT(*) AS terms_due_for_renewal,
  COUNT(r.subscription_id) AS terms_renewed,
  ROUND(100 * SAFE_DIVIDE(COUNT(r.subscription_id), COUNT(*)), 2) AS subscription_renewal_rate_pct
FROM due_terms AS d
LEFT JOIN renewed_terms AS r
  ON r.subscription_id = d.subscription_id
 AND r.period_end = d.period_end
GROUP BY d.renewal_month
ORDER BY d.renewal_month;
Adobe Experience Platform (AEP Query Service)
-- ==========================================
-- 2. ADOBE AEP QUERY SERVICE SQL
-- ==========================================
-- Subscription Renewal Rate by renewal month from billing datasets ingested into AEP.
-- Base: every paid term due in the month (cancelled-before-due terms stay in as non-renewals).
-- Table and column names (billing_subscription_periods, billing_subscriptions, billing_invoices; is_trial, is_paused, is_test,
-- termination_reason, billing_reason, period_start, paid_at) are a normalized billing schema: map them to your source (e.g. Stripe, Recharge).
WITH due_terms AS (
  SELECT
    p.subscription_id,
    p.period_end,
    DATE_TRUNC('month', p.period_end) AS renewal_month
  FROM billing_subscription_periods AS p
  JOIN billing_subscriptions AS s
    ON s.subscription_id = p.subscription_id
  WHERE p.is_trial = FALSE
    AND COALESCE(p.is_paused, FALSE) = FALSE  -- paused at the due date: out of the base until it resumes
    AND s.is_test = FALSE
    AND COALESCE(s.termination_reason, '') NOT IN ('fraud', 'merchant_terminated')
    AND p.period_end >= DATE_TRUNC('month', CURRENT_DATE - INTERVAL '12' MONTH)
    -- whole renewal months only, reported once the last due date plus the 7-day grace window has passed
    AND p.period_end < DATE_TRUNC('month', CURRENT_DATE - INTERVAL '7' DAY)
),
renewed_terms AS (
  SELECT DISTINCT d.subscription_id, d.period_end
  FROM due_terms AS d
  JOIN billing_invoices AS i
    ON i.subscription_id = d.subscription_id
   AND i.billing_reason IN ('subscription_cycle', 'subscription_update')  -- plan / interval changes at renewal count as renewed
   AND i.period_start = d.period_end  -- invoice covers the next term
   AND i.status = 'paid'
   AND i.paid_at >= d.period_end - INTERVAL '1' DAY
   AND i.paid_at < d.period_end + INTERVAL '7' DAY
)
SELECT
  d.renewal_month,
  COUNT(*) AS terms_due_for_renewal,
  COUNT(r.subscription_id) AS terms_renewed,
  ROUND(100.0 * COUNT(r.subscription_id) / NULLIF(COUNT(*), 0), 2) AS subscription_renewal_rate_pct
FROM due_terms AS d
LEFT JOIN renewed_terms AS r
  ON r.subscription_id = d.subscription_id
 AND r.period_end = d.period_end
GROUP BY d.renewal_month
ORDER BY d.renewal_month;

Source Data

Backend Billing (normalized subscription periods and invoices model, e.g. modelled from Stripe / Recharge billing data)

Dependencies

Prerequisite: List the dependencies required for this Metric

Events:

subscription-startsubscription-cancellation

Dimensions:

subscription-planbilling-frequencysubscription-status

Report Attributes

Subscription Plan Billing Frequency Renewal Cycle Number Acquisition Cohort Payment Method Country

Recommended Reporting Views

Views
Subscription Performance DashboardCustomer Retention DashboardExecutive Overview

Segment Eligibility

true

Governance

Data SensitivityInternal

Derived KPIs

Governance

Created bydevyendarm
Created on9/11/2026
Last modified bydevyendarm
Last modified on9/19/2026
Version1.0.0
Validation stateqa passed
StatusPUBLISHED

GitHub

View File on GitHubcatalog/metrics/subscription-renewal-rate.yml

Community Discussion