Skip to content

Going Beyond Firebase: Performance Monitoring for Kotlin Apps using Koin with the Kotzilla Platform

As Kotlin developers, we all want our apps to feel fast and smooth: quick startup, responsive UI, no weird freezes.

Firebase Performance Monitoring provides a great starting point with built-in metrics like app startup time, screen rendering, and network calls. But when it comes to uncovering deeper performance issues and their root causes, such as why your app is becoming slow or unresponsive due to a ViewModel blocking the main thread, Firebase relies on you to add custom traces manually

That means searching through your code, deciding where to place those traces, and hoping they catch the real problem. This process can get tedious and often leaves gaps, especially in complex Kotlin apps with many critical execution paths.

I work at Kotzilla, where we saw these limitations firsthand. That is why we built the Kotzilla Platform, designed specifically for Kotlin apps, especially those using Koin. It automatically tracks components, dependency lifecycles, and thread activity without extra code, giving you clear, Koin-level visibility into the critical performance issues in your apps. The Kotzilla SDK leverages the Koin container to provide this unique insight.

I tested Firebase and the Kotzilla Platform side-by-side on Google’s NowInAndroid app, deliberately slowing things down to see what each tool would reveal. Firebase offered broad stats but missed the fine details I needed. The Kotzilla Platform gave me the deep insights I was after.

Let me walk you through what I found.

Testing both tools on a real app: NowInAndroid

To ground this comparison in reality, I tested both tools on Google’s official NowInAndroid app, which we migrated from Hilt to Koin for dependency injection.

NowInAndroid is a fully functional Android app built entirely with Kotlin and Jetpack Compose. It follows Android design and development best practices and serves as a helpful reference for developers. It’s meant to keep developers up-to-date with the Android world by providing regular news updates.

The setup

For this comparison, I followed the official getting started guides from Firebase Performance Monitoring and Kotzilla Platform to integrate the SDKs into the NowInAndroid app.

I created two separate Android Studio projects by cloning the NowInAndroid app for Koin, available here. Then, I introduced deliberate delays to simulate some performance issues in the following classes:

  • Scenario 1: A 1-second blocking delay on the main thread in MainActivityViewModel.kt
  • Scenario 2: A 10-second delay during app startup in NiaApplication.kt
  • Scenario 3: A 1-second delay in a background task inside SyncWorker.kt

These scenarios cover a range of common, yet hard-to-detect, performance issues: UI thread blocking, slow app startup, and background execution delays.

Here’s an example of the delay added to MainActivityViewModel.kt:

Screenshot 2025-06-24 at 16.00.55

Firebase Performance Monitoring: what it shows… and what it doesn’t

Firebase automatically monitors these traces:

  • App Startup: Time from app launch until it becomes responsive (i.e, onResume() is called).
  • App Background: Time from when the last activity enters the background (onStop()) until any activity returns to the foreground (onResume()).
  • App Foreground: Time while the app is actively in use, from onResume() to onStop().
  • HTTP/S Network Requests: Duration, size, and success rates of HTTP/S requests.

Firebase also provides a custom trace API so you can manually instrument specific parts of your app’s lifecycle.

But here’s what I found across these scenarios:

I ran the app multiple times, progressively introducing the three delays across user sessions, and connected it to the Firebase Console to evaluate what the platform could detect out of the box.

Note: Firebase delays in surfacing session data (often 10+ minutes, sometimes hours) made rapid debugging in debug builds difficult. Several samples with deliberate delays never appeared in the Firebase Console at all.

