LLMSkillHub
mirroredCopied from nirholas/cryptocurrency.cv under MIT. nirholas has not claimed this page, and is not affiliated with LLM SkillHub.

nirholas / scale-to-1m

Step-by-step prompts to prepare free-crypto-news for 1M+ concurrent users. Covers database, job queues, WebSocket scaling, CDN caching, observability, load testing, DDoS protection, graceful degradation, API gateway, multi-region deployment, and disaster recovery.

0
SKILL.md
9.6 KB

Scale to 1M+ Users — Prompt Playbook

Goal: Transform free-crypto-news from a single-instance Vercel app into a horizontally-scaled, multi-region platform capable of serving 1M+ concurrent users — surpassing CoinGecko and DeFiLlama.

Current State (Feb 2026)

  • ~82% Edge Runtime routes on Vercel (226/351 API routes)
  • Redis (Upstash) for distributed caching + rate limiting
  • Nginx load balancer with 2+ app replicas in Docker
  • WebSocket server with Redis pub/sub, leader election, 10K connection cap per instance
  • SSE with 500 concurrent connection cap + auto-disconnect at 30min
  • HTTP connection pool via undici Agent for upstream API calls
  • No persistent database — static JSON archive + Redis cache
  • Provider framework with circuit breakers, anomaly detection, health monitoring
  • Only market-price category wired through ProviderChain (3 adapters: CoinGecko, CoinCap, Binance)
  • 11 API client libs (CoinMarketCap, CryptoQuant, DeFiLlama, Glassnode, L2Beat, LunarCrush, Messari, NFT Markets, The Graph, CryptoPanic, NewsAPI) NOT wired through ProviderChain

Prompt Sequence

Execute these prompts in order. Each builds on the previous.


Prompt 1 — PostgreSQL + Drizzle ORM

Add a PostgreSQL database to free-crypto-news using Drizzle ORM.

Requirements:
1. Add drizzle-orm, drizzle-kit, @neondatabase/serverless as dependencies
2. Create src/lib/db/schema.ts:
   - articles (id, slug, title, summary, url, source, category, coin_tags text[],
     published_at, fetched_at, embedding vector(1536), language, sentiment_score, impact_score)
   - prices_snapshot (id, coin_id, symbol, price_usd, market_cap, volume_24h, change_24h, timestamp)
   - provider_health (id, provider_name, chain_name, success_rate, avg_latency_ms, circuit_state, recorded_at)
   - api_usage (id, api_key, endpoint, method, status_code, latency_ms, timestamp, ip_hash)
   - users (id, email, api_key, tier, created_at, last_active_at)
   - alerts (id, user_id, type, config jsonb, last_triggered_at, created_at)
3. src/lib/db/index.ts — drizzle client, @neondatabase/serverless HTTP mode for Edge Runtime
4. drizzle.config.ts, db:generate/migrate/push/studio scripts
5. src/lib/db/queries/ — reusable query functions
6. GIN indexes on coin_tags, full-text on title, btree on published_at DESC
7. Migration script: scripts/db/migrate-archive.ts (JSONL → PostgreSQL)
8. File-based fallback if DATABASE_URL not set

Target: <100ms queries for 1M+ articles.

Prompt 2 — Background Job Queue with Inngest

Add Inngest for reliable background job processing.

Requirements:
1. Install inngest, create src/lib/inngest/client.ts (id: "free-crypto-news")
2. src/app/api/inngest/route.ts serve endpoint
3. Migrate crons: archive (5m), digest (daily), x-sentiment (15m),
   predictions (daily), tag-scores (1h), enrich-articles (10m)
4. New functions:
   - prices/snapshot.capture (30s) — snapshot top 100 prices to DB
   - providers/health.record (1m) — health metrics to DB
   - alerts/check.all (1m) — user alert evaluation
   - cache/warm.predictive (2m) — predictive cache warming
   - analytics/usage.aggregate (1h) — rollup stats
5. 3x retry with backoff, idempotency keys, error reporting
6. Fallback to Vercel cron when Inngest not configured

Target: 10K+ articles/hr, 100K+ price updates/hr.

Prompt 3 — WebSocket TypeScript Rewrite + Scaling

Refactor ws-server.js to TypeScript with production hardening.

Current state: JavaScript with Redis pub/sub, leader election, 10K cap,
safeSend, maxPayload 64KB, graceful shutdown.

Requirements:
1. Refactor → src/lib/ws/server.ts (TypeScript)
2. Keep all existing: pub/sub, leader election, safeSend, caps, shutdown
3. Add ioredis for cluster support
4. Type-safe channels: "prices:{coinId}", "news:latest", "news:breaking",
   "alerts:{userId}", "market:global", "sentiment:live"
5. Per-client subscription tracking: Map<WebSocket, Set<string>>
6. Per-IP limit (100 conns) + per-instance limit (50K)
7. /ws/stats metrics endpoint
8. 4 replicas in docker-compose.yml

Target: 50K connections/instance, 200K total.

Prompt 4 — CDN + Edge Caching Strategy

Comprehensive CDN caching with tag-based purging.

Requirements:
1. src/lib/cache/cdn-headers.ts — setCacheHeaders(res, preset):
   REALTIME (s-maxage=5), FAST (30), STANDARD (120), SLOW (3600), STATIC (86400)
