Firebase Performance: What It Is, Metrics, and How to Track

Author: IT Sectr Published: 2026-04-29 Reading time: 16 min

Firebase Performance Monitoring is a tool built into the Firebase platform for automatically collecting and analyzing mobile app performance metrics in real time. Unlike custom solutions based on logcat or Xcode Instruments, the Performance SDK measures app startup time, HTTP request duration, screen rendering speed, and custom scenarios without modifying business logic. According to Google Firebase (2026), the service is used in 40% of Firebase projects to identify bottlenecks and maintain app performance at target levels.

Key Takeaways

  • Firebase Performance is a performance monitoring tool with automatic collection of key metrics.
  • Automatic metrics include startup time, HTTP requests, and screen rendering without writing code.
  • Custom traces allow measuring the performance of specific scenarios: feed loading, image processing.
  • Performance thresholds are configured in the Firebase console for automatic degradation alerts.
  • Crashlytics integration provides context: performance on devices where a crash occurred.

What Is Firebase Performance Monitoring

Firebase Performance Monitoring is an SDK and cloud platform for collecting, aggregating, and visualizing mobile app performance metrics. The SDK is embedded into the app and automatically instruments key points: the Activity lifecycle (Android) or ViewController (iOS), network requests via URLSession (iOS) or OkHttp (Android), and system calls. The collected data is sent to the Firebase server, where it is aggregated by app version, device, country, and other attributes.

The Performance SDK architecture is built on the principle of minimal overhead: instrumentation adds no more than 1–2% to the execution time of measured operations. Data is collected asynchronously and buffered on the device before sending, eliminating any impact on UI thread performance. Data is sent on a schedule (by default every 30 minutes) or when the buffer reaches 100 KB.

The key difference between Firebase Performance and Android Studio profilers (CPU Profiler) or Xcode Instruments is production monitoring. Firebase Performance collects data from real user devices, not just developer devices. This allows detecting issues that only occur on specific models, OS versions, or in particular regions — issues that cannot be reproduced in a controlled environment.

How the SDK Collects Data Without Code Changes

Automatic instrumentation is the main feature of Firebase Performance. For Android, the SDK automatically registers ActivityLifecycleCallbacks and measures the time between onCreate and onResume (screen rendering time). For iOS, it swizzles viewDidLoad and viewDidAppear methods. Network requests are intercepted at the OkHttpInterceptor (Android) or NSURLProtocol (iOS) level. The developer does not need to add start/stop calls for standard metrics.

Enabling and disabling the Performance SDK is managed through the Google Services plugin (Android) or Info.plist (iOS). For debugging, you can enable verbose logging of the Performance SDK, which shows which metrics are being collected and sent. In production, it is recommended to keep logging at the warning level to avoid cluttering logs with unnecessary information. For projects on Flutter or React Native, automatic instrumentation may be limited — more details in the code examples section.

Free Limits and Pricing

Firebase Performance is available on the free Spark tier with no limits on the number of traces or data volume. The paid Blaze tier also does not charge for Performance Monitoring — it is one of the few Firebase services that is completely free on both tiers. There is only one limitation: data is stored for 30 days (on Spark) and up to 365 days (on Blaze). For long-term analysis, export data via BigQuery export.

No cost makes Firebase Performance an ideal choice for any project — from prototype to enterprise application with millions of users. The only expense is outgoing traffic from the Performance SDK, but it is negligible compared to other network operations of the app (less than 1 MB per month per device). BigQuery export charges for storage and queries, but the Performance SDK itself is free.

Automatic Metrics: What Is Measured Without Code

Firebase Performance automatically collects five categories of metrics without a single line of code: app startup time, slow HTTP requests, screen rendering speed, memory usage (Android only), and frame rate (Android only). These metrics are available in the Firebase console immediately after connecting the SDK and the first user session.

App Start Time — the time from process launch to full UI readiness for interaction. It is divided into cold start (app launches from scratch) and warm start (app resumes from background state). Cold start includes loading DEX files, initializing static fields, calling Application.onCreate and Activity.onCreate. Firebase automatically classifies the start type and shows time distribution for each type.

Screen Rendering Time — the time from the start of screen loading (onCreate for Android, viewDidLoad for iOS) to the moment the screen is ready for interaction (onResume, viewDidAppear). Firebase aggregates data by each screen (by class name or custom screen name), allowing you to identify which screen loads the longest. For Android, dropped frames are additionally measured — the number of frames skipped during screen rendering (jank).

MetricAndroidiOSWhat It Shows
App StartYesYesCold and warm start time
Screen RenderingYesYesDisplay speed of each screen
HTTP RequestsYesYesMetrics of each network request
Dropped FramesYesNoSkipped frames (jank)
Memory UsageYesNoRAM consumption in sessions

