CalculatorCase StudyGuidesWikiChecklistSimulatorAbout
wiki

Wiki &
Checklists.

Everything you need before deploying. Pre-launch checklists, cache strategies, and the 5 golden rules of hosting cost management.

This wiki is based on public pricing and real horror stories. It's a side-project, not legal or financial advice — treat these numbers as educated estimates.

The 5 Golden Rules
1

Cache aggressively

Static content = CDN, not origin. Use Cloudflare free tier in front of everything.

2

Measure requests

>200 requests/session is a red flag. Profile on staging, set budgets, monitor in production.

3

Sample analytics

10-30% sampling is enough for decisions. 100% logging is a luxury only small sites can afford.

4

Billing alerts from day 1

Set alerts at $100, $200, $500. Use a virtual card with spending limits for experiments.

5

Build portably

Vendor lock-in = cost risk. Keep business logic vendor-neutral. Have a migration plan ready.

Pre-Launch Checklist6 categories · Interactive progress tracking
+
0/230% complete

Measurements

0/4

Load Testing

0/3

Billing Safety

0/3

Cache & CDN

0/4

Performance

0/5

Analytics

0/4
Cache Strategy TableRecommended headers for every resource type
+
ResourceCache-ControlNotes
Static JSON/HTMLpublic, max-age=2592000, stale-while-revalidate=8640030 days + 1 day SWR
Archival pagespublic, max-age=604800 to 25920007-30 days; manual busting on changes
Assets (JS/CSS w/ fingerprint)public, max-age=31536000, immutable1 year, immutable
API with dynamic datapublic, max-age=60, stale-while-revalidate=3001 min + 5 min SWR
User data (auth)private, no-cacheNever CDN

Key rule: Cache everything that is static or near-static. Archival data (like emails in jmail) is the perfect candidate — content doesn't change, cache for 30 days.

Provider Decision TreeWhen to switch based on session volume
+
< 100k sessions
Vercel Pro— Convenient, cost is manageable. Good DX, zero ops overhead.
100k – 1M sessions
Calculate & compare— If Vercel > $200/mo, consider CF Workers. Run the numbers before committing.
1M+ sessions
CF Workers or VPS + CDN— Cloudflare Workers or VPS + CDN will be significantly cheaper. Worth the migration effort.
10M+ sessions
Vercel rarely makes sense— At this scale, Vercel costs are 7-10x more than alternatives. Migrate or prepare for large bills.
Emergency PlanImmediate actions when costs spike
+

Immediate Actions (no redeploy)

  • 1Turn off AGGRESSIVE_PRELOAD feature flag — eliminates ~70% of requests
  • 2Enable degraded mode: simpler UI, pagination, no animations/prefetches
  • 3Increase cache TTL via Cloudflare dashboard (e.g. from 1h to 24h)

If Bill Keeps Growing

  • 1Switch DNS to Cloudflare-cached version (proxy mode)
  • 2Disable Vercel Analytics (~36% of jmail's bill)
  • 3Enable rate limiting on edge (Cloudflare rate limiting rules)

Prevention (set up before you need it)

  • 1Attach a virtual card with a hard spending cap ($100–$200) to Vercel billing — the simplest and most effective safeguard
  • 2Enable Vercel Spend Management — set a monthly limit with auto-pause. Available on Pro/Team plans (check your dashboard, features may change)
  • 3Add a kill switch env var (APP_KILL_SWITCH) — check it in your root layout or middleware, return a static maintenance page when set to true
  • 4Set up Cloudflare rate limiting — free plan gives 5 rules. Example: /api/* at 100 req/min/IP, everything else at 300 req/min/IP

For the full layered playbook — virtual cards, Spend Management, Cloudflare setup, kill switches, and more — see the Viral Protection guide.

Architecture by PhaseRecommended stack at each growth stage
+
Phase 1Launch (up to 100k sessions)

Next.js → Vercel Pro + Cloudflare DNS (proxy, free tier) + Supabase + Plausible/Umami

Phase 2Growth (100k – 1M sessions)

Run the cost calculator. Consider CF Workers (OpenNext) or VPS + CDN. Enable analytics sampling.

Phase 3Scale (1M+ sessions)

CF Workers + R2 + D1/Neon, or Hetzner/Railway + aggressive CDN. Vercel only for preview/staging.

Monitoring AlertsThresholds and actions for cost spikes
+
ConditionThresholdAction
Request spike>10× averageAlert + investigate source
p95 latency>2sCheck origin / cache miss rate
Error rate>5%Immediate response
Vercel billing>$200/moEvaluate if worth staying
Vercel billing>$500/moConsider migration to CF Workers
Avoiding Vendor Lock-in5 principles for portable architecture
+
1Keep business logic in a vendor-neutral layer (plain Node/TS)
2Minimize Vercel-only features (SDK, edge middleware) — use only when genuinely needed
3API routes / logic: easy to switch to Workers / Fly / VPS
4Env vars and secrets: single source of truth, easy to migrate
5Have a migration 1-pager ready for every project: server, API, storage, cron, testing

“Build on tech that can be moved absolutely anywhere.” — Wes Bos

<Link> vs <a>When each is the right choice
+

Next.js logs a warning when you use <a> instead of <Link> for internal routes — and it's right. But the opposite problem is never flagged: wrapping external URLs in <Link> when a plain <a> is better.

With prefetch={true} (the default!), Next.js tries to prefetch the destination route — for an external URL, that's a wasted cross-origin request. Even with prefetch={false}, <Link> wraps navigation in the router, intercepts the click, and parses the URL — unnecessary work for a link that opens a new tab anyway.

ScenarioUseWhy
Internal navigation (SPA routing)<Link prefetch={false}>Client-side routing, preserves React state, no full page reload.
External link (https://...)<a target="_blank" rel="noopener noreferrer"><Link> adds router overhead with zero benefit — the browser opens a new tab anyway.
Anchor on the same page (#id)<a href="#id">No router needed — pure scroll behavior.
Download / mailto / tel<a>Not routes — the browser handles these natively.

HostCost approach: <Link prefetch={false}> for internal routes, plain <a> for external links. Every link type chosen deliberately.

DogfoodingHow this site applies its own principles
+

This site applies every principle it teaches. Here's how:

Cache aggressively — 100% static export (SSG). Every page is a plain HTML file, ready for CDN caching with immutable fingerprinted assets.
Prefetch on intent only — Internal routes use <Link prefetch={false}> — no viewport prefetching. External links use plain <a> tags — zero router overhead, zero prefetch leaks. Every link type chosen deliberately.
Lazy-load heavy dependencies — Recharts (~150KB) is loaded via next/dynamic only on pages with charts. The /wiki page loads zero chart JavaScript.
No vendor lock-in — All calculation logic lives in pure TypeScript (lib/). Zero Vercel SDK. Static export means deploy anywhere.
No analytics overhead — Zero analytics scripts. No tracking, no double-dipping, no extra edge requests eating into your budget.
Lightweight first load — No SSR, no API routes, no server runtime. Static HTML + CSS with lazy-loaded JS. The lightest a Next.js app can be.