diff --git a/static/app/views/explore/utils.tsx b/static/app/views/explore/utils.tsx
index 1f97455b80f293..1e74bb8a849fa7 100644
--- a/static/app/views/explore/utils.tsx
+++ b/static/app/views/explore/utils.tsx
@@ -65,6 +65,7 @@ export function getExploreUrl({
sort,
field,
id,
+ table,
title,
referrer,
}: {
@@ -79,6 +80,7 @@ export function getExploreUrl({
referrer?: string;
selection?: PageFilters;
sort?: string;
+ table?: string;
title?: string;
visualize?: BaseVisualize[];
}) {
@@ -100,6 +102,7 @@ export function getExploreUrl({
field,
utc,
id,
+ table,
title,
referrer,
};
diff --git a/static/app/views/performance/newTraceDetails/index.tsx b/static/app/views/performance/newTraceDetails/index.tsx
index 4bf58637ebd592..5e6307c1444465 100644
--- a/static/app/views/performance/newTraceDetails/index.tsx
+++ b/static/app/views/performance/newTraceDetails/index.tsx
@@ -22,6 +22,7 @@ import {
} from 'sentry/views/performance/newTraceDetails/traceOurlogs';
import {TraceSummarySection} from 'sentry/views/performance/newTraceDetails/traceSummary';
import {TraceTabsAndVitals} from 'sentry/views/performance/newTraceDetails/traceTabsAndVitals';
+import {PartialTraceDataWarning} from 'sentry/views/performance/newTraceDetails/traceTypeWarnings/partialTraceDataWarning';
import {TraceWaterfall} from 'sentry/views/performance/newTraceDetails/traceWaterfall';
import {
TraceLayoutTabKeys,
@@ -165,6 +166,11 @@ function TraceViewImpl({traceSlug}: {traceSlug: string}) {
traceSlug={traceSlug}
organization={organization}
/>
+
{
+ describe('when the trace is older than 30 days', () => {
+ beforeAll(() => {
+ jest.useFakeTimers().setSystemTime(new Date(2025, 0, 31));
+ });
+
+ afterAll(() => {
+ jest.useRealTimers();
+ });
+
+ it('should render warning', () => {
+ const organization = OrganizationFixture();
+ const start = new Date('2024-01-01T00:00:00Z').getTime() / 1e3;
+
+ const eapTrace = makeEAPTrace([
+ makeEAPSpan({
+ op: 'http.server',
+ start_timestamp: start,
+ end_timestamp: start + 2,
+ children: [makeEAPSpan({start_timestamp: start + 1, end_timestamp: start + 4})],
+ }),
+ ]);
+
+ render(
+ ,
+ {organization}
+ );
+
+ expect(screen.getByText('Partial Trace Data:')).toBeInTheDocument();
+
+ expect(
+ screen.getByText(
+ 'Trace may be missing spans since the age of the trace is older than 30 days'
+ )
+ ).toBeInTheDocument();
+
+ expect(
+ screen.getByRole('link', {name: 'Search similar traces in the past 24 hours'})
+ ).toBeInTheDocument();
+
+ const queryString = encodeURIComponent('is_transaction:true span.op:http.server');
+ expect(
+ screen.getByRole('link', {name: 'Search similar traces in the past 24 hours'})
+ ).toHaveAttribute(
+ 'href',
+ `/organizations/${organization.slug}/explore/traces/?mode=samples&project=1&query=${queryString}&statsPeriod=24h&table=trace`
+ );
+ });
+ });
+
+ describe('when the trace is younger than 30 days', () => {
+ beforeAll(() => {
+ jest.useFakeTimers().setSystemTime(new Date(2025, 0, 1));
+ });
+
+ afterAll(() => {
+ jest.useRealTimers();
+ });
+
+ it('should not render the warning', () => {
+ const organization = OrganizationFixture();
+ const start = new Date('2025-01-01T00:00:00Z').getTime() / 1e3;
+
+ const eapTrace = makeEAPTrace([
+ makeEAPSpan({
+ op: 'http.server',
+ start_timestamp: start,
+ end_timestamp: start + 2,
+ children: [makeEAPSpan({start_timestamp: start + 1, end_timestamp: start + 4})],
+ }),
+ ]);
+
+ render(
+ ,
+ {organization}
+ );
+
+ expect(screen.queryByText('Partial Trace Data:')).not.toBeInTheDocument();
+
+ expect(
+ screen.queryByText(
+ 'Trace may be missing spans since the age of the trace is older than 30 days'
+ )
+ ).not.toBeInTheDocument();
+
+ expect(
+ screen.queryByRole('link', {name: 'Search similar traces in the past 24 hours'})
+ ).not.toBeInTheDocument();
+ });
+ });
+});
diff --git a/static/app/views/performance/newTraceDetails/traceTypeWarnings/partialTraceDataWarning.tsx b/static/app/views/performance/newTraceDetails/traceTypeWarnings/partialTraceDataWarning.tsx
new file mode 100644
index 00000000000000..72fdf03e1a86f3
--- /dev/null
+++ b/static/app/views/performance/newTraceDetails/traceTypeWarnings/partialTraceDataWarning.tsx
@@ -0,0 +1,103 @@
+import {useMemo} from 'react';
+import moment from 'moment-timezone';
+
+import {Alert} from '@sentry/scraps/alert';
+import {Link} from '@sentry/scraps/link';
+import {Text} from '@sentry/scraps/text';
+
+import {t, tct} from 'sentry/locale';
+import {MutableSearch} from 'sentry/utils/tokenizeSearch';
+import useOrganization from 'sentry/utils/useOrganization';
+import usePageFilters from 'sentry/utils/usePageFilters';
+import {Mode} from 'sentry/views/explore/contexts/pageParamsContext/mode';
+import type {OurLogsResponseItem} from 'sentry/views/explore/logs/types';
+import {getExploreUrl} from 'sentry/views/explore/utils';
+import {getRepresentativeTraceEvent} from 'sentry/views/performance/newTraceDetails/traceApi/utils';
+import type {TraceTree} from 'sentry/views/performance/newTraceDetails/traceModels/traceTree';
+
+interface PartialTraceDataWarningProps {
+ logs: OurLogsResponseItem[] | undefined;
+ timestamp: number | undefined;
+ tree: TraceTree;
+}
+
+export function PartialTraceDataWarning({
+ logs,
+ timestamp,
+ tree,
+}: PartialTraceDataWarningProps) {
+ const organization = useOrganization();
+ const {selection} = usePageFilters();
+
+ const rep = getRepresentativeTraceEvent(tree, logs);
+
+ let op = '';
+ if (rep?.event) {
+ op =
+ 'transaction.op' in rep.event
+ ? `${rep.event?.['transaction.op']}`
+ : 'op' in rep.event
+ ? `${rep.event.op}`
+ : '';
+ }
+
+ const queryString = useMemo(() => {
+ const search = new MutableSearch('');
+ search.addFilterValue('is_transaction', 'true');
+
+ if (op) {
+ search.addFilterValue('span.op', op);
+ }
+
+ return search.formatString();
+ }, [op]);
+
+ if (!timestamp) {
+ return null;
+ }
+
+ const now = moment();
+ const isTraceTooYoung = moment(timestamp * 1000).isAfter(now.subtract(30, 'days'));
+
+ if (isTraceTooYoung) {
+ return null;
+ }
+
+ const projects =
+ typeof rep.event?.project_id === 'number' ? [rep.event?.project_id] : [];
+
+ const exploreUrl = getExploreUrl({
+ organization,
+ mode: Mode.SAMPLES,
+ query: queryString,
+ table: 'trace',
+ selection: {
+ ...selection,
+ projects,
+ datetime: {
+ start: null,
+ end: null,
+ utc: null,
+ period: '24h',
+ },
+ },
+ });
+
+ return (
+ {t('Search similar traces in the past 24 hours')}
+ }
+ >
+
+ {tct(
+ '[dataCategory] Trace may be missing spans since the age of the trace is older than 30 days',
+ {
+ dataCategory: {t('Partial Trace Data:')},
+ }
+ )}
+
+
+ );
+}