Average Subscription Duration
Also known as: Average Customer Tenure, Average Subscription Length, Average Subscription Lifetime, Average Subscriber Tenure, Mean Subscription Duration
Subscription specialisation of Average Customer Tenure: mean days from first paid cycle to cancellation, or to period end if still active. Feeds subscription Customer Lifetime Value.
Business Use Case
1️⃣ Finance feeds duration by plan into LTV forecasts and resets CAC ceilings when it falls quarter on quarter.,2️⃣ Marketing sees discount-acquired subscribers lasting less than full-price ones and caps the first-order discount.,3️⃣ Merchandising compares duration by delivery frequency and makes the longest-lasting cadence the default.,4️⃣ Customer Service sees cohorts cancelling around the second cycle and adds a pause offer to the cancel flow.
Business Criticality
High
Journey / Navigation Area
Monetization
Owning Function
Finance
Scope
User
Formula
Calculation Notes
1️⃣ Duration runs from the first successful paid charge to the cancellation effective date; active subscriptions are measured to period end.,2️⃣ Base is every subscription active at any point in the period; free trials that never reach a paid cycle are excluded.,3️⃣ Cancellations scheduled after period end are measured only to period end, so a closed period's value does not change.,4️⃣ Paused periods and skipped shipments stay in the duration; a pause does not end the subscription.,5️⃣ Reactivation within 30 days of cancellation continues the same subscription; a later restart opens a new subscription record.,6️⃣ Involuntary cancellations count and end on the last dunning date; test, staff and fraud-cancelled subscriptions are excluded.,7️⃣ Active durations are right-censored, so the value rises as the programme ages; compare acquisition cohorts of equal age.
Technical Details
Events
SQL Queries
Google Analytics 4 (BigQuery)
-- ==========================================
-- 1. GOOGLE BIGQUERY SQL
-- ==========================================
DECLARE start_date DATE DEFAULT DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY);
DECLARE end_date DATE DEFAULT DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY);
WITH subs AS (
-- Paid subscription records (trials that never reached a paid charge, test, staff and fraud-cancelled excluded); involuntary cancellations end on the last dunning date
SELECT
customer_id,
first_paid_date,
IF(cancellation_type = 'involuntary', last_dunning_date, cancellation_effective_date) AS end_dt
FROM `your-project.crm.subscriptions`
WHERE first_paid_date IS NOT NULL
AND first_paid_date <= end_date
AND NOT is_test
AND NOT is_staff
AND COALESCE(cancellation_reason, '') != 'fraud'
),
flagged AS (
-- A record opens a new subscription unless it reactivates 0 to 30 days after the customer's previous cancellation (overlapping records stay separate)
SELECT
*,
IF(DATE_DIFF(first_paid_date, LAG(end_dt) OVER (PARTITION BY customer_id ORDER BY first_paid_date), DAY) BETWEEN 0 AND 30, 0, 1) AS is_new
FROM subs
),
chained AS (
-- Number the stitched subscriptions per customer
SELECT
*,
SUM(is_new) OVER (PARTITION BY customer_id ORDER BY first_paid_date ROWS UNBOUNDED PRECEDING) AS sub_seq
FROM flagged
),
stitched AS (
-- One row per subscription: first paid charge to final end (NULL while still active); pauses do not end it
SELECT
MIN(first_paid_date) AS first_paid_date,
IF(COUNTIF(end_dt IS NULL) > 0, NULL, MAX(end_dt)) AS end_dt
FROM chained
GROUP BY customer_id, sub_seq
)
-- Mean days from first paid charge to cancellation, or to period end if still active, over subscriptions active at any point in the period
SELECT
ROUND(AVG(DATE_DIFF(LEAST(COALESCE(end_dt, end_date), end_date), first_paid_date, DAY)), 1) AS average_subscription_duration_days
FROM stitched
WHERE COALESCE(end_dt, end_date) >= start_date;Adobe Experience Platform (AEP Query Service)
-- ==========================================
-- 2. ADOBE AEP QUERY SERVICE SQL
-- ==========================================
WITH params AS (
-- Reporting period: last 90 days up to yesterday
SELECT
DATE_SUB(CURRENT_DATE, 90) AS start_date,
DATE_SUB(CURRENT_DATE, 1) AS end_date
),
subs AS (
-- Paid subscription records (trials that never reached a paid charge, test, staff and fraud-cancelled excluded); involuntary cancellations end on the last dunning date
SELECT
s.customer_id,
s.first_paid_date,
CASE WHEN s.cancellation_type = 'involuntary' THEN s.last_dunning_date ELSE s.cancellation_effective_date END AS end_dt
FROM aep_backend_dataset_crm_subscriptions s
CROSS JOIN params p
WHERE s.first_paid_date IS NOT NULL
AND s.first_paid_date <= p.end_date
AND NOT s.is_test
AND NOT s.is_staff
AND COALESCE(s.cancellation_reason, '') != 'fraud'
),
flagged AS (
-- A record opens a new subscription unless it reactivates 0 to 30 days after the customer's previous cancellation (overlapping records stay separate)
SELECT
*,
CASE WHEN DATEDIFF(first_paid_date, LAG(end_dt) OVER (PARTITION BY customer_id ORDER BY first_paid_date)) BETWEEN 0 AND 30 THEN 0 ELSE 1 END AS is_new
FROM subs
),
chained AS (
-- Number the stitched subscriptions per customer
SELECT
*,
SUM(is_new) OVER (PARTITION BY customer_id ORDER BY first_paid_date ROWS UNBOUNDED PRECEDING) AS sub_seq
FROM flagged
),
stitched AS (
-- One row per subscription: first paid charge to final end (NULL while still active); pauses do not end it
SELECT
MIN(first_paid_date) AS first_paid_date,
CASE WHEN COUNT(*) > COUNT(end_dt) THEN NULL ELSE MAX(end_dt) END AS end_dt
FROM chained
GROUP BY customer_id, sub_seq
)
-- Mean days from first paid charge to cancellation, or to period end if still active, over subscriptions active at any point in the period
SELECT
ROUND(AVG(DATEDIFF(LEAST(COALESCE(st.end_dt, p.end_date), p.end_date), st.first_paid_date)), 1) AS average_subscription_duration_days
FROM stitched st
CROSS JOIN params p
WHERE COALESCE(st.end_dt, p.end_date) >= p.start_date;Source Data
CRM
Dependencies
Prerequisite: List the dependencies required for this Metric
Events:
Dimensions:
Report Attributes
Subscription Plan Billing Frequency Acquisition Cohort Acquisition Channel Cancellation Type (Voluntary / Involuntary) First-Order Discount
Recommended Reporting Views
Segment Eligibility
true
Governance
Derived KPIs
Governance
GitHub
catalog/metrics/average-subscription-duration.yml