Scenarios 1 & 2: App start time & ViewModel resolution delays

  • The average app startup time increased as expected when introducing a 10-second delay in NiaApplication.kt and a 1-second delay in MainActivityViewModel.kt.

    Screenshot 2025-06-20 at 16.22.14

  • I configured Firebase to track default metrics: app startup time, time in background, time in foreground, and MainActivity duration.

  • However, drilling into session details revealed no insights into what caused the delays, only percentile distributions across recorded sessions for each metric.

    Screenshot 2025-06-20 at 17.06.25

    Screenshot 2025-06-20 at 16.22.41

  • Firebase offered no automatic tracking of ViewModel resolution time, main thread blocking, or any indicator of the underlying issue (only visual graphs of startup evolution and app state durations).

    Screenshot 2025-06-20 at 17.13.08

  • To get additional detail, I had to manually add custom traces. Below is an example of a trace I created to monitor startup performance.

    Screenshot 2025-06-24 at 17.47.38

  • In this case, adding the trace was straightforward because I knew I was testing startup issues. But delays caused by ViewModel resolution would be much harder to detect without guessing where to add instrumentation in advance. Unless I already identified the app's critical paths and traced them during development, these would go unnoticed.

    Screenshot 2025-06-20 at 17.22.55

    Screenshot 2025-06-20 at 17.23.08

    Note: During testing, it was also challenging to find real user sessions to analyze. Out of 12 runs, only 2 specific user sessions with performance data eventually surfaced after nearly two days.

  • This view revealed some impact on startup and screen appearance, along with basic CPU and memory usage but still no information about what was causing the problem or a way to isolate and analyze that user session.

    Screenshot 2025-06-24 at 14.49.41

Scenario 3: Background Worker Delay

  • The 1-second delay in SyncWorker.kt was completely invisible in Firebase’s default reporting.

    Screenshot 2025-06-20 at 17.04.28
  • While Firebase monitors foreground and background durations, it provides no visibility into background worker or thread-level execution. As a result, you cannot tell whether time spent in the background was due to normal app suspension or a performance issue like a thread bottleneck or long-running task.

    Screenshot 2025-06-20 at 17.11.43
  • Spotting performance issues in background tasks requires even more manual instrumentation. Without it, worker-related delays remain undetected—even when examining specific user sessions:

    Screenshot 2025-06-24 at 14.55.04

General limitations of Firebase Performance Monitoring

Firebase provides general metrics, such as app start time and screen rendering, but do not provide detailed insights to identify performance issues related to ViewModels, asynchronous execution or multithreading.

  1. Lack of granularity

    Performance issues often arise from operations within ViewModels, including data loading and processing. Firebase does not automatically track these aspects, requiring custom traces to diagnose delays effectively.

    Developers must anticipate and instrument critical app paths manually and maintain this tracing code over time.

    This would require to initialize Firebase Performance Monitoring in the NiaApplication and then implement custom traces in all the classes and components that we would like to track, such MainActivity or MainActivityViewModel

  2. Asynchronous execution and multithreading issues

    Firebase Performance Monitoring does not adequately capture problems associated with asynchronous execution and multithreading. As such, it may not provide a complete picture of how background tasks and thread utilization impact app performance. Those issues can be addressed programmatically using the Firebase APIs but this kind of approach requires major code instrumentation.

    Firebase is often used in combination with Android Studio’s CPU Profiler to help with the analysis of thread activity and identify issues related to asynchronous execution and multithreading.

Kotzilla Platform: deep Koin-level performance visibility for Kotlin apps

To simulate realistic delays, I introduced identical slowdowns in specific classes and ran the app multiple times using a debug build to generate user sessions across three scenarios.

The initial key difference was that the Kotzilla Console immediately identified multiple issues related to those scenarios. It provided an overview with categorization, impacted session count, and severity levels.

With these scenarios, Kotzilla delivered the following insights:

Screenshot 2025-06-20 at 17.34.55

With these scenarios, the Kotzilla Platform delivered the following insights:

Scenario 1: 1-second delay blocking the main thread during MainActivityViewModel resolution

Kotzilla automatically detected a 1-second main thread block caused by MainActivityViewModel resolution. The console pinpointed the exact blocking call, categorized it as critical, and provided initial analysis, impact summary, and actionable recommendations.

Screenshot 2025-06-20 at 17.32.36

I could filter and select a specific user session to investigate further using a dedicated timeline view showing key moments, such as screen transitions and detected issues, including performance bottlenecks and crashes.

Screenshot 2025-06-20 at 17.29.47

The timeline was automatically focused on the exact moment the issue occurred. This provided complete context around the problematic component, including its resolution time (+1s) and thread activity; confirming the main thread was blocked.

Since Kotzilla integrates with the Koin container, I was also able to explore the full dependency graph of that component to investigate whether any dependency resolutions were slower than expected.

Screenshot 2025-06-20 at 17.30.58

One of the dependencies took more than 15ms to resolve, but the bulk of the delay was due to the MainActivityViewModel itself; making it easy to pinpoint the source of the 1-second delay as the initialisation of the ViewModel.

 

