Repository navigation
[Due for payment 2026-10-12] Add account-size telemetry to Sentry (db_size, re-bucketed count tags, transactions_count) #98432
Description
Strategy
The largest accounts are where app performance is compared hardest against competitors, and where slowness hurts retention most. Keeping the app fast for them means our performance work has to target the factors that actually cause slowness for a given group of users, instead of spreading effort evenly.
Background
We use user-level tags in Sentry to split performance data into groups — today we have reports_count, personal_details_count and policies_count (added in #80531). These cover a lot and work well for basic segmentation. Some facts about the data behind them — partly just how the app works, partly what production data shows:
- Onyx loads the whole local database into memory on every app start, so startup time grows with database size.
- In production span data, nearly all enterprise users report
personal_details_count:10000+, and ~95% of all spans carrypolicies_count:2-10. - Transactions are the most numerous entity in an account — the applause account holds 62.8k transactions vs 13.2k reports.
Problem
When a group of users shows bad p90s in Sentry, we can't tell whether the cause is local data volume or lots of transactions — the size categories we already collect put nearly all users into the same few buckets — so we end up reproducing heavy accounts manually or picking optimization targets by guessing.
Solution
Three independent additions, one per fact above. Each works on its own — we're happy to land just some of them, and we'd like to hear opinions on which ones are worth it.
1. db_size — first ship only the exact db_size_bytes numeric attribute, and once we've collected real data, add a bucketed tag with borders based on the actual size distribution. The value is measured at app start and re-measured whenever the underlying data changes (e.g. report or transaction count changes), through a debounced call so it doesn't fire too often. Each measurement updates the value attached to new spans and is also stored, so on the next app start the last known value is attached right away — every span, including the TTI/startup span, carries it. With this, any span can be filtered by database size, so "slow because the local DB is big" becomes directly checkable. Onyx already exposes Storage.getDatabaseSize() on all platforms: on mobile it reads the SQLite header, so the value is exact and cheap (cost does not grow with DB size); on web a reliable value exists only on Chromium browsers (~92% of our web spans), and everywhere else we report an explicit unavailable.
2. Re-bucket the existing tags in two steps — data first, buckets second
- a. Add the exact values as numeric span attributes (now) —
reports_count_raw,personal_details_count_raw,policies_count_raw,transactions_count_raw. The middleware that already copies tags to child spans (copyTagsToChildSpans) adds them in its existing loop, so it's a few lines of code. Numeric attributes support range filters and aggregations in Sentry (p90(),avg()— this already works for the existingreport_action_countattribute), so deep analysis is possible from day one. The existing bucketed tags stay untouched in the meantime. - b. Design new buckets for the tags based on the real distributions we collected (after ~1-2 weeks of data) — instead of guessing borders now. We deliberately don't propose the borders yet; that will be a short follow-up once the data is in. Two things we already know for that step: the re-bucketed tags will need new names (e.g.
reports_count_v2), because Sentry keeps ~3 months of data and old bucket values would mix with new ones in every query; and bucket labels will need an ordering prefix (e.g.1_0-100,2_101-1k), because Sentry sorts tag values alphabetically.
3. transactions_count — a new tag counting transactions. With it, we can compare p90s between users with hundreds vs tens of thousands of transactions and decide whether transaction-heavy accounts need dedicated optimization work. Implementation is simple: same pattern as the existing count tags in TelemetrySynchronizer, one entry in CONST.TELEMETRY.TAGS (child spans get it automatically since #86182). Same caveat as reports_count: this counts the local cache, not the whole account.
Reported in Slack.
Issue Owner
Current Issue Owner: @aimane-chnaifIssue Owner
Current Issue Owner: @aimane-chnaifMetadata
Metadata
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity
melvin-bot commentedon Aug 17, 2026
@arekm213 Eep! 4 days overdue now. Issues have feelings too...
arekm213 commentedon Aug 18, 2026
Im working on this issue, i hope to deliver a PR with that tomorrow
melvin-bot commentedon Aug 21, 2026
@arekm213 Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!
35 remaining items
[-][Due for payment 2026-09-07] Add account-size telemetry to Sentry (db_size, re-bucketed count tags, transactions_count)[/-][+][Due for payment 2026-10-12] Add account-size telemetry to Sentry (db_size, re-bucketed count tags, transactions_count)[/+]melvin-bot commentedon Oct 5, 2026
@aimane-chnaif @mallenexpensify
The solution for this issue has been 🚀 deployed to production 🚀 in version 9.5.2-4 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:
If no regressions arise, payment will be issued on 2026-10-12. 🎊
The following checklist (instructions) will need to be completed before the issue can be closed. Please copy/paste the Contributor+ Checklist from here into a new comment on this GH and complete it. If you have the K2 extension, you can simply click: [this button]. If no checklist is needed for this issue, you can click: [no checklist button]
aimane-chnaif commentedon Oct 6, 2026
Not overdue
melvin-bot commentedon Oct 9, 2026
@aimane-chnaif Whoops! This issue is 2 days overdue. Let's get this updated quick!
aimane-chnaif commentedon Oct 11, 2026
BugZero Checklist:
[Contributor] The offending PR has been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake.
Link to comment:
[Contributor] If the regression was CRITICAL (e.g. interrupts a core flow) A discussion in #expensify-open-source has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner.
Link to discussion:
[Contributor] If it was decided to create a regression test for the bug, please propose the regression test steps using the template below to ensure the same bug will not reach production again.
[BugZero Assignee] Create a GH issue for creating/updating the regression test once above steps have been agreed upon.
Link to issue: https://github.com/Expensify/Expensify/issues/679893
Regression Test Proposal
no need. sentry issue
mallenexpensify commentedon Oct 14, 2026
@aimane-chnaif is additional payment due here?
aimane-chnaif commentedon Oct 14, 2026
yes because it's different PR
mallenexpensify commentedon Oct 14, 2026
Updated payment summary above