If you run a subscription platform for creators, a patron who stops watching is a patron about to cancel. The signal shows up in view data weeks before the failed renewal does: watch time falls, sessions get further apart, and then the card doesn't charge. This article turns that data into a churn dashboard, plus the per-creator view you can hand to each creator on your platform.
The whole thing runs on one export: patron health, a creator scorecard, tier performance, the clips your creators should cut, and the win-back list for patrons cooling off before renewal.
How the data flows
FastPix Player SDK ──▶ FastPix Video Data ──▶ CSV export ──▶ chdb ──▶ churn dashboard + nudges
(web / mobile / TV, (watch time, completion, (this article) (creator scorecard,
patron + creator + device, replay events per view) tier perf, clips)
tier in custom dims)creator-platform-sample-synthetic.csv: https://drive.google.com/file/d/1zqnSTmmr61X0Eu-z-_ph84YaqHRnQomA/view?usp=sharing
Illustrative synthetic data (not real patrons): ~280 patrons across 7 creators and 3 subscription tiers over an 8-week window, with the full playback event stream on every view. Columns mirror a real FastPix Video Data export. Every snippet runs against it. No FastPix account yet? Start free with $25 credit (no credit card) and build this on your own platform.
Part 1: Get view data flowing from your player
Playback happens in your player. FastPix Video Data captures every interaction from inside it: it dedupes the beacons, stitches events into sessions, adds geo and device data, and computes quality scores, across millions of concurrent views when you need it. What you export is one clean row per view, with a patron ID and the full playback event stream on every row.
Already collecting views with FastPix? Skip to Part 2. New here? Setup is about ten minutes.
Step 1: Add the player (or add monitoring to the one you have)
<script src="https://unpkg.com/@fastpix/[email protected]/dist/player.js"></script>
<fastpix-player playback-id="YOUR_PLAYBACK_ID" stream-type="on-demand"></fastpix-player>Patrons watch on the phone, the laptop, and the living-room TV, so cover every surface. The monitoring SDK captures the same data from hls.js, video.js, native mobile, and TV players:
import fastpixMetrix from "@fastpix/data-core";
fastpixMetrix.tracker(videoElement, {
hlsjs: hls,
Hls: Hls, // both are required
data: { workspace_id: "YOUR_WORKSPACE_KEY" },
});Step 2: Tag each view with patron, creator, and tier
The churn questions all need these three. Pass them in custom dimensions so every view can be grouped by who watched, whose content it was, and which subscription tier they pay for:
fastpixMetrix.tracker(videoElement, {
hlsjs: hls,
Hls: Hls,
data: {
workspace_id: "YOUR_WORKSPACE_KEY",
custom_2: patron.id, // who is watching
custom_6: creator.handle, // whose content it is
custom_8: patron.tier, // Free / Supporter / Insider
},
});Step 3: Export the views
Export from the Video Data dashboard (Views → Export CSV) or the export API, which is what a nightly job pulls. The columns this article uses: viewer_id, subscriber_since, subscription_tier, custom_creator, video_title, video_duration, view_start, view_max_playhead_position (how far they got), view_total_content_playback_time (watch time), device_type, and events (the playback stream, used for the clip suggestions in Part 3).
Part 2: Build the dashboard
The stack is chdb (embedded ClickHouse, pip install chdb). Same SQL later runs on a real ClickHouse.
Step 4: Patron health from days since last watch
Load views, sum watch time per patron, and classify each patron by how recently they last watched. On a monthly renewal cycle, idle time is the earliest churn signal you have.
import chdb, pandas as pd, datetime
v = chdb.query("""
SELECT viewer_id AS patron, subscriber_since AS subbed, view_start AS watched_at,
subscription_tier AS tier, custom_creator AS creator,
CAST(video_duration AS Int64) AS dur,
CAST(view_max_playhead_position AS Int64) AS reach_ms,
CAST(view_total_content_playback_time AS Int64) AS watch_ms, events
FROM file('creator-platform-sample-synthetic.csv', CSVWithNames)
""", "DataFrame")
v["watch_min"] = v["watch_ms"] / 60000.0
end = pd.Timestamp(datetime.date(2026, 3, 2))
per = v.groupby("patron").agg(
tier=("tier","first"), watch_min=("watch_min","sum"),
last_watch=("watched_at","max")).reset_index()
per["days_idle"] = (end - per["last_watch"]).dt.days
per["health"] = per["days_idle"].apply(
lambda d: "Active" if d <= 14 else ("Cooling" if d <= 30 else "Churn-risk"))A patron is Active if they watched in the last 14 days, Cooling at 15–30 days idle, and Churn-risk beyond that. On the sample: 48% Active, 35% Cooling, 17% Churn-risk. The Cooling group is where a win-back still works.
Step 5: Creator scorecard
Group by home creator (each patron's most-watched) for patron retention and median watch time. This is the same view you expose to each creator, and the one your own retention team reads across the platform.
prim = v.groupby("patron")["creator"].agg(lambda s: s.mode().iat[0]) # home creator
mem_health = dict(zip(per.patron, per.health))
# retention by home creator: share of a creator's patrons still ActiveThe scorecard ranks creators by whether their patrons stay, not by how much they post. In the sample, Marisol Vega keeps 64% of her patrons active on 126 minutes of median watch, while two creators with similar watch time (around 70 minutes) retain very differently, 50% versus 42%. Upload count and raw views do not predict retention; watch time and the retention column do.
Step 6: Tier performance
Every subscription tier should earn its price in retention. Group patron health and median watch by tier to see whether each price point pulls its weight.
for t in ["Insider", "Supporter", "Free"]:
sub = per[per.tier == t]
print(t, len(sub), sub.watch_min.median(),
(sub.health == "Active").mean())In the sample the tiers line up the way you would hope: Insider 57% active, Supporter 50%, Free 44%, with median watch rising alongside price. When a paid tier retains no better than free, that is a packaging problem the data caught before the churn report did.
Step 7: Most-replayed clips from the event stream
The events column carries a playhead position (pt) and a wall-clock timestamp (vt) for every playback event. A backward jump in the playhead after real watching is a replay. Cluster those landings per video and you get the moments patrons rewind to, which are the clips a creator should cut for promotion.
import json
def replay_landings(events_json):
evs = [e for e in json.loads(events_json) if e.get("pt") is not None and e.get("vt")]
return [b["pt"] for a, b in zip(evs, evs[1:])
if b["vt"] - evs[0]["vt"] >= 2000 and (b["pt"] - a["pt"]) < -1000]On the sample this surfaces one clear clip per top creator, the strongest being a 70-second stretch of Marisol Vega's Q&A that patrons rewound 14 times. That is a promo clip your platform can suggest to the creator automatically.
Start using FastPix for free - $25 credit, no credit card required. Build this on your own platform this week. Create your workspace →
Part 3: What the dashboard shows
Cooling patrons are where retention is won. The 35% Cooling group has not churned yet; they have gone quiet. They are the list a win-back campaign should run against, because the Churn-risk group beyond 30 days idle is mostly already gone. Catching patrons in the Cooling window is the whole point of watching idle time instead of waiting for the failed renewal.
Retention ranks creators differently from output. A creator who posts constantly but whose patrons drift is worth less to your platform than one whose smaller audience keeps watching. Only the retention column surfaces that, and it is the column that maps to subscription revenue. Hand the same view to your creators and they will see it too.
Tiers should retain in order, and when they don't you have a packaging problem. Higher tiers retaining better is the sign your pricing matches value. A paid tier that retains like the free one is telling you its extra content isn't landing, which is a product decision, not a churn-team one.
Part 4: Nudges that act on the dashboard
The dashboard is more useful when it drives your messaging. FastPix supplies the signals; your push, email, or in-app engine sends the message.
for p in per.itertuples():
if p.health == "Cooling":
nudge(p.patron, "New from the creators you follow") # win-back before renewal
elif p.health == "Churn-risk":
save_offer(p.patron) # save offer / creator promptOn the sample this produces 98 win-back nudges for Cooling patrons and 48 save offers for Churn-risk patrons. The same signals drive the workflows a creator platform needs:
| Signal | Condition | What you trigger |
|---|---|---|
| Patron cooling | 15–30 days since last watch | Win-back push, new-content digest |
| Churn-risk before renewal | 30+ days idle near renewal date | Save offer, pause-instead-of-cancel prompt |
| Creator retention slipping | Home-patron active rate falling | Prompt the creator, surface their scorecard |
| Most-replayed moment | Rewatches cluster in one segment | Auto-suggest a promo clip to the creator |
How different teams use this
| Team | What they track | The signal that matters |
|---|---|---|
| Creator subscription platform (this article) | Patron health, creator scorecard, tier performance | days since last watch |
| Streaming fitness platform | Member health, instructor scorecard, program funnel | early-habit → retention |
| Online course platform | Learner progress, genuine completion | reach + watch coverage |
Running this on your own data
Point Step 4 at your own export and set two things for your platform: the idle thresholds behind Active / Cooling / Churn-risk (tie them to your renewal cycle, monthly here) and which custom dimensions carry your patron, creator, and tier IDs. Everything else, the scorecard and tier table and clip finder, runs unchanged.
Frequently Asked Questions (FAQs)
How do I predict subscription churn from video data?
Track the number of days since each patron last watched a video, using a unique patron ID. Watch time typically declines and viewing sessions become less frequent weeks before a subscription renewal fails. Patrons who have been inactive for 15–30 days are strong candidates for early win-back campaigns before they cancel.
Which creators actually keep patrons subscribed?
Measure retention by each patron's most-watched creator, then calculate how many of those patrons remain active over time. This ranks creators by their ability to retain subscribers rather than simply by how much content they publish, making it a more meaningful metric for subscription revenue.
Do higher subscription tiers really retain better?
Compare member retention across subscription tiers by measuring the percentage of active patrons in each group. Higher-priced tiers should generally retain users better than free plans. If a paid tier performs no better than the free tier, it may indicate that your pricing or feature packaging needs improvement.
How do I find clip-worthy moments for my creators?
Analyze playback events for backward playhead jumps that occur after viewers have watched normally. These replay clusters reveal moments that patrons found valuable enough to watch again, making them excellent candidates for promotional clips that your platform can recommend automatically.
What does it cost to start?
Getting started is free. You receive a $25 credit with no credit card required. The Video Data free tier includes 100,000 plays per month, and the FastPix Player is free for FastPix customers.





