Track your FlutterFlow app's performance by enabling Firebase Performance Monitoring (automatic app start and screen render traces), adding custom traces around your slowest operations via a Custom Action, and monitoring Crashlytics for crash-free user rate. The critical mistake is testing only in FlutterFlow's Run Mode on a fast desktop connection — real users on 3G with budget Android phones see completely different performance numbers.
What Firebase Performance Monitoring Measures
Firebase Performance Monitoring automatically measures three things the moment you enable it: app start time (from launch to first interactive frame), screen render time (frame rate per page), and network request latency (how long HTTP calls take). These automatic traces cover most of what you need. For custom workflows — like the time it takes to load a user's feed, process a payment, or render a chart — you add custom traces using the Performance SDK in a FlutterFlow Custom Action. All data is split by device, OS, country, and app version in the Firebase Console, making it easy to see that your app is fast on iOS but slow on Android 10.
Prerequisites
- FlutterFlow project with Firebase connected
- Firebase Performance Monitoring package added to your FlutterFlow project (firebase_performance)
- App published or in Test Flight/internal testing — Run Mode performance is not representative
- Firebase Analytics enabled (Performance Monitoring uses the same data pipeline)
Step-by-step guide
Enable the Firebase Performance Monitoring package
Enable the Firebase Performance Monitoring package
In FlutterFlow go to Settings > Flutter Packages and add firebase_performance at the latest version. This package is separate from firebase_core and must be added explicitly. After adding it, go to your main.dart initialization (Custom Code > main function if you have one, or FlutterFlow's Firebase initialization flow) and confirm that Firebase is initialized before the app runs. Performance Monitoring auto-initializes when the package is present — no additional code is needed for automatic traces. Rebuild your app in Test Mode to confirm there are no package conflicts.
Expected result: The firebase_performance package is in your project's dependencies and Performance Monitoring shows 'Connected' in Firebase Console.
Interpret automatic traces in the Firebase Console
Interpret automatic traces in the Firebase Console
Navigate to Firebase Console > Performance > Dashboard. The Traces table shows three automatic trace types: _app_start (time from cold launch to first frame), _st_{PageName} (screen render per page), and network traces for every HTTP call your app makes. Click on _app_start and view the duration percentile distribution. The p50 (median) should be under 2 seconds; p95 should be under 5 seconds. Click on a specific page's screen trace and look for the 'Slow/Frozen frames' rate — above 1% slow frames means users are experiencing jank. Use the filters at the top to segment by device model, OS version, and country to pinpoint where performance is worst.
Expected result: You can identify your three slowest screens and the device/OS combinations where performance is worst.
Add a custom trace around your heaviest operation
Add a custom trace around your heaviest operation
Automatic traces don't tell you why a screen is slow — just that it is. Add a custom trace to instrument your most complex operation. In FlutterFlow create a Custom Action called startPerfTrace and another called stopPerfTrace. The start action creates a named trace and starts it; the stop action stops it and records the duration to Firebase. Wrap these around your most expensive flow, such as loading a personalized feed, processing an image, or running a multi-step form submission. In the Firebase Console, your custom trace appears under Performance > Custom Traces with the same distribution and segmentation views as automatic traces.
1// Custom Action: perfTrace.dart2import 'package:firebase_performance/firebase_performance.dart';34// Store active traces — keyed by name5final Map<String, Trace> _activeTraces = {};67Future startPerfTrace(String traceName) async {8 final trace = FirebasePerformance.instance.newTrace(traceName);9 await trace.start();10 _activeTraces[traceName] = trace;11}1213Future stopPerfTrace(String traceName) async {14 final trace = _activeTraces[traceName];15 if (trace != null) {16 await trace.stop();17 _activeTraces.remove(traceName);18 }19}2021// Add custom metric to an active trace22Future addTraceMetric(23 String traceName, String metricName, int value) async {24 _activeTraces[traceName]?.setMetric(metricName, value);25}Expected result: Custom trace durations appear in Firebase Console > Performance > Custom Traces within 24 hours of real device usage.
Monitor Crashlytics alongside Performance for a full health picture
Monitor Crashlytics alongside Performance for a full health picture
Performance Monitoring tells you about slowness; Crashlytics tells you about crashes. Both together give you a complete app health view. In Firebase Console open Crashlytics and check three metrics: crash-free users rate (should be above 99.5% for a healthy app), crash count trend over the last 30 days, and affected users per issue. Click each issue to see the stack trace, affected device models, and the app version that introduced it. For performance-related crashes (out-of-memory, ANR — Application Not Responding), you will see them in both Crashlytics and as spikes in the Performance > Slow/Frozen frames view. Set up Crashlytics Velocity Alerts to receive an email when a new crash type affects more than 0.1% of your users in one hour.
Expected result: You have a baseline crash-free rate and the top crash types identified and prioritized.
Set up performance regression alerts
Set up performance regression alerts
Firebase Performance Monitoring supports threshold alerts that fire when a metric crosses a value you define. Go to Firebase Console > Performance > Alerts and create a new alert. Select the trace (e.g., _app_start), choose the metric (duration p90), set the threshold (e.g., alert when > 4000ms), and add your email. Create alerts for your three most critical traces: app start time, your highest-traffic screen, and your main Cloud Function's HTTP response time. Also go to Firebase Console > Functions > Dashboard and check the 95th percentile execution time for each Cloud Function. Functions taking more than 5 seconds regularly indicate a query or external API call that needs optimization.
Expected result: You receive email notifications when app start time or key trace durations exceed your defined thresholds.
Complete working example
1// Custom Actions for Firebase Performance Monitoring2// Add firebase_performance to your FlutterFlow packages3import 'package:firebase_performance/firebase_performance.dart';45// In-memory store for active traces (single session scope)6final Map<String, Trace> _activeTraces = {};78/// Start a named performance trace9Future<void> startPerfTrace(String traceName) async {10 try {11 final trace = FirebasePerformance.instance.newTrace(traceName);12 await trace.start();13 _activeTraces[traceName] = trace;14 } catch (e) {15 // Fail silently — performance tracking should never crash the app16 debugPrint('PerfTrace start error: $e');17 }18}1920/// Stop a named performance trace and record it21Future<void> stopPerfTrace(String traceName) async {22 try {23 final trace = _activeTraces[traceName];24 if (trace != null) {25 await trace.stop();26 _activeTraces.remove(traceName);27 }28 } catch (e) {29 debugPrint('PerfTrace stop error: $e');30 }31}3233/// Add a custom integer metric to an active trace34/// (e.g., number of items loaded, bytes downloaded)35Future<void> addTraceMetric(36 String traceName, String metricName, int value) async {37 try {38 _activeTraces[traceName]?.setMetric(metricName, value);39 } catch (e) {40 debugPrint('PerfTrace metric error: $e');41 }42}4344/// Add a custom attribute to an active trace45/// (e.g., user segment, feature flag value)46Future<void> addTraceAttribute(47 String traceName, String key, String value) async {48 try {49 _activeTraces[traceName]?.putAttribute(key, value);50 } catch (e) {51 debugPrint('PerfTrace attribute error: $e');52 }53}Common mistakes when tracking the Performance of Your FlutterFlow App
Why it's a problem: Only checking performance in Run Mode on a fast WiFi connection
How to avoid: Always test performance on a real physical device, preferably a mid-range Android (not your development iPhone). Use Firebase Performance Monitoring data from real users as the authoritative source.
Why it's a problem: Adding performance traces inside widget build methods
How to avoid: Place traces around user-initiated operations in action flows (button taps, page loads), not in widget constructors or build methods.
Why it's a problem: Ignoring the p95 metric and only looking at p50 (median)
How to avoid: Always review p95 alongside p50. Your optimization target should be bringing p95 down, not improving the median of already-fast users.
Best practices
- Treat your app start time p90 as a product KPI — track it in your analytics dashboard and alert on regressions after every release.
- Wrap every Cloud Function call from FlutterFlow with a custom trace so you can see end-to-end latency including network time, not just server execution time.
- Segment performance data by app version in the Firebase Console to immediately identify which release caused a regression.
- Test on at least three device classes: a flagship phone, a 3-year-old mid-range Android, and a tablet — they will have very different performance profiles.
- Keep your Firestore queries paginated with a page size of 20-50 items. Loading 500 documents into a list on a slow connection is the single most common performance killer in FlutterFlow apps.
- Use Firebase Performance network traces to identify which API endpoints are slow — sometimes a third-party API is the bottleneck, not your app code.
- Review Cloud Function cold start times in Performance data. If cold starts are frequent, consider minimum instances to keep functions warm for high-traffic endpoints.
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I have a FlutterFlow app using Firebase and want to set up proper performance monitoring. Explain how Firebase Performance Monitoring's automatic traces work, how to add custom traces for specific operations, and how to interpret the percentile distribution data in the Firebase Console. What are the key metrics I should track and what thresholds indicate a problem?
Write a FlutterFlow Custom Action in Dart that wraps Firebase Performance Monitoring's Trace API. I need functions to start a named trace, stop it, add a custom integer metric, and add a custom string attribute. Include error handling so performance tracking never crashes the app.
Frequently asked questions
How long does it take for Performance Monitoring data to appear in the Firebase Console?
Automatic traces from real devices typically appear within 12-24 hours of the first session. Custom traces follow the same pipeline. The Realtime tab in Firebase Console shows data within a few minutes, but the main dashboard aggregates over a longer window.
Can I see performance data from FlutterFlow's Test Mode?
Test Mode runs in a browser on your machine and is not a representative environment for performance data. The performance numbers you see in Test Mode reflect your development hardware and network, not your users' devices. Use internal distribution (TestFlight, Firebase App Distribution) to test on real devices.
What is a good app start time target?
Aim for under 2 seconds at p50 and under 4 seconds at p95 for a cold start. Warm starts (app already in memory) should be under 1 second. If your app start p90 is above 5 seconds, investigate what is running in your On App Load actions.
How do I measure Firestore query performance specifically?
Wrap your Firestore query in a custom trace: call startPerfTrace before the query action in FlutterFlow and stopPerfTrace after the result is returned. You can also add a metric for the number of documents returned. This gives you query-specific latency data in the Firebase Console.
Is Firebase Performance Monitoring free?
Yes. Performance Monitoring is included at no cost on both the Spark (free) and Blaze plans. There are no per-event charges for performance data. The only costs are indirect — if performance monitoring drives you to increase Firebase Function invocations, those are billed normally.
Can I track performance for specific user segments?
Yes, via custom trace attributes. Call addTraceAttribute with a key like 'user_segment' and the user's segment value before stopping the trace. You can then filter performance data by this attribute in the Firebase Console's custom traces view.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation