From cde833edfb84bd1ff7de70a79609bed3e6db37cd Mon Sep 17 00:00:00 2001 From: Dan Fuller Date: Fri, 10 Apr 2026 15:28:34 -0700 Subject: [PATCH] ref(flags): Remove frontend checks for `minute-resolution-sessions` feature flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This feature flag has `default=True` and is always on for all users. Remove all frontend feature checks and the `highFidelity` parameter from `getSessionsInterval` — sub-hour resolution is now always used for recent data, matching existing behavior for all users. A follow-up backend PR will remove the feature registration from `temporary.py` once this is deployed. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../app/components/charts/sessionsRequest.tsx | 6 +- .../components/charts/useSessionsRequest.tsx | 5 +- static/app/utils/sessions.spec.tsx | 104 +++++++----------- static/app/utils/sessions.tsx | 33 +++--- .../charts/projectSessionsAnrRequest.tsx | 1 - .../charts/projectSessionsChartRequest.tsx | 6 +- .../releases/list/releasesAdoptionChart.tsx | 10 +- 7 files changed, 59 insertions(+), 106 deletions(-) diff --git a/static/app/components/charts/sessionsRequest.tsx b/static/app/components/charts/sessionsRequest.tsx index 7a55ec21659257..63bd2513b71664 100644 --- a/static/app/components/charts/sessionsRequest.tsx +++ b/static/app/components/charts/sessionsRequest.tsx @@ -82,7 +82,6 @@ export class SessionsRequest extends Component { query, groupBy, interval, - organization, } = this.props; return { @@ -96,10 +95,7 @@ export class SessionsRequest extends Component { end, interval: interval ? interval - : getSessionsInterval( - {start, end, period: statsPeriod}, - {highFidelity: organization.features.includes('minute-resolution-sessions')} - ), + : getSessionsInterval({start, end, period: statsPeriod}), }; } diff --git a/static/app/components/charts/useSessionsRequest.tsx b/static/app/components/charts/useSessionsRequest.tsx index 675883ebd86c1d..9eb1cf4a1c1b33 100644 --- a/static/app/components/charts/useSessionsRequest.tsx +++ b/static/app/components/charts/useSessionsRequest.tsx @@ -45,10 +45,7 @@ export function useSessionsRequest({ end, interval: interval ? interval - : getSessionsInterval( - {start, end, period: statsPeriod}, - {highFidelity: organization.features.includes('minute-resolution-sessions')} - ), + : getSessionsInterval({start, end, period: statsPeriod}), }; const sessionQuery = useApiQuery( diff --git a/static/app/utils/sessions.spec.tsx b/static/app/utils/sessions.spec.tsx index 8dec09c5dbe665..e9feb23233611f 100644 --- a/static/app/utils/sessions.spec.tsx +++ b/static/app/utils/sessions.spec.tsx @@ -192,80 +192,52 @@ describe('utils/sessions', () => { }); describe('getSessionsInterval', () => { - describe('with high fidelity', () => { - it('>= 60 days', () => { - expect(getSessionsInterval({period: '60d'}, {highFidelity: true})).toBe('1d'); - }); - - it('>= 30 days', () => { - expect(getSessionsInterval({period: '30d'}, {highFidelity: true})).toBe('4h'); - }); - - it('14 days', () => { - expect(getSessionsInterval({period: '14d'}, {highFidelity: true})).toBe('1h'); - }); - - it('>= 6 hours', () => { - expect(getSessionsInterval({period: '6h'}, {highFidelity: true})).toBe('1h'); - }); - - it('between 6 hours and 30 minutes', () => { - expect(getSessionsInterval({period: '31m'}, {highFidelity: true})).toBe('5m'); - }); - - it('less or equal to 30 minutes', () => { - expect(getSessionsInterval({period: '30m'}, {highFidelity: true})).toBe('1m'); - }); - - it('less or equal to 10 minutes', () => { - expect( - getSessionsInterval( - {start: '2021-10-08T12:00:00Z', end: '2021-10-08T12:05:00.000Z'}, - {highFidelity: true} - ) - ).toBe('10s'); - }); + it('>= 60 days', () => { + expect(getSessionsInterval({period: '60d'})).toBe('1d'); + expect( + getSessionsInterval({ + start: '2021-07-19T15:14:23Z', + end: '2021-10-19T15:14:23Z', + }) + ).toBe('1d'); + }); - it('ignores high fidelity flag if start is older than 30d', () => { - expect( - getSessionsInterval( - {start: '2017-09-15T02:41:20Z', end: '2017-09-15T02:42:20Z'}, - {highFidelity: true} - ) - ).toBe('1h'); - }); + it('>= 30 days', () => { + expect(getSessionsInterval({period: '30d'})).toBe('4h'); }); - describe('with low fidelity', () => { - it('>= 60 days', () => { - expect(getSessionsInterval({period: '60d'})).toBe('1d'); - expect( - getSessionsInterval( - {start: '2021-07-19T15:14:23Z', end: '2021-10-19T15:14:23Z'}, - {highFidelity: true} - ) - ).toBe('1d'); - }); + it('14 days', () => { + expect(getSessionsInterval({period: '14d'})).toBe('1h'); + }); - it('>= 30 days', () => { - expect(getSessionsInterval({period: '30d'})).toBe('4h'); - }); + it('>= 6 hours', () => { + expect(getSessionsInterval({period: '6h'})).toBe('1h'); + }); - it('14 days', () => { - expect(getSessionsInterval({period: '14d'})).toBe('1h'); - }); + it('between 6 hours and 30 minutes', () => { + expect(getSessionsInterval({period: '31m'})).toBe('5m'); + }); - it('>= 6 hours', () => { - expect(getSessionsInterval({period: '6h'})).toBe('1h'); - }); + it('less or equal to 30 minutes', () => { + expect(getSessionsInterval({period: '30m'})).toBe('1m'); + }); - it('between 6 hours and 30 minutes', () => { - expect(getSessionsInterval({period: '31m'})).toBe('1h'); - }); + it('less or equal to 10 minutes', () => { + expect( + getSessionsInterval({ + start: '2021-10-08T12:00:00Z', + end: '2021-10-08T12:05:00.000Z', + }) + ).toBe('10s'); + }); - it('less or equal to 30 minutes', () => { - expect(getSessionsInterval({period: '30m'})).toBe('1h'); - }); + it('falls back to 1h if start is older than 30d', () => { + expect( + getSessionsInterval({ + start: '2017-09-15T02:41:20Z', + end: '2017-09-15T02:42:20Z', + }) + ).toBe('1h'); }); }); diff --git a/static/app/utils/sessions.tsx b/static/app/utils/sessions.tsx index 3e3ebdfd0e1c68..af703f0a02818c 100644 --- a/static/app/utils/sessions.tsx +++ b/static/app/utils/sessions.tsx @@ -257,20 +257,14 @@ export function initSessionsChart(theme: Theme) { type GetSessionsIntervalOptions = { dailyInterval?: boolean; - highFidelity?: boolean; }; export function getSessionsInterval( datetimeObj: DateTimeObject, - {highFidelity, dailyInterval}: GetSessionsIntervalOptions = {} + {dailyInterval}: GetSessionsIntervalOptions = {} ) { const diffInMinutes = getDiffInMinutes(datetimeObj); - if (moment(datetimeObj.start).isSameOrBefore(moment().subtract(30, 'days'))) { - // we cannot use sub-hour session resolution on buckets older than 30 days - highFidelity = false; - } - if (dailyInterval === true && diffInMinutes > TWENTY_FOUR_HOURS) { return '1d'; } @@ -287,22 +281,23 @@ export function getSessionsInterval( return '1h'; } - // limit on backend for sub-hour session resolution is set to six hours - if (highFidelity) { - if (diffInMinutes <= MINUTES_THRESHOLD_TO_DISPLAY_SECONDS) { - // This only works for metrics-based session stats. - // Backend will silently replace with '1m' for session-based stats. - return '10s'; - } + // we cannot use sub-hour session resolution on buckets older than 30 days + if (moment(datetimeObj.start).isSameOrBefore(moment().subtract(30, 'days'))) { + return '1h'; + } - if (diffInMinutes <= 30) { - return '1m'; - } + // limit on backend for sub-hour session resolution is set to six hours + if (diffInMinutes <= MINUTES_THRESHOLD_TO_DISPLAY_SECONDS) { + // This only works for metrics-based session stats. + // Backend will silently replace with '1m' for session-based stats. + return '10s'; + } - return '5m'; + if (diffInMinutes <= 30) { + return '1m'; } - return '1h'; + return '5m'; } // Sessions API can only round intervals to the closest hour - this is especially problematic when using sub-hour resolution. diff --git a/static/app/views/projectDetail/charts/projectSessionsAnrRequest.tsx b/static/app/views/projectDetail/charts/projectSessionsAnrRequest.tsx index d8455a8953d2d2..f2f54ffdc5893b 100644 --- a/static/app/views/projectDetail/charts/projectSessionsAnrRequest.tsx +++ b/static/app/views/projectDetail/charts/projectSessionsAnrRequest.tsx @@ -54,7 +54,6 @@ export function ProjectSessionsAnrRequest({ const baseParams = { field: [yAxis, 'count_unique(user)'], interval: getSessionsInterval(datetime, { - highFidelity: organization.features.includes('minute-resolution-sessions'), dailyInterval: true, }), project: projects[0], diff --git a/static/app/views/projectDetail/charts/projectSessionsChartRequest.tsx b/static/app/views/projectDetail/charts/projectSessionsChartRequest.tsx index 1ac90116df7e6d..59afa964edfe95 100644 --- a/static/app/views/projectDetail/charts/projectSessionsChartRequest.tsx +++ b/static/app/views/projectDetail/charts/projectSessionsChartRequest.tsx @@ -200,15 +200,13 @@ class ProjectSessionsChartRequest extends Component< } queryParams({shouldFetchWithPrevious = false}): Record { - const {selection, query, organization} = this.props; + const {selection, query} = this.props; const {datetime, projects, environments: environment} = selection; const baseParams = { field: this.field, groupBy: this.isCrashFreeRate ? undefined : 'session.status', - interval: getSessionsInterval(datetime, { - highFidelity: organization.features.includes('minute-resolution-sessions'), - }), + interval: getSessionsInterval(datetime), project: projects[0], environment, query, diff --git a/static/app/views/releases/list/releasesAdoptionChart.tsx b/static/app/views/releases/list/releasesAdoptionChart.tsx index 8802e978db757d..e2593a9c13eb96 100644 --- a/static/app/views/releases/list/releasesAdoptionChart.tsx +++ b/static/app/views/releases/list/releasesAdoptionChart.tsx @@ -75,12 +75,8 @@ export function ReleasesAdoptionChart({ const diffInMinutes = getDiffInMinutes(datetimeObj); - // use high fidelity intervals when available - // limit on backend is set to six hour - if ( - organization.features.includes('minute-resolution-sessions') && - diffInMinutes < 360 - ) { + // limit on backend is set to six hours + if (diffInMinutes < 360) { return '10m'; } @@ -88,7 +84,7 @@ export function ReleasesAdoptionChart({ return '1d'; } return '1h'; - }, [organization, location]); + }, [location]); const getReleasesSeries = (response: SessionApiResponse | null) => { // If there are many releases, display releases with the highest number of sessions