Skip to content

perf(api): faster iOS service detail, widgets and per-request auth - #1088

Merged
Makisuo merged 2 commits into
mainfrom
perf/ios-overview-rollups
Sep 26, 2026
Merged

Makisuo merged 2 commits into
mainfrom
perf/ios-overview-rollups

Conversation

@Makisuo

@Makisuo Makisuo commented Sep 26, 2026 •

Copy link
Copy Markdown
Collaborator

Why

The iOS service detail screen sometimes took 20s+ to load. Traces show every GET /v2/services/:name/overview in the last week took 18-30s (median 23.6s), and nearly all of it was one warehouse read: the all-metrics timeseries.

That read never set rootSpansOnly, and canUseAnnualServiceOverview requires rootOnly === true to route to the service_overview_minutely / service_overview_hourly rollups. So it fell through to a raw traces scan of every span of the service, with quantiles. For ingest over 24h that is 23.6s. The summary and operations reads in the same request finish in under 1s.

/v2/widget_summary (the Home Screen widgets, ~1k calls/week, server p50 2.2s, p95 5.3s) had the same gap in its sparkline series, plus its three reads ran serially.

What changed

  • Service overview: the timeseries filters now pass rootSpansOnly: true. The read routes to the minutely rollup plus the raw edge on service_overview_spans. This also fixes a population mismatch: the chart counted every span while the summary above it counts entry spans. The web service page already reads entry spans (custom-charts.ts).
  • Widget summary: the series read entry spans too (the population throughput_per_second counts), with whole-second bounds like the catalog. Issues, catalog and both series now run concurrently.
  • Region check (OrganizationRegionService): ensureServedHere re-read Clerk every 5s for any org without a chosen region, which includes every org that predates regions. That was a Clerk call on ~74% of API requests (p50 163ms, p95 588ms) before the handler ran. The 5s TTL now applies only while an org can still choose its region (organizationRegionOpen: unchosen and inside the 7-day REGION_CHOICE_WINDOW_MS, the same rule OrganizationService enforces when the choice is written). Everything else caches for the existing 60s.
  • Regression tests assert both endpoints send rootSpansOnly: true to the query engine.

Verification

  • Compiled both queries: they now read FROM service_overview_spans, service_overview_minutely instead of FROM traces.
  • Ran the new overview SQL against production for the exact request that took 23.6s. It returned well inside the time limit with sane values (~300k entry spans per 30m bucket, p95 ~245ms).
  • vitest on telemetry.http.test.ts and widget-summary.http.test.ts: 21 passed. apps/api and packages/backend typecheck clean (the test-config typecheck has pre-existing stub errors in telemetry.http.test.ts, none in the new lines).

Reviewer notes

  • Server-only fix; no app release needed.
  • Behaviour change: overview chart counts and latency percentiles now describe entry spans, so values will drop for services with many internal/client spans. That matches the headline numbers and the web app.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Summary by CodeRabbit

  • Bug Fixes
    • Service overview and widget summary metrics now consistently reflect the selected deployment environment and focus on top-level spans.
    • Widget summary time ranges are now aligned to whole-second precision, improving consistency across displayed results.

The v2 service overview and widget summary timeseries never set
rootSpansOnly, so they skipped the service_overview minutely/hourly
rollups and scanned every raw span of the service or org. The phone's
service detail screen waited 18-30s on that read for a busy service.

Both now read entry spans (the same population as their summary numbers)
and route to the rollups. The widget summary also runs its issues,
catalog and series reads concurrently instead of one after another.
@maple-review-bot

maple-review-bot Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Note

A newer push replaced 5712236 before its review finished. The latest commit is reviewed in a new comment.

@coderabbitai

coderabbitai Bot commented Sep 26, 2026

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: b8acfba5-daff-40b9-8933-1a40d79c9022

📥 Commits

Reviewing files that changed from the base of the PR and between c8a7d96 and 5712236.

📒 Files selected for processing (4)
  • apps/api/src/routes/v2/telemetry.http.test.ts
  • apps/api/src/routes/v2/telemetry.http.ts
  • apps/api/src/routes/v2/widget-summary.http.test.ts
  • apps/api/src/routes/v2/widget-summary.http.ts
 ____________________________________________________________________________________________________________________________________________________
< There are no final decisions. No decision is cast in stone. Instead, consider each as being written in the sand at the beach, and plan for change. >
 ----------------------------------------------------------------------------------------------------------------------------------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

ensureServedHere re-read Clerk every 5s for any org without a chosen
region, which is every org that predates regions. In practice that was a
Clerk call on ~74% of API requests (p50 163ms, p95 588ms) ahead of the
handler.

The 5s TTL only protects an org that can still choose EU. The choice is
refused once an org is past REGION_CHOICE_WINDOW_MS, so key the short TTL
on organizationRegionOpen (unchosen and inside the window) instead of
"unchosen".
@Makisuo Makisuo changed the title perf(api): read iOS service overview and widget series from the rollups perf(api): faster iOS service detail, widgets and per-request auth Sep 26, 2026
@maple-review-bot

Copy link
Copy Markdown

Note

Maple is reviewing this pull request at 05d2d12. This comment updates with the review when it finishes.

@Makisuo
Makisuo merged commit b999891 into main Sep 26, 2026
36 of 37 checks passed
@Makisuo
Makisuo deleted the perf/ios-overview-rollups branch September 26, 2026 23:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant