Revenue Analytics counts canceled Stripe subscriptions as active when subscription rows are stale
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 39.9k
- Forks
- 3.4k
- Avg merge
- 6h 51m
- Merged PRs (30d)
- 232
Description
Bug
Revenue Analytics' subscription, customer, and LTV charts can be wrong when the data warehouse holds stale Stripe subscription rows. Subs canceled after their initial sync stay counted as active forever; churn never increments; LTV stays empty. MRR / Gross revenue look correct.
Repro
- Set up a Stripe data warehouse source with the default Subscription schema (append-only incremental, keyed on
created). - Have at least one subscription that gets canceled in Stripe after it was first synced.
- Open Revenue Analytics, look at any period after the cancellation.
Expected: the canceled sub falls out of "active" and appears in churn after its ended_at.
Actual: it stays counted as active forever; churn never increments; LTV chart is empty.
Root cause
Stripe subscription sync is append-only by created timestamp (posthog/temporal/data_imports/sources/stripe/settings.py:78, source.py:262 - supports_incremental=False, supports_append=True). The DWH only fetches subs with new created values; existing rows are never re-fetched. When Stripe populates ended_at on cancellation, our copy of the row stays with ended_at = NULL.
The Revenue Analytics subscription view passes ended_at straight through (products/revenue_analytics/backend/views/sources/stripe/subscription.py:55), and the metrics query treats NULL ended_at as still active (_period_gteq_expr in revenue_analytics_query_runner.py:469-482 short-circuits to true when isNull(left)).
Result:
- Subscription / customer counts inflate as canceled subs accumulate
- Churn check (
_period_eq_expronended_at) never fires, sochurned_customer_count = 0 - LTV
multiIfreturnsNULLwhenchurned_customer_count = 0, so the series is empty (revenue_analytics_metrics_query_runner.py:204-209)
MRR is unaffected because it's driven by invoices; when billing stops, no new invoices arrive and MRR drops naturally.
Fix options
- Add a merge / upsert sync mode for Stripe subscriptions in the data warehouse so existing rows update.
- Auto-schedule periodic full refresh of the Subscription schema as a workaround.
- Land the durable fix in Customer Analytics if Revenue Analytics stays in maintenance mode.
Customer workaround today: trigger a full refresh on the Subscription schema in DWH settings, and repeat periodically.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with posthog/temporal/data_imports/sources/stripe/settings.py and source.py, then read products/revenue_analytics/backend/views/sources/stripe/subscription.py and the expressions in revenue_analytics_query_runner.py. Compare the available fix options and trace how ended_at reaches the metrics queries. Done means canceled subscriptions are no longer active, churn increments after ended_at, and LTV is populated.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- analytics, data-engineering
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100