Skip to content

Latest commit

 

History

History
50 lines (38 loc) · 3.22 KB

File metadata and controls

50 lines (38 loc) · 3.22 KB

v1.7.3 - Performance Tune-Up: Sentry Sampling, ISR & Query Dedup

Released: June 11, 2026

Summary

Config-level performance pass from the 2026-06-11 audit (devnotes/audits/2026-06-11.md): cut Sentry trace/telemetry overhead, restored ISR on /talks, protected the spread-reading route from Vercel's 10s timeout, and deduplicated detail-page database queries. Zero functionality changes.


Features

  • Sentry sampling reduced — client traces 100% → 10%, server/edge 100% → 20%. Errors are still always captured; session replay stays at 10% sampling + 100% on errors.
  • Sentry tunnelRoute removed — browser telemetry now goes directly to sentry.io instead of routing through /monitoring on our own Vercel functions (saves one function invocation per event).
  • /talks back on ISR — removed force-dynamic that was cancelling revalidate = 3600; the listing now serves from CDN cache like /cards and /themes. Admin edits still bust the cache via existing revalidatePath('/talks') calls.
  • Spread-reading timeout protection — added maxDuration = 60 to the one heavy route that lacked it (4 sequential Gemini/YouTube calls vs the 10s Hobby default).
  • Detail-query dedupgetCardWithMappings and getTalkWithMappedCards wrapped in React cache(), halving DB roundtrips per card/talk detail render (generateMetadata + page were each running the same queries).

Files Changed

New Files

  • devnotes/audits/2026-06-11.md - Performance audit report (P1-P10 ranked findings; P5-P10 remain open)

Modified Files

  • instrumentation-client.ts - tracesSampleRate 1 → 0.1
  • sentry.server.config.ts - tracesSampleRate 1 → 0.2
  • sentry.edge.config.ts - tracesSampleRate 1 → 0.2
  • next.config.ts - removed tunnelRoute: "/monitoring"
  • app/talks/page.tsx - removed export const dynamic = 'force-dynamic'
  • app/api/spreads/spread-reading/route.ts - added export const maxDuration = 60
  • lib/db/queries/cards.ts - getCardWithMappings wrapped in React cache()
  • lib/db/queries/talks.ts - getTalkWithMappedCards wrapped in React cache()

Testing Checklist (Eval Bar)

  • Vercel build succeeded, including the /talks prerender step (deploy confirmed)
  • curl -sI https://tarottalks.app/talks twice — second response shows x-vercel-cache: HIT
  • No /monitoring references in page payload; devtools shows Sentry events going to *.ingest.us.sentry.io directly
  • Hit https://tarottalks.app/api/sentry-example-api — error appears in Sentry dashboard (capture survived sampling change)
  • Vercel dashboard → Functions: api/spreads/spread-reading shows 60s max duration
  • Complete a live 3-card spread reading on https://tarottalks.app — full reading, no timeout
  • Card + talk detail pages unchanged: correct <title>, og:image meta, mappings render
  • /api/admin/health OK; admin-diagnostics script all green
  • Within 24–48h: Sentry tracing ingest volume drops ~80–90%; /monitoring invocations go to zero

Rollback Notes

  • If /talks ever fails at build-time prerender (the original reason for force-dynamic), re-add export const dynamic = 'force-dynamic'; to app/talks/page.tsx and redeploy. All other changes stand alone.