Network Requests (HTTP/HTTPS)

Performance SDK automatically intercepts and measures every HTTP/HTTPS request sent from the app via URLSession, OkHttp, or URLConnection. For each request, the following are recorded: URL (path without query parameters for security), HTTP method, response code, response size in bytes, request duration, and connection speed (WiFi, Cellular). Data is aggregated in the Network Requests dashboard of the Firebase console.

Slow Requests — requests whose duration exceeds a set threshold. By default, the slow request threshold is 4000 ms. This metric is critical for identifying backend issues: if after a backend update the number of slow requests grows from 1% to 15%, that is a signal for immediate server log analysis. Users will not wait more than 5 seconds for a response — Firebase data shows that 53% of users close the app if a request takes longer than 3 seconds.

Limitations of Automatic Instrumentation

iOS limitations: on iOS, the Performance SDK cannot measure dropped frames (this is a private API). For measuring jank on iOS, use MetricKit or CADisplayLink. Also, on iOS, the SDK does not intercept requests made through third-party HTTP clients that do not use URLSession (e.g., SwiftNIO). For such cases, use custom traces with HTTP attributes.

Android limitations: on Android, automatic memory measurement is only available on devices with Android 8.0+ (API 26+). For older versions, use custom traces with data obtained through Debug.getMemoryInfo(). Also, the SDK does not intercept WebSocket connections — they require separate traces. Despite these limitations, automatic metrics cover 80% of performance monitoring needs.

Custom Traces and HTTP Attributes

Custom traces are named time intervals that the developer manually creates to measure the performance of specific scenarios: loading a news feed, processing an image, synchronizing data, executing a complex database query. Custom traces complement automatic metrics and allow measuring exactly those code segments that the developer considers critical for performance.

Each trace has a name (maximum 100 characters) and can contain up to 5 custom metrics — numerical values recorded inside the trace. For example, in an "image_processing" trace, you can measure metrics like "original_file_size" and "processed_file_size". Metrics are displayed in the Firebase console as distributions (min, max, average, percentiles), allowing analysis of not only duration but also operation characteristics.

HTTP attributes — a special type of custom trace for network requests that were not automatically intercepted by the SDK (e.g., via WebSocket or third-party libraries). HTTP attributes include URL, HTTP method, response code, and response size. Firebase displays them in the Network Requests section alongside automatically collected requests, providing a unified picture of network interaction.

When to Use Custom Traces

Custom traces are indispensable for measuring: data loading time from local database (Room, CoreData), duration of complex computations (encryption, compression), animation and transition performance, response time of third-party SDKs (maps, payments, analytics). For each such scenario, create a trace, wrap the measured code in start/stop, and add attributes for subsequent segmentation.

Do not overuse custom traces. Each trace adds battery and traffic overhead. It is recommended to have no more than 10–15 active traces in the production version of the app. For debugging, you can add more traces, but before release, disable excess ones via Remote Config (use the performance_tracing_enabled flag). This allows enabling detailed tracing only for selected users or sessions.

Trace Attributes for Segmentation

Custom attributes are key-value pairs that can be added to a trace for subsequent filtering in the Firebase console. For example, for the "feed_load" trace, you can add attributes like "feed_type" (main, explore, following) and "cache_status" (cold, warm). In the console, trace data can be filtered by these attributes to determine which feed type loads the slowest.

Limitations: each trace can have up to 5 custom attributes. Attribute values are strings up to 100 characters. Attributes must be set before the trace starts; changing an attribute after start is ignored. This limitation is related to performance: fixing attributes after start would require additional synchronization.

Performance Thresholds and Alerts

Thresholds are configurable boundary values for metrics, upon exceeding which Firebase Performance generates a warning. Thresholds are set in the Firebase console (Performance > Thresholds) for each automatic metric: app start time (cold/warm), screen rendering time, slow HTTP requests, HTTP response time. You can set global thresholds for all app versions or specific ones for particular versions.

Alerts are automatic notifications that Firebase sends when a threshold is exceeded. Alerts can be configured via email, Slack webhook, PagerDuty, or Cloud Functions (for custom handling). Each alert contains: metric name, current value, threshold value, app version, segment (device, country). Alerts allow responding to performance degradation before it becomes noticeable to users.

Recommended thresholds per industry standard (Google I/O 2025): cold start — under 2 seconds, warm start — under 1 second, screen rendering — under 500 ms, HTTP request duration — under 3000 ms (95th percentile), slow request share — under 5%. For highly competitive apps (Social, E-commerce), target thresholds can be stricter: cold start < 1.5 seconds, HTTP < 1000 ms.

Setting Thresholds in the Firebase Console

