feat(extend-app-start): [3/4] Eagerly create the extended app start transaction#5608
Open
buenaflor wants to merge 32 commits into
Open
feat(extend-app-start): [3/4] Eagerly create the extended app start transaction#5608buenaflor wants to merge 32 commits into
buenaflor wants to merge 32 commits into
Conversation
Contributor
|
This was referenced Jun 23, 2026
📲 Install BuildsAndroid
|
Contributor
Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| ba0608b | 319.63 ms | 373.04 ms | 53.41 ms |
| 682e090 | 347.33 ms | 427.28 ms | 79.95 ms |
| db5be2f | 311.84 ms | 365.94 ms | 54.10 ms |
| 388ffc5 | 315.18 ms | 362.43 ms | 47.25 ms |
| ca0c0cf | 318.45 ms | 370.06 ms | 51.61 ms |
| b76203f | 336.02 ms | 403.42 ms | 67.40 ms |
| 201a6fd | 326.00 ms | 371.92 ms | 45.92 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| ba0608b | 0 B | 0 B | 0 B |
| 682e090 | 0 B | 0 B | 0 B |
| db5be2f | 0 B | 0 B | 0 B |
| 388ffc5 | 0 B | 0 B | 0 B |
| ca0c0cf | 0 B | 0 B | 0 B |
| b76203f | 0 B | 0 B | 0 B |
| 201a6fd | 0 B | 0 B | 0 B |
Previous results on branch: feat/app-start-extension-materialize
Startup times
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 69caaee | 313.73 ms | 373.92 ms | 60.19 ms |
| 3a27919 | 371.17 ms | 447.31 ms | 76.14 ms |
| 4451634 | 321.21 ms | 376.21 ms | 55.00 ms |
| ae82ca0 | 381.62 ms | 426.12 ms | 44.51 ms |
| 44c06ea | 324.19 ms | 384.88 ms | 60.69 ms |
| 4cf89ba | 340.51 ms | 416.92 ms | 76.41 ms |
| a037262 | 318.06 ms | 364.59 ms | 46.52 ms |
| 20bbe9a | 305.48 ms | 387.25 ms | 81.77 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 69caaee | 0 B | 0 B | 0 B |
| 3a27919 | 0 B | 0 B | 0 B |
| 4451634 | 0 B | 0 B | 0 B |
| ae82ca0 | 0 B | 0 B | 0 B |
| 44c06ea | 0 B | 0 B | 0 B |
| 4cf89ba | 0 B | 0 B | 0 B |
| a037262 | 0 B | 0 B | 0 B |
| 20bbe9a | 0 B | 0 B | 0 B |
54be119 to
d2b96ad
Compare
0f8ee4d to
5dfb0e1
Compare
5dfb0e1 to
0bd259a
Compare
5dd39af to
3bc1643
Compare
0bd259a to
0b6ada0
Compare
3bc1643 to
45f6c0b
Compare
c3f3627 to
cbaef2f
Compare
…tion (standalone-only) Registers an extend-listener on AppStartExtension that eagerly creates the standalone app.start transaction + extended child span in Application.onCreate, held open via waitForChildren until Sentry.finishAppStart() or the deadline. The first activity continues the eager trace into ui.load (attaching the screen so it stays a foreground app.start) instead of creating a second app.start; headless finishes the eager txn. The app start vital is max(natural, extended) so an early finish never shortens it, and is suppressed on deadline. Standalone-only. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2d5188e to
01b1dc4
Compare
cbaef2f to
d996425
Compare
…on extendAppStart Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… coverage Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nd trim comments Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…xtension-materialize
…app start path Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…xtension-materialize
…xtension-materialize
Two issues in onHeadlessAppStart for extended starts: - The extended branch finished the eager transaction but never persisted appStartEndTime, leaving the continuation window unbounded so a later activity would wrongly continue the stale trace. Persist it on all paths. - The branch only checked isActive(), so if the extension already finished (finishExtendedAppStart or the deadline) before the headless idle ran, a second, empty standalone app.start was created. Guard on shouldSendStartMeasurements to avoid the duplicate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…n path The first activity continuing an extended app.start did not clear the stored trace headers (only the headless-follow path did), so a later activity saw them and wrongly reused the finished app start trace. Clear them on the extension path too. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…t screen While the extension was open, every activity's onActivityCreated re-attached app.vitals.start.screen to the eager app.start, so a second activity opened before finishExtendedAppStart() overwrote the launch screen. Gate the attach on isAppStart so only the launch activity sets it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…xtension-materialize
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…lize' into feat/app-start-extension-materialize # Conflicts: # sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java
…xtension-materialize
…xtension-materialize
Remove comments that restated the adjacent test code (the eager extendAppStart call and the second-activity open). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…xtension-materialize
…xtension-materialize
…xtension-materialize
The test names describe the scenarios; the inline comments restated them. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…xtension-materialize
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit c861ba9. Configure here.
…xtension-materialize
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

PR Stack (Extend App Start)
📜 Description
Registers the extend-listener and wires the extension through to the trace and the vital, making the feature work end-to-end. The extension is eager and standalone-only — only the standalone
app.starttransaction is independent of an activity and can be created inApplication.onCreate.ActivityLifecycleIntegrationenableStandaloneAppStartTracingis on (this is what makes the API standalone-only). OnSentry.extendAppStart()the listener eagerly creates the standaloneapp.starttransaction (waitForChildren+ deadline) and itsapp.start.extendedchild, and returns them as anExtendedAppStart.PerformanceAndroidEventProcessormax(natural first-frame duration, extended end), so an early finish never shortens it. On deadline the measurement is suppressed entirely (no inflated ~30s value); spans still attach. Non-extended starts are unchanged.Notes
appStartTransactionfield, so per-activity cleanup can't cancel it.ui.load(viaisActive()) instead of starting a secondapp.start, and attaches the screen so the foregroundapp.startkeeps itsapp.vitals.start.screen.waitForChildrenholds it open untilSentry.finishExtendedAppStart(). Headless finishes it at the headless stop time. A sharedcreateStandaloneAppStartTransaction(...)helper backs both paths.ui.load) extension path are removed — eager creation makes them unnecessary.💡 Motivation and Context
Part of the app start extension API stack (#5553). This is where the extension actually affects the trace and the vital, scoped to standalone app start tracing because only the standalone
app.starttransaction can be created eagerly inonCreate.💚 How did you test it?
Unit tests (TDD):
ActivityLifecycleIntegrationTest— eagerapp.start+ extended child on extend; first activity continues the trace with no secondapp.startand the screen attached; standalone & headless stay open untilfinishExtendedAppStart(); standalone-off is a no-op; the eager txn survives activity destroy.PerformanceAndroidEventProcessorTest— extended end drives the cold measurement; an early finish never reports shorter than the first-frame duration; a deadline finish suppresses the measurement.apiCheck, spotless, and the:sentry-android-coreunit suite pass.📝 Checklist
sendDefaultPIIis enabled.🔮 Next steps
[4/4]— add the publicSentry.extendAppStart()/Sentry.finishExtendedAppStart()/Sentry.getExtendedAppStartSpan()facade.#skip-changelog