When there is no last-year's-numbers to copy, you benchmark the shape of the traffic, not the event.
📌 TL;DR
This year's World Cup gave me nothing to compare against: three host countries, North American daytime traffic, a newly regulated Brazil, and a four-year gap since the last one. So I stopped trying to benchmark the event and benchmarked the traffic shape instead. The Super Bowl gave me a known ceiling. I sized the slow-to-change layer against it, alerted early enough to actually decide, and re-cut capacity at each stage of the tournament.
🧩 The problem: nothing to compare against
Every big event I prep for comes with a reference. The Super Bowl has last year's Super Bowl. March Madness has last year's bracket. Even a routine deploy has last week's deploy sitting right next to it.
This World Cup came with none of that.
Some context. I'm based in Poland. The platforms I support run regulated sports betting and gaming across North America, and more and more of Latin America. My quiet hours and my busy hours have never lined up, and this tournament pushed that gap wider than anything before it. Three host countries at once, a first. Games landing in US and Canadian daytime instead of the usual European overnight slot for me. And a freshly regulated Brazilian market on its biggest live stage yet. The last men's World Cup was four years ago, played in December, with a single host. Nothing in it looked like the load I was about to get. There was no "last year's World Cup" to pull a number from.
So how do you size for something that has never happened?
🎯 Benchmark the shape, not the event
You don't size the event. You size the shape of the traffic.
Our single highest-traffic event, by a wide margin, is the Super Bowl. One night, one enormous spike, done in about four hours. If I sized for a Super Bowl peak, and I had good reason to believe the World Cup would not beat it, then I had my ceiling.
So I stacked every variable that made this tournament unusual. North American time zones. The Brazil surge. The extra marketing operators were pouring into it. Even with all of that piled on, the arithmetic still landed under Super Bowl peaks. That gave me a number to build against, then I added buffer on top, because nobody sizes to the exact expected figure and calls it done. You leave room for the estimate to be wrong.
I won't publish my internal capacity figures, those stay private, but the public volume numbers show why the ceiling held. This year the Super Bowl ran 81.4 million geolocation checks on a single game day. March Madness Final Four weekend ran 145.6 million. The World Cup ran 1.94 billion, but spread across four weeks. Far more total traffic, thinned out over time. No single moment ever out-peaked the Super Bowl, which is the whole reason a Super Bowl ceiling was safe to build against.
The method is the point, and it travels: find the closest event you do have data for, and size against its shape.
🧱 Stateless vs stateful: where the real constraint lives
This is where "just auto-scale it" falls apart.
Application layers are stateless. Traffic climbs, you add instances, you're done in seconds. Databases are a different animal. You cannot resize a production database mid-tournament. It takes days, and if you get it wrong you are not looking at a slow page, you are looking at a real outage.
So for the stateful layer the question was never "can we react fast enough." It was "did we size this correctly two weeks ago." If the answer to the second one is no, the first one doesn't matter. You've already lost the race the moment the spike arrives.
The rule I keep coming back to: anything that needs a maintenance window to resize gets sized before the event, not during it.
📉 Alerts that buy decision time
Most monitoring is tuned to tell you when something is already wrong. I tune mine to tell me while I still have options.
That does not mean one alert at a low number. It means tiers, matched to how slow the fix is.
tier 1 ~mid utilization investigate now, you have time to decide and act
tier 2 high utilization page someone, act immediately
The first tier is the one that matters for slow-to-change resources. When a database is sitting at mid utilization there is still real headroom: enough to look at what's happening, decide whether it needs action, and add capacity long before anything costs me. If my only alert is the classic 80-90% page, the decision has already been made for me by the time it fires, and it's the wrong decision. For a layer that scales in days, an alert that fires at "already in trouble" is useless.
The tier depends on the resource. A stateless pool can wait for a higher threshold, because I can fix it in seconds. The slow layer gets the early signal, because I can't.
🗓️ Six weeks is six events, not one
A four-hour game and a six-week tournament are not the same scaling problem. Treating them the same is how you either overspend badly or under-prepare badly.
Running Super Bowl-level infrastructure flat out for six straight weeks is expensive for no reason. So instead of one static config for the whole run, I split it into stages with a gate between each. At every gate I looked at what the previous stage's traffic actually did, compared it to the prediction, and adjusted for the next stage.
After the first gate I already had enough real data to pull certain instance counts back down without giving up any safety margin. Real traffic replaced my assumptions the moment it was available.
🛡️ Redundancy, in layers
If something breaks anyway, this is the order it fails in and what catches it.
Availability zones first: stateless components spread across zones, one zone has a problem, load shifts on its own. Then database failover: a standby that promotes within seconds if the primary dies. Most teams would call seconds fast. I treat it as the floor, not the win. Then a queuing layer: if something spikes past what's scaled, or a component can't take traffic for a moment, requests queue instead of erroring, and the user sees a slightly longer wait instead of a failure. Last, a live-live failover to a second cloud provider, for the day the primary provider itself has a bad one. That layer is not theoretical. It held through last year's major AWS outage with no customer impact.
The goal with every layer past the first is to never use it. "We'll probably be fine" is not a redundancy strategy, and hoping the bad day lands on someone else's shift is not one either.
The honest limitation: none of this is free, and none of it is seamless. Live-live across two providers means paying for a second stack you hope stays idle, and keeping the two in sync is constant work. And on the stateful side there is still a real exposure window during a failover, the seconds between the primary dying and the standby taking over. Fast is not the same as invisible. That gap is the part I watch most closely, because it's the one the diagram makes look cleaner than it is.
🧭 My take
The World Cup didn't give me a precedent. Super Bowl traffic patterns gave me a ceiling, and that turned out to be enough.
None of this is specific to betting infrastructure, or to me. Any team sizing for an event with no direct precedent is solving the same problem. Find the closest analog you have real data for. Benchmark its shape, not its specifics. Size the slow layer well before you need it, because you can't buy that time back later. And set your early alert to give you decision time instead of reaction time. The teams that get caught out are almost always the ones who tried to react to the stateful layer in real time. By then the race is already over.
📚 Resources
- Match Ready: How GeoComply Prepares for the Biggest Moments in Sport — the companion piece, with the eight questions I'd ask any infrastructure partner before a major event.


Top comments (0)