In the Firebase console, go to the Performance section, open the Thresholds tab. For each metric, set the desired threshold value and the percentage of users that should be affected by the exceedance. For example: "consider cold start slow if it exceeds 2 seconds for more than 10% of users". Firebase will show current metric values and exceedance history to help choose realistic thresholds.

Important: thresholds do not affect data collection, they only control notification generation. If the threshold is too low (e.g., cold start 1 second, while 50% of devices start in 3 seconds), alerts will come constantly and become "noise" that developers stop noticing. Set thresholds based on current performance, then gradually tighten them as you optimize the app.

Performance Dashboard in the Firebase Console

The Performance Dashboard displays key metrics as time series broken down by app version, device, country, connection type, and OS version. For each metric, the following are available: average, median, 95th percentile, 99th percentile. The 95th percentile is the most informative metric for performance evaluation, as it shows how the app performs on weak devices, ignoring outliers.

The dashboard supports version comparison: select two app versions (current and previous) for visual metric comparison. If after an update the 95th percentile startup time increased from 2.1 to 3.4 seconds — the regression is obvious, and you need to find the commit that caused the slowdown. Firebase Performance integrates with GitHub, GitLab, and Bitbucket, allowing you to link metric changes to specific commits.

Code Examples for Performance Monitoring

Let's look at integration examples of Firebase Performance Monitoring in an Android app using Kotlin. The code demonstrates creating a custom trace for measuring news feed loading, adding an HTTP attribute for a non-automatically intercepted request, and using Trace to measure image processing time. All examples account for the ability to disable tracing via Remote Config.

Before using, add the dependency: implementation("com.google.firebase:firebase-perf") via Firebase BOM. For automatic instrumentation, no additional setup is required — the SDK intercepts standard operations automatically after adding the dependency.

Custom Trace for Feed Loading

The first example — measuring load time of the news feed from the server. The trace wraps the asynchronous fetchFeed operation, which retrieves data from the network and parses JSON. Custom attributes have been added to the trace: data source (cache or network) and the number of received posts. This allows segmenting data and understanding under which conditions the feed loads the slowest.

kotlin
suspend fun loadFeedWithTrace(source: String) {
    val trace = Firebase.performance
        .newTrace("feed_load")
    trace.putAttribute("source", source)

    try {
        trace.start()
        val feed = fetchFeed()
        trace.putMetric(
            "items_count",
            feed.size.toLong()
        )
    } finally {
        trace.stop()
    }
}

The function loadFeedWithTrace takes a source parameter ("cache" or "network"), which is used as a trace attribute. After the asynchronous operation completes, the trace stops in a finally block, guaranteeing stop even on exception. The items_count metric allows analyzing how the number of posts affects load time. In the Firebase console, you can filter traces by the source attribute and see that network loading is 3 times slower than cache.

HTTP Attribute for Non-Standard Request

The second example — HTTP attribute for a request made via WebSocket (not intercepted automatically). The HttpMetric class is used, which allows manually registering a URL request, its method, response code, and size. Firebase will display this request in the Network Requests section alongside automatically intercepted ones.

kotlin
suspend fun sendWithHttpMetric() {
    val metric = Firebase.performance
        .newHttpMetric(
            "https://api.example.com/data",
            FirebasePerformance.HttpMethod.POST
        )
    metric.start()

    try {
        val response = webSocketSend()
        metric.setHttpResponseCode(response.code)
        metric.setRequestPayloadSize(1024)
        metric.setResponsePayloadSize(
            response.body.length.toLong()
        )
    } finally {
        metric.stop()
    }
}

In the example, sendWithHttpMetric uses newHttpMetric to register a non-standard HTTP call. The SDK does not intercept it automatically, so the developer manually sets the URL, method, response code, and sizes. It is important to set the URL without query parameters (for security and aggregation) — that is, /data, not /data?token=abc. Firebase automatically groups identical URL patterns.

Measuring Image Processing Time

The third example demonstrates measuring time for image processing (compression, resizing) using a custom trace. In this case, the trace wraps a synchronous operation, but for production use coroutines or RxJava to avoid blocking the UI thread.

kotlin
fun compressImage(bitmap: Bitmap): ByteArray {
    val trace = Firebase.performance
        .newTrace("image_compression")
    trace.putAttribute(
        "format", "JPEG"
    )
    trace.start()

    val stream = ByteArrayOutputStream()
    bitmap.compress(
        Bitmap.CompressFormat.JPEG, 80, stream
    )
    val result = stream.toByteArray()
    trace.putMetric(
        "output_size_kb",
        result.size / 1024.toLong()
    )
    trace.stop()
    return result
}

The function compressImage measures image compression time to JPEG at 80% quality. The format attribute allows comparing JPEG versus WebP compression time in the future. The output_size_kb metric shows how efficient the compression is. In the Firebase console, you can see the distribution: on weak devices (budget Android), compression takes 4 times longer than on flagships, which could be the cause of delays when uploading images to the server.

How to Improve Performance Based on Data

Firebase Performance provides data but does not give ready-made solutions. Analyzing metrics requires understanding typical causes of performance degradation for each metric. Let's look at the main degradation patterns and how to diagnose them using Performance Monitoring data. Approach: find an anomaly in a metric → check typical causes → apply optimization → verify the result after a week.

Slow cold start (> 2 seconds): causes — heavy SDK initialization in Application.onCreate (analytics, crash reporting, map SDK), loading large resources (fonts, themes), synchronous operations on the main thread at startup. Solutions: lazy SDK initialization, deferred resource loading, using SplashScreen API (Android 12+) to show a placeholder during initialization. Firebase Performance will show which app version started slowing down — check which dependencies were added or updated.

Slow screen rendering (> 500 ms): causes — complex View hierarchy (nested ConstraintLayout, multiple Fragments), loading data on the UI thread (network or disk), heavy draw operations (large images, custom Views). Solutions: optimize layout hierarchy (Layout Inspector in Android Studio), offload data to background thread, cache images via Glide or Coil. Use the Screen Rendering filter in Firebase to find the slowest screen and optimize it first.

Optimizing Network Requests

Slow HTTP requests (> 3 seconds): causes — slow server, large payloads, lack of caching, suboptimal protocol (HTTP/1.1 instead of HTTP/2), DNS resolution. Solutions: check the server side (uptime, latency), reduce response size (pagination, GraphQL, protobuf instead of JSON), enable caching via HTTP headers (Cache-Control), use OkHttp Interceptor to add timeouts and retry logic.

Firebase Performance shows request time distribution: DNS resolution, TCP handshake, TLS handshake, request send, response receive. If most of the time is spent on DNS — use DNS preloading (OkHttp DNS-over-HTTPS). If on TLS — use session resumption and tune cipher suites. If on response receive — check response size and user network speed. Firebase data allows localizing the problem at the protocol level, rather than just saying "request is slow".

Remote Config Integration for Disabling Tracing

For production, it is recommended to add a Remote Config flag performance_tracing_enabled, which allows remotely disabling custom traces. If the Firebase Performance SDK on the client generates too much data or affects performance (on weak devices), you can disable traces for all users, leaving only automatic metrics, which have minimal overhead.

Example logic: at app startup, check the Remote Config parameter performance_tracing_enabled. If false — all calls to Firebase.performance.newTrace() return a stub object that does not collect data. This is implemented via a wrapper class that checks the flag before creating a trace. This approach allows enabling detailed tracing for specific users (beta testers, developers) without affecting the entire audience.

Frequently Asked Questions

Does the Performance SDK affect app performance?

SDK overhead is minimal — less than 1–2% of the time of measured operations. Data is collected asynchronously on a background thread and buffered on the device. For production apps with millions of users, the additional load from the SDK is negligible and does not affect UX.

How long is data stored in Firebase Performance?

On the free Spark tier — 30 days, on the paid Blaze tier — up to 365 days. For long-term storage and analysis, use BigQuery export: Performance data can be exported to BigQuery and stored indefinitely (charged separately).

Can Firebase Performance be used with Flutter?

Yes, through the native Android and iOS SDKs. The firebase_performance Flutter plugin provides an API for custom traces and HTTP attributes. Automatic metrics (app start, screen rendering) are only available through native SDKs and do not cover the Flutter layer. For full Flutter monitoring, use DevTools alongside Firebase Performance.

How to set up performance degradation notifications?

In the Firebase console (Performance > Thresholds), set thresholds for metrics and configure notification channels: email, Slack, PagerDuty, Cloud Functions. It is recommended to set alerts for cold start and slow HTTP request share — these are the most critical metrics for user experience.

Why is there no data in the Firebase Performance dashboard?

Main reasons: SDK not added to the project, app has not been launched on a physical device (emulator may not send data), less than 12 hours have passed since the first launch (data appears within 24 hours), network blocking on the device (firewall, VPN). Check the SDK logs: enable verbose Performance SDK logging in a debug build.

Summary

  • Firebase Performance Monitoring is a free tool for collecting performance metrics from production devices.
  • Automatic metrics (app start, screen rendering, HTTP requests) are collected without writing code.
  • Custom traces allow measuring the performance of specific scenarios with attributes and metrics.
  • Thresholds and alerts help respond to degradation before users notice it.
  • 95th percentile is the key metric for evaluating performance on weak devices.
  • Data is stored for 30 days (Spark) or up to 365 days (Blaze) with BigQuery export capability.
  • Optimization starts with the dashboard: find the slowest screen or request and fix the cause.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also