Profiling: add Profile Functions tab to Explore UI
- Dominant language
- Python
- Stars
- 44.8k
- Forks
- 4.9k
- Avg merge
- 21h 10m
- Merged PRs (30d)
- 635
Description
## Summary
There is no UI path to query all transactions where a specific profiled function exceeded a given duration threshold. The backend EAP `profileFunctions` dataset already stores this data with `function`, `function.duration`, and `transaction_name` as filterable attributes, but the Explore UI has no "Profile Functions" tab to surface it.
## Current behavior
The existing profiling UI surfaces function performance in three ways:
- **Slowest Functions widget** — aggregates function performance across all profiled transactions, but links only to individual flamegraph captures, not a filtered transaction list.
- **Suspect Functions table** — scoped to a single transaction type, same limitation.
- **Function Trends widget** — navigates to individual profiles only; no cross-transaction search.
The EAP API is also not publicly exposed, so customers cannot query the `profileFunctions` dataset directly as a workaround.
## Gap
Users cannot answer the question: *"Find all transactions where function `X` exceeded `N` ms"* — even though the backend can answer it. This matters for understanding how widespread a performance regression is across an application, rather than just knowing it was slow in one captured profile.
Verified from source (`sentry/profiles/task.py`, EAP `attributes.py`):
- Each function call occurrence is stored as a separate `TraceItem` row with `function`, `function.duration`, `transaction_name`, and `profile_id`.
- Filtering `function = "myFn" AND function.duration > 100ms` is a valid query against the dataset.
- `trace_id` is currently set to `profile_id` as a placeholder, so joining back to the spans/transactions table via trace context is not yet supported.
- Profile function ingestion into EAP is behind an internal feature flag and may not be broadly enabled.
## Options
1. **Add a "Profile Functions" tab to Explore** — backed by the `profileFunctions` EAP dataset, functionally analogous to the existing Spans tab. Users could filter by `function`, `function.duration`, `transaction`, etc. and get a list of matching occurrences with `profile_id` deep-links. No new backend work required; the data model is already in place.
2. **Expose function-level aggregation in the dashboard widget builder** — surface `profileFunctions` as a selectable dataset in dashboards. Lower discovery friction but less flexible than Explore.
3. **Add cross-profile search to the existing Slowest Functions / Suspect Functions views** — augment current widgets to link out to a filtered list rather than individual flamegraphs. Narrower scope but faster to ship.
## Recommendation
Option 1 (Explore tab) is the most composable and directly unblocks the use case without new backend work. It aligns with how Spans exploration already works and sets a foundation for future function-level alerting or dashboarding.
Prerequisite: confirm rollout status of the EAP profile function ingestion flag before committing to a GA timeline.
Action taken on behalf of Prithvi Rajakumar.
Contributor guide
Research direction
Start by reviewing sentry/profiles/task.py and the EAP attributes.py references to confirm the profileFunctions data and its rollout flag. Then compare the proposed Explore tab with the existing Spans tab. Done means a Profile Functions tab can filter function-level occurrences and provide profile_id deep-links, with the ingestion prerequisite confirmed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- data, full-stack
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100