Scenario 2: 10-second delay in app startup

The Kotzilla Platform detected a 10-second delay during app startup, providing exact resolution times for every component in the dependency graph. It clearly showed how the main thread was blocked, delaying UI readiness.

Screenshot 2025-06-20 at 17.35.42

In the timeline, you can see the main thread blockage and the 1-second delay before the first screen appeared. Users can also see the threshold used to trigger this slow startup issue.

Scenario 3: 1-second delay in SyncWorker execution

Kotzilla identified a 1-second delay in the background thread during the SyncWorker task. It provided deep visibility into the timing and impact of this delay on overall app performance.

Screenshot 2025-06-20 at 17.37.19

Screenshot 2025-06-20 at 17.38.03

Thanks to the Timeline view I was able to observe that:

  • The SyncWorker was blocking a background thread for more than 1000ms.
  • Several dependencies tied to the SyncWorker have performance issues due to delayed task resolution.
  • The background thread performance is impacted by the complexity of the dependency graph, with 31 dependencies involved in the background task resolution.

And all of this came without manual tracing or custom instrumentation.

Still can’t get enough of tracing?

The Kotzilla Platform also offers a dedicated SDK API that lets you define custom traces, logs, and contextual properties. This is ideal for advanced debugging or adding specific data or properties where needed.

With the Kotzilla SDK API, you can:

  • Log custom messages to your app’s performance timeline using log("message")
  • Record exceptions with log("error message", exception)
  • Benchmark specific code blocks using trace("block_name") { ... }
  • Add contextual data to sessions with setProperties(...)
  • Link sessions to specific users via setUserId("user_123")

The API works on both Android and Kotlin Multiplatform (KMP) projects and is easy to set up:

  • On Android: use analytics() inside your startKoin block.
  • On KMP: initialize it with KotzillaCoreSDK.setup(...) in commonMain.

This gives you fine-grained control over what gets tracked, when, and how, helping you debug and optimize even the most complex flows.

Firebase Performance Monitoring vs Kotzilla Platform: side-by-side comparison

Feature Firebase Performance Monitoring Kotzilla Platform
Components execution tracking and behaviour (ie ViewModels) 🚫 Not automatic (manual traces required) ✅ Built-in for Koin
Dependency graphs visualisation and resolutions insights 🚫 Not available ✅ Built-in for Koin
Thread execution visibility and performance 🚫 Limited (manual traces required) ✅ Built-in (main and background threads)
Issues detection and root cause analysis 🚫 Not directly supported ✅ Dashboards for issues and root cause analysis tools
Session-level performance data ⚠️ May be delayed or partial ✅ Graphical timeline, session-specific, real-time
Instrumentation effort ⚠️ Moderate to high for custom traces ✅ Minimal (automatic + optional SDK)
Crash reporting and session context ⚠️ Separate Crashlytics setup; no unified view ✅ Unified crash & performance data with full session context
Cross-platform support ✅ Broad (Android, iOS, web) ⚠️ Kotlin-only (Android + KMP using Koin)
Network monitoring (HTTP/S requests) ✅ Built-in 🚫 Not natively supported

Conclusion

For Kotlin developers, getting deep, actionable performance insights shouldn’t require endless manual tracing. While Firebase Performance Monitoring provides useful high-level metrics, it often falls short when you need to understand the real performance issues and internals of modern Kotlin apps.

That’s why we built the Kotzilla Platform. It fills this gap with automatic, Koin-level visibility that pinpoints exactly where your app’s performance bottlenecks are. No more searching through code or relying on custom traces to catch the real issues. The Platform tracks component and dependency lifecycles, thread execution, and app behavior out of the box, giving you precise, real-time insights.

And it’s not just for debugging development builds. The platform is built to monitor performance in your release builds running in production. It helps you uncover issues that only occur on specific devices or under certain conditions; problems that are known as hard to reproduce locally.

The result is faster resolution times, reduced downtime, and smoother user experiences. Your team can ship high-quality Kotlin apps more efficiently and with greater confidence.

The Kotzilla Platform is built specifically for Kotlin developers using Koin, giving you the power to debug and monitor performance across Android and Kotlin Multiplatform apps with confidence.