Fixing Elusive Unity ANRs: How Amanotes Used Sentry to Cut Errors by 50%

This is a guest post from Thuan Do The from Amanotes, a music game publisher who are using Sentry for their Unity game Duet Cats.
In today’s mobile-first world, users expect apps to launch instantly and respond seamlessly. For game developers, maintaining that buttery-smooth experience isn’t just a nice-to-have—it’s essential for retention and revenue. But what happens when performance starts breaking down, and there’s no clear cause?
That's exactly where we found ourselves at Amanotes. As we continued to add new features to one of our top games, Duet Cats – a music rhythm game with over 10 million downloads on Google Play and App Store – we noticed a troubling trend: every new feature seemed to double the number of "Application Not Responding" errors (ANRs).
Duet Cats
With the game's complexity and fanbase quickly growing, performance became our biggest bottleneck. We triple-checked our code, profiled every new component, and even compared builds line-by-line. The results? No obvious culprits. Everything looked clean—yet ANRs were spiking.
We were chasing ghosts.
In search of deeper insights, we turned to Sentry, a tool primarily known for error and performance monitoring for web and mobile. We were skeptical at first—Unity wasn't its typical domain. But as soon as we integrated Sentry, we discovered something remarkable: clear patterns emerging from the chaos!
Awake()
was triggered very late, after 5s. How significant is this? Extremely! It means the ANRs weren’t coming from our game logic at all—the app was freezing before our code even had a chance to run!
Sentry trace view
Suddenly, it was obvious why our optimizations didn’t work: we’d been tuning performance in the wrong place all along!
Two operations stood out as silent performance killers:
Scene loading transaction
Transaction breakdown with spans
Sentry’s transaction-level view gave us a powerful breakdown of the exact spans causing delays. Sorting by 95th percentile duration we were able to pinpoint the slowest operations affecting the top 5% of users—the ones most vulnerable to ANRs.
Heavy Scenes: Loading and Main stood out, with the Loading span peaking at 5.89 seconds for the p95 percentile—dangerously above the ANR threshold.
Heavy Methods: significant impact, especially when initialized too early during startup.
IronSourceEvents.IronSourceEvents
AppOpenAds.AppOpenAdController
This view removed all guesswork. We now had a clear list of priority optimizations based on real-world performance, not assumptions. And then it finally clicked—we could clearly see why the ANRs were happening.
Our previous build hadn’t crossed the 5-second ANR threshold, but it was already skating dangerously close. For a significant portion of users, some operations were taking up to 4.9 seconds.
The new features we added? They only introduced an extra 0.1 seconds. But that tiny bump was enough to push many devices just over the limit—triggering a wave of ANRs.
We hadn’t introduced new issues—we had unknowingly tipped a fragile system over the edge.
With Sentry’s deep visibility, we finally knew exactly where to look and what to fix.
Scene Loading Time: Reduced from 17.8s to 3.71s (~80% improvement)
Before: 17.8 second transaction duration
After: 3.71 second transaction duration
ANR Rate: Reduced from 0.98% to 0.46% (~50% improvement)
Decreasing user-perceived ANR
Optimizing Unity startup and scene loading doesn’t require magic—just the right tools for monitoring and measurement.
Unity takes time to init itself - and all of this happens in the first frame!
Unity first frame load
Initialize IL2CPP
Initialize Player
Initialize Graphics (load managers)
First scene always load in sync
Keep the first scene minimal: Use it as a shell to warm up systems asynchronously.
Keep the shader / preload asset list empty: Delay or manually warm up shaders
Avoid work in the first several frames: No network calls, no I/O operation, no SDK inits, no asset loading
Scenes takes time to load all referenced assets to RAM
Unity scene loaded assets
Scenes takes time to integrate / Initialize all
gameObjects
and scripts in the hierarchy and this happens within a single frameUnity scene gameObjects
Serialization callbacks
Awake from load
Callbacks for
Start()
,OnEnable()
Load scenes asynchronously: Synchronous loads mean everything—textures, prefabs, materials—must be RAM-ready in one frame. That’s a recipe for ANRs.
Reduce dependencies: Split large scenes into smaller ones. Avoid bloated prefabs. Use dependency graphs if needed.
Preload smartly: In complex cases, preload essential assets before activating the scene.
Defer instantiation: Don’t populate entire scenes up front. Use object pools,
Resources.Load()
, or Addressables to spawn objects on demand.
At Amanotes, integrating Sentry into our Unity workflow helped us pinpoint the invisible issues that traditional profiling tools missed. What once looked like random hangs were, in fact, predictable performance cliffs—just waiting to be crossed.
If you're a Unity developer struggling with performance or haunted by unexplained ANRs, we highly recommend giving Sentry for Unity a try. It’s not just a crash logger, it’s a window into your game's real-world performance.
Your users (and your future self) will thank you!