Ryan Coughlan
← products

personal project · live · product, design & engineering — solo

Crunchtime

Pick the scores, share a link, settle it in a mini-league.

What it is

Crunchtime is a footie prediction game and fantasy league. Every year multiple friend groups of mine go ahead and forecast their end of year tables, with options to update the predictions throughout the season. But the maintenance is always messy - files get lost, spreadsheets get edited, arguments ensue. Crunchtime solves that, you can predict your table or all the matches of a game week, and set up your leagues to run through the whole season, or at intervals of your choosing. When predicting results, an exact score gets you 3 points, the right result gets you 1, and your table amongst your friends gets updated with every result.

The problem with the latter application is that a whole season becomes daunting, and once you miss one round of fixtures you may as well fall off the wagon, so by October the numbers drop and the leaderboard freezes.

With crunchtime I’ve tried to tackle both engagement throughout the year, and getting a group in without friction.

Validating the problem first

Before touching the design I interviewed three user groups, each mattering for different reasons

WhoWhy they mattered
Friends who play every seasonThe end user filling in their predictions a few hours before the fixtures - it all falls down if they stop filling in their picks
Admins of football fan forumsThe organisers - they don’t just bring one player but an entire community. They can be the trigger for network effects
People in football subredditsKeenos - They've tried every app going and have no inclination to be polite about mine

How I asked

I follow the common PM principles: ask about what people did, not what they would do. Opinions about the future, or flattery, are cheap. The value is in understanding people’s actual actions and habits.

So instead of “would you use a prediction app”, here are some of the questions I asked across the segments:

Forum Admins (the organisers):

15 conversations with admins who run prediction competitions for football fan forums. They’re the most important lever for growth as they bring a whole league and broader community with them.

  • Walk me through how you set up last season's competition. What was the biggest pain in the backside?
  • What's the most time consuming bit of running it each week?
  • When someone joins halfway through the season, what do you do?
  • What have you tried to keep people involved after Christmas?

Subreddits and general users

5 conversations with friends and 18 with people from subreddits. The latter mattered because they're not my mates and are disinclined to be flattering, and they’ve often tried every app and solution going.

  • Which prediction or fantasy apps have you used, and which did you stop using? When did you stop?
  • Which leagues do you follow apart from the Premier League?
  • Tell me about the last prediction league you were in. When did you last fill in your picks?
  • Have you paid for anything to do with fantasy football or predictions? What was it, and why?
  • What's the last thing you posted about football that wasn't a result?
  • The last time you missed a deadline, what was going on that week? And what did you do the following week?

Learnings

Some of the key insights I took from this were:

  • The appetite was genuine, but friction and admin killed momentum. Spreadsheets, pinned threads, chasing people for picks - all processes with a horrible hassle-reward balance
  • People try crazy things and put tremendous effort in. Spreadsheet management, multiple WhatsApp groups, homemade bash scripts. If they’re willing to overcome this friction…
  • App fatigue is a factor and nobody wants an account before they’ve felt the value. Any friction on install or sign up is an opportunity to lose people before they’ve even started, so I’m doubling down on being browser based, for now
  • Once people miss a week or two, they’re gone. There’s very rarely a mechanism to keep people engaged or to reintegrate them into actual competition.
  • Late joiners have no incentive to sign up. Some keen admins calculated average points per game, but generally there’s no fair way of integrating new joiners. This is where mini competitions, head to head and last man standing join the roadmap
  • Deadlines are missed because people forget, not because they lose interest. Thus email reminders were born (added to the existing capability to bulk enter scores ahead of time)
  • People don’t drift away from engagement with the actual matches, they drift away from the effort. And once you miss a week, maybe the hill to climb becomes unappealing
  • Admins want control over who’s allowed in their league. This drove the admin control panel and the optional requirement for new joiners to be accepted
  • People care as much about the Champions League as the prem. And it’s easier to engage people, particularly post group-stages, to stick around. I haven’t yet had a chance to canvas fans of other leagues, e.g. fan forums in Germany
  • People love to share and debate their bold calls. So the shareable link, where they can ruffle some feathers in a group chat with a a surprise Arsenal loss, is a great engagement hook

This informed clear priorities for me of: getting rid of the administrative overhead, then the account wall, then fix the October drop off and reengagement

Pressure testing the leakiest assumption

The first assumption to challenge was not whether people enjoyed predictions (the betting markets are all the evidence you need there) or competing with mates, it’s whether they’d overcome the hassle of creating an account. So the first roadmap item to prototype and test was Quick Predict: a login free mode where your pick lives in the URL rather than a database.

Encoding a whole game week into a couple of characters per fixture, so the link never expires and requires no storage, was an interesting engineering challenge.

The growth loop is the product

Two growth loops have been active from the beginning.

The Link

Because the prediction becomes a link, everyone who shares one is doing the advertising for us, and no need to bolt on a referral scheme afterwards. The invite is already the thing people want to send. So the job became removing the friction between a received link and a completed matchday, with the gambit that once somebody has a few predictions they care about, asking them to create an account to link together all their game week data is an easier ask.

The Admin

One code to join a league brings a whole group in. And the weekly review to see “How everyone called it” brings out that competitive edge and the inspiration to keep coming back for bragging rights

A change in priorities

The original plan geared towards: an anonymous, ad supported predictor, followed by accounts with competitions and a paid tier, then a data product. Running the first experiment through the World Cup with my mates this summer rearranged the priorities. What people actually wanted was to compete with each other and win bragging rights, not to admire their own predicted table. Accounts, mini-leagues and join codes got pulled forward into a 2 day sprint to be completed before the group stages of the World Cup were over. Updates to this before the beginning of this season included league approvals and multiple admins per league.

This also drove who I was building for first: The Organiser. The bloke who bothers to run the WhatsApp league is going to be the one to build the whole network, and the glue to keep it going. Taking away the friction of scoring, hassling for predictions and any other maintenance is a big win for them.

Ergo I removed:

  • Ads. They blemish the experience that matters most - the first matchday. No ads until there’s a habit worth disrupting
  • Paywall. A pro tier only comes to the table when people are coming back unprompted (though I’ve features in mind in the roadmap)

Identifying success metrics

Sign ups tell you very little about a 38+ week game. The funnel I optimised for is:

Link opened → game week completed → account created → predictions claimed → return for second match day → third

It’s not the whole season, but you know you have a habit there to build upon at this point.

MomentEventWhy it matters
SetupFirst matchday completed (Quick Predict or account)Shows the initial traction. Measuring the friction between opening the first link and finishing a matchday.
EngagementFirst matchday scored while in a league, with “How everyone called it” viewedIt becomes competition when they're interested in the rest of their league.
ActivatedPredicted 2 consecutive matchdays in a leagueIt becomes a habit and they see recurring value. The main activation metric.

I’m also thinking about league activation. Given the league is what I’m trying to keep alive, it’s arguably even more important. A league is activated when at least 3 members each predict the first matchday.

Another instructive metric has been the share of fixtures with a prediction against them, per league. I’m still fighting that league that goes quiet after a couple of months

How we’re doing so far (October 2026)

StepCountStep conversion
Quick Predict links shared1,240—
Links opened (unique visitors)2,1801.8 opens per share
Matchday completed1,00346% of opened
Account created31131% of completers
Second consecutive matchday (activated)15916% of completers
Third consecutive matchday12679%
Funnel (first 9 gameweeks)
MetricValue
Leagues created64
Leagues activated (≥3 members on first matchday)37 (58%)
Avg members per activated league6.4
Activated players per league created (organiser yield)3.7
Median time, link opened → matchday completed3m 40s
Leagues
GW1GW2GW3GW4GW5GW6GW7GW8GW9
91%89%86%84%84%76%71%69%63%
Fixture coverage per league (activated leagues, mean)

Will people persist?

Ah, the October problem again.

Presently Crunchtime has one way to play - you predict every scoreline, one table for the season. You can arbitrarily choose when to start and finish that table, but that’s for your own management. It’s a good game, but only one shape, and the system rewards the competitive regular who’s likely going to stay anyway. For the person 12 points adrift in October - why bother? Or for those who want to join in January?

The link share mechanism has proved successful for getting people in, but keeping them engaged requires some options in the format, as you can see in the data above

Some options we have going forwards, all revolve around making the scoring rule a choice and every new format a variant rather than an entirely new product. Despite what Malcolm Gladwell says, sometimes people really do want choice. This opens up the following possibilities:

  • Last Man Standing. Pick one team to win each week, never reuse a team, get it wrong and you're out. One minute per week, not indefinitely, is a much easier sell
  • Head-to-head. A rival every weekend, even when the title's gone.
  • Mini competitions. A cup, a one month table, a run in league for the last ten games. Something to win for whoever joined in January.

Last Man Standing is the first up. It's the easiest yes for the player who won't do ten scorelines and won’t commit to 38 weeks. Alongside it, reminders before every lock. It’s a cheap retention feature, it hooks in the forgetful friend and it helps out the league admins.

All of these journeys allow me to keep the two growth mechanisms: the shareable link for the casual predictor and the mini-league join code for the admins to share their competitions.

Shipping like it matters

One roadmap with stable IDs, so we can maintain state and persistence. A staging environment with a demo toolkit that mocks states (locked fixtures, played matchdays, full leaderboards), because you can't design for a state you can't see in August.

Before launch I conducted a pen test: two real privilege escalations found and fixed at the database layer, and added to a regression suite that replays the attacks on every pull request. Side project or not, I treat other people’s data with caution.

built with

  • Next.js
  • TypeScript
  • Supabase
  • Postgres RLS
  • Tailwind
  • Vercel