System Design · Issue 6
How Supercell Made Brawl Stars Load in 5 Seconds
A 35-second load on old Android phones was quietly gating when people played. Here is how the Titan team tore apart the loading pipeline.

The constraint
A 35-second tax on a 3-minute game

On older Android devices, Brawl Stars took roughly 35 seconds to load. A typical match runs about 3 minutes. So before you could play a short session, you paid a load tax that was almost a fifth of the game itself.
Supercell developer Damien Mabin put it bluntly: "You can't really play on a toilet break." The load time was long enough to discourage the spontaneous, drop-in play that a mobile game lives on.
The data backed this up. Android players opened the game less often but stayed longer once in, while iOS players, with shorter loads, dipped in and out freely. The load time was shaping when and how often people played, not just how happy they were.
The trigger
Brazil forced the team to look

The push came from a Brawl Stars relaunch campaign in Brazil, a market with a large share of older and lower-spec Android phones. Suddenly the slow path was not an edge case, it was the mainstream experience, and performance became a business problem.
When the team dug in, there was no dramatic culprit. As Damien said, there was "no villain in the server room." The loading pipeline had simply grown, over years, into something painfully sequential.
The logic was spread around the codebase, a bit like spaghetti.
Root cause
Load, wait, load, wait

Loading a game means pulling in UI files, textures, sounds, 3D models, and animation data, and those assets have real dependencies. A button needs its texture. A screen needs its sound. A character needs its model, animation, and effects before it can appear.
The old system respected those dependencies by doing almost everything one step at a time: load an asset, wait for it, load the next, wait again. Even assets with nothing to do with each other were queued up nose to tail.
OLD: strictly sequential UI ─▶ wait ─▶ texture ─▶ wait ─▶ sound ─▶ wait ─▶ model ─▶ ... one thread, one asset at a time, ~35s
The first job was not optimization. It was dependency mapping: working out what genuinely must load before what, what could run at the same time, and what only looked like a dependency because nobody had questioned the assumption in years.
The design
A task queue and parallel workers

The fix was to break loading into small discrete tasks, load this sound, this UI file, this texture, this model, and push them into a shared queue. Multiple worker threads then pull tasks off and run them in parallel, held back only by the real asset dependencies.
Damien described the concept as almost boring: "You create tasks, put them in a queue, and then multiple threads pick them up and work through them in parallel." The genuinely hard part was drawing the line correctly, since some assets, like the loading screen before the main menu, legitimately must serialize.
NEW: dependency-aware parallelism
┌─▶ Thread 1 ─▶ texture
Queue ────┼─▶ Thread 2 ─▶ sound
(tasks) ├─▶ Thread 3 ─▶ model
└─▶ Thread 4 ─▶ UI file
serialize only where deps demand it, ~5-6sThere was a second, quieter bug this exposed. Server messages sometimes arrived before the client assets needed to handle them were ready, which used to crash the game. They added a buffer so incoming messages sit in a queue until the game state is ready to consume them.
The payoff
35 seconds down to 5

On older Android devices, load time dropped from ~35 seconds to ~5-6 seconds. Even newer iOS devices, already fast, went from ~7 seconds to ~2.5 seconds. The whole project, from design through stabilization, crash-fixing, and getting production-ready, took about 4 months.
Old Android
~35s → ~5-6s
New iOS
~7s → ~2.5s
This was only possible because Supercell owns Titan, its in-house engine, end to end. The team changed the loading system itself instead of bolting a workaround on top of it. As Damien put it, "owning the engine mattered."
The costs
Parallelism brings race conditions

Going multi-threaded brought the classic hazard back: race conditions. Thread A waits on resource X while thread B waits on resource Y, and X and Y depend on each other. A circular wait, and now nothing moves.
It showed up two ways. Some were outright crashes. Worse were the silent stalls, where loading simply stopped with no crash and no signal. As Damien said, "It's not a crash, so if you don't pay attention to it, you don't really know what's happening."
Thread A (waits on X)Thread B (waits on Y)
X needs Y, Y needs X: progress silently stops
To catch the stalls, they added analytics that flag moments where loading progress stopped without a matching crash report. After release there was a spike in crashes, and the Brawl and Titan teams spent the next few days chasing them down. They went in expecting it: "We knew we would have crashes and instability."
The stupid problem
When the game loads faster than its own logo

Supercell's startup logo animation runs about 2.8 seconds. Once loading fell to 5-6 seconds, the game was sometimes functionally ready before the logo finished playing. The loading screen stopped appearing the way people expected.
So players filed bug reports, convinced something was broken. Nothing was. The game was just faster than the animation designed to cover the wait. The fix was to show the logo only once per day, letting the game otherwise drop straight into the faster flow.
The behavior data followed. Android sessions shifted toward iOS patterns, shorter and more frequent. Damien framed it as handing agency back: "They can play however they want, not how the loading time forces them to play."
The bigger picture
Reaching into a messy shared engine

Titan runs every Supercell game and serves about 300 million players a month, but it was never designed top-down. It started as game code that teams copy-pasted between titles, later merged into one shared engine. A teammate, Elie, called parts of it "a machine that looks good from the front, while the back is held together with duct tape and a prayer."
Titan's boss Timo Tervola calls the resulting decay a "silent killer": no single crash, no explicit complaint, just gradual performance rot on ordinary devices that no feedback form ever captures. The loading fix is one instance of a team hitting a wall the shared engine created and reaching in to fix the engine itself.
Because the loading system lives in Titan, that fix does not stay with Brawl Stars. Under Game Tech's stated principle, when one team solves a hard problem in the engine, the improvement is there for every other game to reuse. The instability was a deliberate call for this game at this moment, and another team, Damien noted, might weigh it differently.
The takeaway
Owning the pipeline is the point
Why it matters
The interesting move here is that the slow load was never a single bug to squash, it was structure: a pipeline that grew sequential because nobody re-examined which assets actually depended on each other. Fixing it meant editing the shared engine, not working around it, and that only paid off because Supercell owns Titan end to end. The reward for that ownership is that one game team's loading rewrite becomes a capability every other game inherits.
The short version
- Brawl Stars load time on older Android fell from **~35s to ~5-6s** (and iOS from ~7s to ~2.5s) in a **4-month** project.
- The core change was decomposing loading into tasks in a **shared queue**, run by **parallel worker threads**, constrained only by real asset dependencies.
- The first step was **dependency mapping**, not optimization: finding what truly must serialize versus what only looked like it.
- Parallelism reintroduced **race conditions**, silent stalls, and a post-launch crash spike that the team knowingly accepted as the cost.
- Owning Titan meant they fixed the engine itself, so the improvement can carry over to every other Supercell game.
Sources
- 1.How Titan Made Brawl Stars Toilet Break-Friendly
- 2.The Secret Game Engine Behind Supercell's Mobile Empire
- 3.Game Engine Architecture
- 4.The Engine Behind Every Supercell Game (and Why You've Never Heard of It)
- 5.Review: Game Engine Architecture – Alan Sguigna
- 6.GitHub - codenameyau/game-engine-architecture: :beginner: Learning how to design 3D game engines · GitHub
- 7.Game Engine Comparison - Titan vs Unreal vs Unity
- 8.Monitor Unreal Engine Game Performance with Application Metrics | Sentry Blog
- 9.Why are there so few Performance Metric comparisons ...
- 10.Postmortems From Game Developers.pdf
- 11.Into the Breach Design Postmortem
- 12.Game Development Postmortems
- 13.Games Postmortem: What Works & What Doesn’t
- 14.Classic Postmortem: The making of Half-Life 2