fix(admin): stop blocking dashboard tiles on PostHog insight recomputes
Problem
Every insight tile fetched its saved insight with refresh=blocking, which holds the HTTP request open while PostHog recomputes the insight. Timed against the real project on a cold cache:
| insight | cold |
|---|---|
| activeOrgs | 20.3s |
| activatedRate | 15.2s |
| newSiteVisitors | 9.4s |
| the other seven | 0.3–1.0s |
Past PostHog's ~15min refresh throttle, loading the Product tab meant a 20s blocking request.
Fix
refresh=blocking → refresh=lazy_async. PostHog serves its cached result immediately and kicks off the recompute in the background. A genuinely cold insight returns no result yet, so fetchInsightResults reports pending and the tile polls until it lands — the same idiom getMrr already uses for Stripe Sigma.
The staleTime + pending-poll wiring is now one useInsightResults hook rather than the identical query block repeated in all four insight tiles.
Measurement
Against the local API with all five Product-tab insights forced to recompute, transport unchanged in both runs:
before (refresh=blocking) — total 18.0s
+ 4.55s WAU
+ 4.83s DAU
+ 4.95s workspacesPerCreator
+ 9.01s activatedRate
+18.05s activeOrgs
after (refresh=lazy_async) — total 0.85s
all five tiles landed between +0.80s and +0.85s
Notes
- Tiles now paint last-known numbers first and update when the recompute lands. The tile header already shows
lastRefresh, so staleness stays visible. - I also checked whether the tRPC batch link was coupling tiles together. It isn't —
httpBatchStreamLinkstreams each result as it resolves (visible in the before-run above, where the fast tiles landed at ~4.5s while activeOrgs was still running). No transport change needed. - Two adjacent things left alone:
getEnterpriseArrfetches Stripe subscriptions serially in a loop, and the business tiles have nostaleTimeso they re-run Mercury/Stripe/cohort queries on window refocus.
Summary by cubic
Stops blocking admin dashboard tiles on PostHog recomputes. Old behavior held requests with refresh=blocking; new behavior uses refresh=lazy_async to return cached results immediately and poll during recompute, keeping stale charts visible.
- Adds
useInsightResults(insight)withstaleTime=10m; polls every 3s whilepending. fetchInsightResultsnow usesrefresh=lazy_async; setspendingwhen noresultorquery_statusis incomplete; throws onquery_status.errorso tiles show an error instead of polling forever.- Tiles (
HogQLLineTile,TrendSeriesTile,RetentionGridTile,PostHogFunnelTile) adopt the hook; show a skeleton only when no result exists; stale numbers stay rendered and update when recompute lands;lastRefreshremains visible. - Product tab cold recomputes improve from ~18s to ~0.85s for the last tile to land.
Summary by CodeRabbit
-
New Features
- Analytics insight tiles now share consistent result loading and refresh behavior.
- Results automatically update while insights are being recalculated, with refreshes continuing until current data is available.
- Insight results are reused briefly to improve responsiveness and reduce unnecessary reloads.
-
Bug Fixes
- Tiles no longer appear complete while results are still pending.
- Stale results are clearly treated as pending during background recomputation, preventing misleading displays.