Capability parity
Browser-only metrics such as LCP and CLS are not generated for Flutter applications. Flutter reports its build, raster,
refresh-rate, slow-frame, frozen-frame, and memory data.
Requirements
- Flutter 3.35 or later;
- Dart 3.9 or later;
- Android 24+ or iOS 13+ when using the default persistent identity store.
device_info_plus,
battery_plus, and connectivity_plus, which the package depends on. Set trackDeviceInfo: false to send only what Flutter
itself exposes.
Install and initialize
1
Create the application
Open RUM → Applications, click Create application, and choose the Flutter platform. Open the setup
guide shows the endpoint, the token, and the configuration filled in with the identifier.
2
Add the package
flutter pub get after updating pubspec.yaml.3
Initialize before runApp
initRum as early as possible: the cold-start time is measured from it to the first frame. RumApp installs the
replay boundary, automatic tap collection, and frustration detection. Replay remains disabled unless
sessionReplaySampleRate selects the current session or recording is started manually.4
Verify the first session
Open RUM → Explorer, select a time range that includes the current time, and confirm that the session of
checkout-mobile appears. Open it to inspect the views and the device context.site accepts the MoleSignal origin, or a base that ends in /api, /api/v1, or /api/v1/rum. The SDK completes the path
and sends events to POST /api/v1/rum/events. applicationId must be the application of the token: it is sent as application.id,
and MoleSignal rejects events that name another application.
Sessions and views
A session is identified by a UUID kept in shared preferences. It ends after 15 minutes without activity or after four hours, and is sampled once, when it starts. The SDK sends no session event: MoleSignal derives sessions from the views. Every event carriessession.id, session.type, and session.start; a view also carries session.has_replay, which is true once a segment
of the session was recorded. A view never spans two sessions: when a session is renewed under a showing view, that view ends and the
same screen continues in a new view with loading_type: session_renewal.
RumNavigationObserver records visible named routes. Supply the observer through the router integration for Router or
go_router applications. Call startView when a route has no stable name or when navigation is managed outside Navigator.
view.url is the route path, without query and fragment unless trackUrlQueryString is set, and view.name is the name. Starting
a view ends the previous one. A view is reported again with a higher view.revision and its counts so far whenever something
in it changed: at most once per flushInterval, and immediately when it starts, ends, or the app is flushed. Views end when the app
goes to the background and are shown again, as view_controller_redisplay, when it returns. Events that happen before the first
startView belong to an ApplicationLaunch view.
Identify users and record application activity
FlutterError.onError and PlatformDispatcher.onError handlers. Forward errors from additional isolates to
the main isolate and call addError. Call clearUser() after sign-out when the next activity must no longer use the identified user.
Actions are tap, custom, back, and the automatic application_start. Automatic taps use the generic name Tap so no screen
content is read. Wrap important controls with RumUserAction to attach a stable business name without taking ownership of Flutter’s
gesture arena:
action.id, and the action reports their counts. Three taps within 50 logical pixels in a second make the last a rage_tap,
and a tap that caused an error is an error_tap. Set trackUserInteractions: true to collect taps; trackFrustrations follows it by default.
Errors carry source, type, message, stack, structured frames, and handling. Framework errors are unhandled, and errors from
PlatformDispatcher.onError are also crashes. addError reports a handled error with the source you choose, custom by default. A request
that failed before a response is a network error; an HTTP error status is only a resource. The SDK does not set error.fingerprint; pass
fingerprint: to choose the grouping.
Monitor HTTP resources and backend traces
Wrappackage:http with MoleSignalHttpClient:
http: ^1.6.0 as a direct application dependency when the application does not already use package:http. The wrapper records
the sanitized URL, method, duration, status code, response size, and available W3C trace identifiers. The duration ends when the response body
is consumed, fails, or is cancelled. Trace context is read in this order: response traceparent, a traceparent entry in Server-Timing,
then request traceparent. Restrict trace-header reading when only selected services are trusted:
startResource and stopResource from their interceptors, or
addResource for a finished request.
Rendering performance fields
Upload release symbols
Setversion, architecture, and debugId from immutable release-pipeline values. Use the same values for every debug artifact
produced by that build. Runtime-detected or derived fallbacks are useful for development, but do not provide a stable production
symbolication identity.
Build Android and iOS releases with --obfuscate and --split-debug-info, and pass the identity with --dart-define:
--split-debug-info, each error frame carries artifact_kind: flutter_symbols, the absolute and relative addresses a symbol file resolves,
and the debug_id the build was configured with. Upload every generated .symbols file with kind=flutter_symbols, the matching android or
ios platform, canonical architecture, and Debug ID. Upload native Android ELF symbols and Apple dSYM DWARF files separately when native crash
frames are forwarded with RumStackFrame.
Artifact upload requires a management token with streams.configure. Never use the application-bound msrum_ client token for artifact management.
Source maps & symbols
Generate, upload, match, and verify Flutter, Android, iOS, and Web debug artifacts.
Enable session replay
Flutter has no DOM. The first captured frame becomes rrwebMeta and FullSnapshot events. Changed frames become incremental image
mutations, and unchanged frames are skipped. The existing MoleSignal replay player can therefore render browser and Flutter sessions
through the same workflow.
sessionReplaySampleRate applies within sessions included by sessionSampleRate; multiply both rates to calculate effective replay coverage.
Manual recording also applies only to an included session. Replay uses a separate queue, a 10-second default flush interval, per-session
sequence numbers, approximately 1 MiB target segments, and an 8 MiB request ceiling. Segments go to POST /api/v1/rum/replay.
Protect replay content
The defaultRumPrivacyLevel.mask covers Text, RichText, and editable regions before PNG encoding. Input fields stay masked in allow mode.
The SDK also removes URL queries and fragments and recursively redacts common sensitive context keys. Raw stack text is sent only with
RumPrivacyLevel.allow; otherwise error.stack is rebuilt from the sanitized frames. Wrap sensitive images, maps, custom-painted content,
platform views, or complete components in an explicit privacy boundary:
RumReplayMask and RumReplayBlock both replace the captured region with an opaque block. Raw, unmasked pixels never enter the event queue.
Delivery
Events are batched into a JSON array and sent toPOST {site}/api/v1/rum/events with the client token. Batches of more than 1 KiB are
gzip-compressed where dart:io is available; set compressRequests: false to turn it off. A request holds at most 48 KiB of events, far below
the 5000 events and 5 MiB the receiver accepts.
- An event that MoleSignal rejects is reported through
onErrorandRumFlushResult, and is never sent again. - Network errors, timeouts,
408,429, and5xxare retried with exponential backoff and jitter, never sooner than theRetry-Afterthe receiver sent. Events survive in a persisted offline queue. - Any other
4xxdrops the batch.
maxQueueSize, maxQueueBytes, queueItemTtl). A newer revision of a view replaces
the older ones that are still waiting, so the revision numbers MoleSignal sees may skip values.
Main configuration
RumSessionReplayConfiguration defaults to a 5-second capture interval, capture after actions, 0.5 output pixels per logical pixel,
a 900-pixel maximum image edge, and mask color #6B7280. excludedUrls, allowedTracingUrls, queue bounds, retry delays, timeouts,
diagnostics, custom transport, and persistence are also configurable.
Flush and stop
Callflush() before a controlled transition that must wait for queued events. Call stop() during final teardown to end the active view
with a last report, remove instrumentation, and flush both event queues. Both return a RumFlushResult that separates accepted, retried,
dropped, remaining, and timed-out events.
Browser RUM SDK
Compare the Browser SDK setup and browser-specific instrumentation.
RUM event format
The events the SDK sends, and the fields of each.
Source maps & symbols
Restore Flutter, Android, iOS, and Web release stacks.