Sports & Media · United States
A live score portal that holds at 40x on match day
A university athletics programme had a fan portal that degraded every match day — live scores arriving up to forty seconds behind the broadcast, the site slowing to a crawl at kick-off, and always-on infrastructure being paid for six days a week when traffic was effectively zero.
- Client
- Collegiate athletics programme
- Published
- 19 November 2025
The client is not named at their request. Figures are as reported by them.
- < 1.8 sec
- Live data latency to client
- 41x
- Match-day peak versus off-day baseline
- 64%
- Off-day infrastructure cost reduction
- 0
- Match days with degraded service
Measured from feed receipt, p95
Across a full season post-launch
The situation
Traffic to the fan portal was near zero for most of the week, then rose roughly fortyfold in the twenty minutes around kick-off and held through the fixture.
The existing build handled this by being permanently large, which was expensive, and it still degraded — because the bottleneck was not capacity. Every fan requesting the live score generated a database query. A hundred thousand people wanting the same number produced a hundred thousand reads of the same row, and when responses slowed, every one of those fans hit refresh.
Live data was arriving up to forty seconds behind the broadcast, which is worse than useless in a stadium where people can hear the crowd around them react first.
What we did
Weeks 1–2 — modelled the actual load. Access logs from the previous season gave us the real curve, which was sharper than the team expected. We load tested the existing build against it and reproduced every failure in a copy of production, which made the subsequent work an engineering exercise rather than an argument.
Weeks 3–8 — rebuilt the read path. A cache-first architecture with the live score as a single small object invalidated on change and fanned out at the edge, rather than composed per request. Personalised elements moved to fragments layered over a cached shell, so one supporter's name in a header no longer made every response unique.
Weeks 9–11 — latency budget end to end. Feed ingestion, processing, publish, edge propagation and client render, each instrumented separately so a regression could be attributed rather than guessed at. We set a budget, alerted on it, and gated releases against it.
Weeks 12–13 — capacity on the fixture list. Scheduled scale-up ahead of each fixture with headroom, scaled back afterwards, rehearsed against a real fixture before the season rather than trusted.
Why caching was the whole answer
Almost every fan in the same moment wants an identical response. Once we accepted that, the problem stopped being how much capacity to buy and became how few origin requests were genuinely necessary.
The answer turned out to be a handful per second regardless of audience size. Match-day infrastructure shrank rather than grew, and the cost reduction came out of the same change that fixed the performance.
What we would do differently
We treated the feed provider as a fixed constraint too early.
Roughly a third of the end-to-end latency was upstream, in the interval between the event occurring and the data reaching us. We engineered hard around our two-thirds and accepted theirs, reporting the combined number.
Midway through the season the client asked their provider directly and found a lower-latency delivery option available on their existing contract. It took one conversation. We had assumed the upstream number was immovable without checking, which is the same mistake we made on a portal integration in another engagement and now have a standing rule about — establish what a third party can actually offer before engineering around what they currently provide.
Where it went next
The programme moved to a NoOps retainer covering match-day operations, which suits a platform whose demand is on a published calendar and whose failures are highly visible.
Automated match reports drafted from the data feed went live the following season, with an editor reviewing before publication. The fan record work — unifying ticketing, merchandise and app identity — is scoped and waiting on a decision about the ticketing platform.
Stack
- Next.js
- TypeScript
- Redis
- Postgres
- CloudFront
- Terraform
- Kubernetes
- Grafana
“The previous build treated match day as a scaling problem. It was a caching problem. Once a hundred thousand identical requests stopped reaching the database, the capacity question mostly went away.”
Want the same conversation about your process?
Bring the workflow that costs you the most time. In thirty minutes you will know whether it is automatable, roughly what it would cost, and where it would fail.
Or email [email protected] · we reply within 1 business day