2. Surrogate-Key headers for tag-based purging
3. src/lib/cache/purge.ts — purgeByTag/Path/All, support Vercel/Cloudflare/Fastly
4. Apply presets to ALL /api/* handlers:
   /api/prices/* → REALTIME, /api/news/* → FAST, /api/search → STANDARD,
   /api/archive/* → SLOW, /api/openapi.json → STATIC
5. Cache-Status: HIT/MISS/STALE/BYPASS header
6. ?force=1 bypass (admin only)
7. Vary: Accept-Encoding, Accept-Language, Accept

Target: 95% cache hit rate, <10ms edge responses.

Prompt 5 — Observability Stack

Production observability for 1M+ scale.

Requirements:
1. src/lib/observability/metrics.ts — Prometheus-compatible:
   http_requests_total, http_request_duration_ms (histogram),
   cache_hits/misses, provider_requests, provider_latency,
   ws_connections, db_queries, job_executions
2. GET /api/metrics (METRICS_TOKEN protected)
3. src/lib/observability/tracing.ts — trace ID per request, structured JSON logs
4. src/lib/observability/alerts.ts — rules for p99, error rate, cache hit, circuit breakers, WS capacity → webhook alerts
5. Grafana dashboard JSON at infra/grafana/dashboard.json
6. /admin/dashboard with live metrics

Target: Identify bottlenecks within 60 seconds.

Prompt 6 — Load Testing Suite

K6 load tests validating 1M user capacity.

Requirements:
1. scripts/load-tests/:
   smoke (10 VU, 1m), load (1K→10K VU, 10m), stress (10K→50K, 15m),
   spike (100→100K→100), soak (5K VU, 1h), websocket (10K conns)
2. Mix: 40% news, 25% prices, 15% market, 10% search, 10% other
3. SLOs: p95 <200ms, p99 <1s, error <0.1%, cache >90%
4. run.sh: start stack → health → smoke → load → stress → report
5. GitHub Action: smoke on PR, full on release

Target: Prove 10K req/sec, <200ms p95.

Prompt 7 — DDoS Protection + Load Shedding

Survive abuse and overload without crashing.

Requirements:
1. src/lib/security/ip-reputation.ts — score 0-100, auto-block >80
2. src/lib/security/request-fingerprint.ts — detect distributed scraping
3. src/lib/security/adaptive-rate-limit.ts — tighten under load
4. src/lib/load-shedding.ts:
   GREEN → YELLOW (>70%: no AI, 2x cache) → ORANGE (>85%: stale only) → RED (>95%: 503 except news+prices)
5. X-Service-Level header
6. WS: ORANGE stop new, RED disconnect idle
7. Admin dashboards for security + load shedding

Target: Survive 100K req/sec DDoS. Never crash.

Prompt 8 — API Gateway + Rate Limit Tiers

Production API gateway with paid tiers.

Requirements:
1. Tiers:
   Free (no key): 30/min, 1K/day
   Starter (free key): 300/min, 50K/day
   Pro ($29/mo): 3K/min, unlimited
   Enterprise ($199/mo): 30K/min, SLA
2. src/lib/gateway/api-key.ts — validation, issuance, rotation, tracking
3. src/lib/gateway/quota.ts — daily quotas, X-RateLimit-* headers
4. Update middleware.ts for tier-based limits
5. GET /api/v1/usage, GET /api/admin/keys
6. Backward compatible: free-tier IP limits still work

Target: Self-serve signup in <2 min.

Prompt 9 — Multi-Region Deployment

Multi-region for <100ms global latency.

Requirements:
1. infra/terraform/ — Neon PG replicas (us-east, eu-west, ap-southeast),
   Upstash Redis Global, Cloudflare DNS
2. src/lib/db/read-replica.ts — route reads to nearest replica
3. X-Region response header
4. docker-compose.multi-region.yml — 3 regional clusters + Traefik
5. docs/MULTI-REGION.md with Mermaid diagram

Target: <100ms global, automatic failover.

Prompt 10 — Disaster Recovery

Survive any infrastructure failure.

Requirements:
1. scripts/dr/snapshot.ts — nightly Redis + PG to R2/S3
2. scripts/dr/restore.ts — full restore + integrity check
3. docker-compose.dr.yml — warm standby
4. infra/runbook.md — 4 failure scenarios
5. RTO <5 min, RPO <1 hour
6. Monthly DR drill

Target: API stays up when everything goes down.

Execution Order

PhasePromptsTimelineImpact
Foundation1 (Database), 2 (Jobs)Week 1Persistent data, async processing
Scale3 (WebSocket), 4 (CDN)Week 2100K concurrent users
Observe5 (Observability), 6 (Load Test)Week 3Know your limits
Protect7 (DDoS + Load Shedding)Week 3Survive attacks
Monetize8 (API Gateway)Week 4Revenue + abuse protection
Global9 (Multi-Region), 10 (DR)Week 4<100ms worldwide

Success Metrics

MetricTarget
p95 response time< 100ms cached, < 500ms uncached
p99 response time< 500ms cached, < 1,000ms uncached
CDN cache hit rate> 95%
Error rate< 0.05%
WebSocket connections100K+ per region
DB query time (p95)< 50ms
TTFB (global)< 100ms
Monthly requests1B+
Uptime99.99%
RTO< 5 minutes
Infra cost at 1M users< $2,000/mo