Skip to content

feat: snapshot + carry-forward for /perps and /hyperliquid cohorts - #689

Merged
Flotapponnier merged 1 commit into
devfrom
feat/cohort-materialize-perp-hl
Jun 24, 2026
Merged

feat: snapshot + carry-forward for /perps and /hyperliquid cohorts#689
Flotapponnier merged 1 commit into
devfrom
feat/cohort-materialize-perp-hl

Conversation

@Flotapponnier

Copy link
Copy Markdown
Collaborator

Summary

  • New src/lib/cohort-snapshot.ts (Upstash REST, single {data, asOf} envelope per key, 24 h TTL safety net, 10 min default staleness ceiling). Mirrors src/lib/materialize/store.ts without the pointer indirection since cohort aggregates are a single blob.
  • fetchPerpCohort, fetchHlCohort, fetchHlHip3Cohort now read Upstash first, fall through to live Prom + writeback on miss/stale, and are wrapped in unstable_cache (60 s) for concurrent-request collapsing. The uncached Prom path is exported as *Fresh for the cron.
  • Two new Vercel crons (every minute): /api/cron/snapshot-perp-cohort (key perp-cohort) and /api/cron/snapshot-hl-cohort (keys hl-frontends + hl-hip3, refreshed in parallel with per-key error isolation). Both gated by the existing CRON_SECRET Bearer header, structure mirrors health-check / indexnow.
  • vercel.json gains the two cron entries.

Why

Both hub pages currently fetch live from Prom on render. A single Prom hiccup (Railway redeploy, scrape miss, harness restart) parks a null cohort in Vercel ISR and the user sees "..." everywhere until the next refresh. With the snapshot layer, the worst case becomes a 5 min stale badge during a harness blip instead of an empty leaderboard.

Reused infra (no new env vars)

  • CRON_SECRET (already on Vercel, gates health-check / indexnow)
  • KV_REST_API_URL + KV_REST_API_TOKEN (already used by src/lib/snapshot.ts per-bench snapshots; falls back to UPSTASH_REDIS_REST_URL / UPSTASH_REDIS_REST_TOKEN to match the materialize layer)

Shape check

The snapshot envelope wraps PerpCohortSummary | HlCohortSummary | HlHip3Summary verbatim; the reader returns envelope.data of the same type, no field drift.

Test plan

  • After merge to dev, confirm Vercel registers the two new crons (vercel.com/.../settings/cron-jobs)
  • Hit /api/cron/snapshot-perp-cohort manually with the CRON_SECRET to seed the blob, then verify /perps renders cohort cards
  • Same for /api/cron/snapshot-hl-cohort and /hyperliquid
  • Simulate Prom outage (point PROMETHEUS_URL at a dead host on a preview) and confirm both hubs keep serving the last good snapshot until the 10 min staleness window

Adds an Upstash-backed cohort snapshot layer so the two hub pages serve
last-known-good data even when Prom blips. A Vercel cron writes a fresh
JSON snapshot every minute; the readers (fetchPerpCohort, fetchHlCohort,
fetchHlHip3Cohort) prefer the snapshot, fall through to live Prom on
stale or missing blobs, and write back on success.
@Flotapponnier
Flotapponnier merged commit f54c62c into devJun 24, 2026
1 check passed
@Flotapponnier
Flotapponnier deleted the feat/cohort-materialize-perp-hl branch July 17, 2026 14:42
Sign up for freeto 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

@Flotapponnier