TrainFlow - Coach Subscription
Product Designer
My role
Designed the coach subscription model, paywall flow, and freeze mechanic - including three concepts rejected after corridor testing
Ran interviews and corridor tests with coaches, then rebuilt the grace period, athlete selection, and freeze duration based on what testing showed
Results
— Free to Paid conversion: 19% · Paywall to payment: 34%
— Freeze to Resume rate within 30 days: 38% - confirming freeze as retention mechanic, not just soft deletion
— Removed three friction points found only after building and testing them - grace period, manual athlete selection, and time-limited freeze
Monetizing existing coaches beat "let's build AI Coach"
There was an internal debate - move toward AI Coach, or monetize what already existed first. We ran both directions through RICE as a team.
AI Coach had higher Reach - the athlete audience is three times larger than the coach audience. But Confidence was low: demand for AI coaching in our niche hadn't been validated, and the feature would be built from scratch. Easy was minimal - ML infrastructure, device data, new UX. Subscription won not because of audience size, but because of predictability - the coach interface already existed, and the pattern was market-proven.
The task wasn't just "launch a paid subscription" - it was finding a form of monetization that wouldn't break the coach's relationship with the product.

9 of 13 platforms cut off athletes with no warning
Before designing anything, I looked at the market. I reviewed more than 30 platforms - TrainingPeaks, TrueCoach, CoachNow, Final Surge, and others.
Most competitors simply cut off the connection to athletes when a subscription expires - hard, with no warning. The only competitor with a freeze mechanic was CoachAccountable, capped at 30 days. Why 30 days? Probably a technical default, not a researched decision. I decided to test that parameter separately.
The paywall should meet motivation, not create a barrier
Core hypothesis: a coach won't pay for a tool until they're sure it fits their process - so the paywall should trigger at the moment of accepting a request, not when entering settings.

The paywall opens the moment the coach tries to accept - not before, not after.
Three hypotheses behind the design decisions:
H-1: A coach converts to paid at the moment of highest motivation - accepting a request - not while passively browsing settings.
H-2: Existing coaches won't leave if the limit doesn't break their current workflow.
H-3: Freeze as a mechanic is worth more than hard deletion.

The paywall only shows what's actually relevant to upgrade to - not the tier already owned.
Grace period looked like a kindness - testing said otherwise
The first version gave coaches a grace period after expiry: a banner reading "Your subscription ended - you have N days to choose a plan or select 4 athletes," with its own modal.

Concept, not shipped - the banner gave coaches a week to think it over. In testing, that's exactly what they did: think it over, and not pay.
In corridor testing, coaches said "why pay now if I have a week," and put off the decision. Grace period solved a problem that didn't exist and created a real one - it delayed conversion. We removed it entirely.

No banner, no grace period - the forced screen appears the moment the subscription ends.
Choosing who gets frozen felt like punishment - so we took that choice away
The first version of the forced screen asked the coach to manually select which 4 athletes to keep active, with a checklist and a live counter ("3 of 4 selected").

Concept, not shipped - coaches froze up here in testing. Choosing who to keep active among their own athletes felt like a punishment, not a feature.
"You're making me choose between my own athletes" - a direct quote from testing. The system now picks automatically - the first four athletes by join date - and the coach just confirms.

No selection screen at all - the system picks, the coach just sees the result
I also changed the CTA on the applicant card: not "Accept request," but "Accept & choose plan" - one tap, and it's clear what happens next.
The biggest fear turned out to be losing the athlete's data, not the price
I ran 5 interviews with coaches already using TrainFlow. The audience was around 30 people at the time, so this covered roughly 15% of it.
The biggest fear turned out to be losing the athlete's data and history when the subscription was cancelled, not the price. "I've been coaching this person for three months - if I don't renew, does it all just disappear?" came up in three of five interviews.
Second insight: coaches see the 4-athlete limit not as a restriction, but as "a free trial run under real conditions."
A one-month freeze that ends in deletion contradicted the exact fear we'd just found
The first version of freeze wasn't indefinite - it had a one-month window. Three days before it expired, the coach got a push notification and an in-app banner warning that paused athletes would be permanently removed, followed by actual deletion from the roster.

Concept, not shipped - a one-month freeze window that ends in permanent removal. This is exactly what the interviews warned against: 'what if I come back later and it's gone?
We removed the time limit entirely. Indefinite storage didn't create meaningful technical cost, and it removed the main fear from the interviews.

No countdown, no deletion - frozen athletes just wait, however long that takes
On the athlete's side, the coach shows a "Collaboration paused by coach" status - no billing details, since it's not their decision.
Reactivation restores everyone at once, not one by one
When the coach renews, every athlete who didn't cancel during the freeze gets automatically restored, with a push: "[CoachName] is back - collaboration resumed." If the coach's account is deleted instead, every affected athlete gets "ended the collaboration" in one pass.
One subscription, three different management screens
Where a coach bought the subscription determines what they can do with it afterward. Apple, Android, and web purchases each carry their own billing rules, and the management screen has to be honest about that instead of pretending they're identical.

No countdown, no deletion - frozen athletes just wait, however long that takes
On iOS, the screen points to managing the subscription through the App Store settings. On Android, it routes to Google Play. On web, cancellation and plan changes happen directly in-app through Stripe. Trying to unify these into one button would have meant either lying about what the button does, or building a fake abstraction layer that doesn't match how the underlying billing actually works. Each platform's screen shows the same plan details - name, renewal date, price - but the action at the bottom honestly reflects where control actually lives.
Analytics were built in before release, not after
I worked with analysts to design the event schema before the feature shipped. Core principle: every event carries its source - the paywall opens from five different places, and without that you see total views, but not where a coach came from or why they didn't pay. We didn't get this right immediately - the first version of the schema had no source field, and I found the gap after walking through the whole flow myself, which we then added together.
We track key moments: paywall opened, plan selected, successful and failed payment, closed without paying, chose to stay on the free plan, subscription cancelled.
Metrics that test the hypotheses:
Free → Paid conversion - the main one, tests whether the paywall's timing is right (H-1).
Paywall → payment - conversion broken down by source, shows which entry point works better.
Freeze → Resume rate - what share of coaches come back after freeze, tests whether freeze works as retention (H-3).
Time to upgrade - how many days a coach thinks before the first payment.
Churn by tier - comparing retention between Pro and Unlimited (H-2).
Working with the team
We worked as a cross-functional team: product designer, iOS and Android developers, backend, QA. Before release, I walked through the entire implemented flow myself and found several discrepancies with the design, which we fixed before launch.
Every restriction has a soft landing
The task wasn't just "build a paywall" - it was designing a model where the coach never feels like they're being punished. Every restriction has a soft landing: hitting the limit - the request stays visible; expiry - a forced screen with two honest exits, no waiting period; freeze - data intact indefinitely, restoration automatic. Monetization is built into the moment of highest motivation - accepting a request - not into passive browsing of settings.