SaaS Analytics Dashboard
Rebuilt a legacy analytics dashboard for a B2B SaaS product, cutting P95 load time from 11 s to 380 ms for 50 k+ daily active users.
Overview
The client had a growing B2B SaaS product where the analytics page had become unusable at scale. What once loaded in 2 seconds now took 11–15 seconds — and support tickets about it were piling up.
I was brought in to diagnose and rebuild the analytics layer without touching the core product database schema.
The Problem
The original implementation ran ad-hoc aggregate queries directly against the production transactional database. At low user counts this was fine. At 50 k daily active users, it created lock contention and occasionally brought down the whole app.
Key constraints going in:
- Could not modify the core product schema
- Had to support arbitrary date ranges up to 2 years of history
- Infrastructure budget was limited — no managed data warehouse
Solution
I built a separate analytics pipeline alongside the existing product:
Pre-aggregation layer — A nightly job (Cloudflare Workers Cron) reads from the production DB in read-only mode and writes summarised rows into a separate schema. The queries against this schema are cheap and predictable.
Redis caching — Common dashboard views (last 7 days, last 30 days) are cached with Upstash Redis. Invalidation fires when the nightly job completes.
Edge delivery — The API endpoint moves to a Cloudflare Worker, so responses are served from the nearest PoP with cache hits returning in single-digit milliseconds.
Stack
| Layer | Tech |
|---|---|
| Frontend | React + TanStack Query |
| API | Cloudflare Workers |
| Cache | Upstash Redis |
| Analytics DB | Cloudflare D1 (SQLite at the edge) |
| Charts | Recharts |
Results
- P95 load time: 11 s → 380 ms
- Server costs: down 40 % (edge compute vs. always-on server)
- Churn: client reported a measurable drop in the month after launch
- Zero schema changes to the production database