-
-
Notifications
You must be signed in to change notification settings - Fork 359
Description
Problem
App start data (cold/warm start measurements) is currently attached to the first sampled navigation transaction as a carrier. This coupling creates several structural problems.
1. Fragile lifecycle dependency
App start data depends on the first navigation transaction surviving its entire lifecycle. That transaction has its own complex lifecycle:
- Idle timeout / heartbeat expiry
- Discard logic (
ignoreEmptyRouteChangeTransactions,ignoreEmptyBackNavigation) - Timing-dependent navigation container registration (
registerNavigationContainer)
Any of these can cause the transaction to be dropped, silently discarding app start data with it. This is the root cause of RN-538 (fixed in #5833 as a targeted workaround).
2. Inconsistent sampling behavior
App start data is only sent when a sampled transaction exists to carry it:
tracesSampleRate: 1.0→ works reliablytracesSampleRate: 0.1→ app start attaches to the first sampled transaction, which may not be the first navigation eventtracesSampleRate: 0→ app start is never sent, even whenenableAppStartTracking: true
A user who explicitly enables enableAppStartTracking likely expects to receive this data regardless of general tracing sample rate. The current design silently drops it.
3. Semantic mismatch between carrier and data
App start measurements can end up attached to any root span that happens to be first and sampled — not necessarily a navigation transaction. This makes the data harder to query consistently in Sentry.
Current workaround
#5833 added a lazy-check mechanism: if the locked navigation transaction is later found to be unsampled, the integration falls through to the next transaction. This fixes the specific regression in RN-538 but doesn't address the structural coupling.
Proposed direction
Decouple app start data from the navigation transaction lifecycle. Possible approaches:
- Dedicated app start transaction — Send app start as its own transaction (similar to the existing
captureStandaloneAppStartpath), always whenenableAppStartTracking: true, respecting a separate or elevated sample rate. - Guaranteed attachment — Attach app start to the first root span regardless of
_sampledstatus, so sampling decisions don't silently discard it. - Session-level metric — Explore whether app start fits better as a session-attached metric rather than a transaction measurement.
Considerations
- Any change to sampling behavior for app start may be a breaking change for users who set
tracesSampleRate: 0to opt out of performance data entirely. - The
captureStandaloneAppStartpath already exists and may be a useful foundation. - Coordination with other mobile SDKs (Flutter, MAUI, Unity) if the approach is standardized.