You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hosting landscape 2026: stay on Netlify (Credit Pro) vs pivot — ranked recommendation + configs
Filed by Muse Spark after parallel explore-agent research: (a) read-only audit of this repo's deploy stack, (b) triage of all platform/infra GitHub issues, (c) live web research on Netlify / Vercel / Cloudflare / Fly / Render / Railway / Cloud Run / ACA / SST+AWS pricing + fit as of 11 Sep 2026.
Scope per requester: India-first, 100s–1000s users now, scale to worldwide later. Concurrency + traffic-spike behaviour explicitly in scope. Netlify Legacy Pro → Credit Pro migration explicitly in scope. Configs included.
Do NOT hard-pivot this week. Stay on Netlify short-term, fix 5 known-bad configs, make the app portable in parallel, and pivot to Fly.io (BOM/SIN) only when a numeric trigger fires.
Rank
Platform
Verdict for THIS stack
Rough cost at our scale
Stay (0–3 mo)
Netlify (resolve Legacy vs Credit below)
Cheapest switch cost. Full Node, ISR/on-demand/PPR-via-function all work today. Pain is real (#1124 stall, #932 cross-region, #1560 cache) but all have mitigations that don't require re-platforming.
$20/mo flat (+ credits if on Credit Pro). See §3 burn math.
1st pivot target
Fly.io + Cloudflare CDN front + Supabase ap-south-1 + Upstash
Best fit for Next.js App Router + Prisma + react-pdf + Razorpay + 5-min cron + India audience. Full Docker, no function timeout, persistent pool kills Supavisor pain, BOM region kills cross-region latency, cheapest persistent egress.
~$29–60/mo (2 machines + volume + egress).
2
Render Standard + Pro workspace
Easiest team DX if you want native Cron + previews + autoscale without Docker ops. Same Node fidelity as Fly.
~$50–115/mo team before traffic.
3
SST (ECS/Fargate container, NOT Lambda) + AWS
Best if AWS/compliance/VPC already in picture. EventBridge cron first-class, CloudFront ISR, Graviton savings. Overkill for single-service SaaS (ALB $22 + NAT $33/AZ floor, 8–12 min first deploy).
~$50–110/mo at scale.
4
Railway Pro
Fastest solo iteration, per-second billing. Fine for standalone MVP. 2026 reliability reports weaker than Fly/Render.
~$15–40/mo.
5
Vercel Pro
Best DX/ISR/PPR/previews/monorepo, maxDuration 800s, Fluid attachDatabasePool. Bill shock risk with react-pdf + 8.6k cron runs/mo + image/ISR. Per-seat kills seat economics vs Netlify flat $20.
Cheapest at scale, fastest edge (330 PoPs, India 10–30ms), zero egress. Blocker today:react-pdf / Prisma TCP / 10–50ms CPU / 128–256MB / Images all need rework. Re-evaluate after official Adapter API adapter + Containers GA.
~$5–25/mo if you fit. We don't yet.
Avoid (new)
AWS Amplify / App Runner / ECS-classic
Amplify: no on-demand ISR/streaming/edge-middleware, 220MB SSR cap. App Runner: closed to new customers 30 Apr 2026 → ECS Express instead.
—
Why phased, not hard pivot: re-platforming does NOT fix our top incidents (#1124 stall is Netlify-specific and goes away on Fly, but #1560 cache-key, #1436 pool=1 deadlock family, #1298 RESEND key, #1377 test-keys-in-prod, #920 build-hits-DB all move with us if we lift-and-shift). Fix-then-port is cheaper than port-then-debug.
Pivot triggers (any one fires → start Fly port, §8):
#1124-class p95 TTFB on cold paths > 8s for 7 consecutive days after §6 stay-fixes, OR BetterStack #1557 false-down > 3/day.
Credit-Pro burn > 2500 credits/mo for 2 consecutive months with BW > 120GB/mo (means PDFs/images must leave the function anyway).
Scheduled ticker p99 > 20s or any reconcile-* needing > 30s (scheduled-function cap) more than weekly.
Hosting today: netlify.toml:1-63[build] command="npm run build" publish=".next", NODE_VERSION=22, NODE_OPTIONS=--max-old-space-size=6144 (raised 4096→6144 per ADR-24, infra: cross-region latency (Netlify us-east-2 ↔ Supabase ap-south-1) causes Postgres pooler connection timeouts #932). No [[plugins/redirects/headers/functions]]. Runtime @netlify/plugin-nextjs@5.15.13 (platform-injected, not in deps) single function ___netlify-server-handler (v2 name — v1 ___netlify-handler names match NOTHING, netlify.toml:34-38 gotcha). No netlify/edge-functions/, no _redirects/_headers. Redirects/headers in code (next.config.mjs:62-105,316-323, middleware.ts:156-210).
Portable alt already in repo but unused in prod: Dockerfile, Dockerfile.prod:1-84, docker-compose*.yml (HEALTHCHECK /api/health), shims lib/url.ts:42-43 (VERCEL_URL), cleanup-route.ts:116 (VERCEL_CRON_SECRET).
2. What keeps breaking on Netlify (measured, linked)
2.1 One fat function + cold-stall (the #1 platform tax)
Stream: restore noise cancellation and background blur, and put a size budget on the server function #1158 OPEN — Stream filters parked, size budget risk.parked/stream-call-filters after 18/18 deploy failures. Standing risk: Lambda 250MB unzipped (Invalid AWS Lambda parameters on handler, not raisable; Vercel 5GB flag has no Netlify equivalent). Parked pkg only ~5.4MB but handler already ~245MB (node_modules 1.5GB, @prisma 164MB, @sentry 78MB). Next dep of any size breaks deploy with green checks + local next build OK. Wants netlify build; du -sh .netlify/functions-internal/___netlify-server-handler budget in CI.
PG_POOL_MAX=1 makes Promise.all over Prisma reads a no-op on every deployed context #1117 CLOSED — PG_POOL_MAX=1 makes Promise.all over Prisma reads a no-op. Sequential median 1142ms vs parallel 1176ms (noise) over 20 rounds GET /api/auth/get-session. Deliberate: 125 functions×10 default = 1250 sockets vs Supavisor ~200 cap. Rule: collapse to nested select/relationJoins until measured.
Netlify Durable Cache ignores the query string on /api/user/consultants: page 2 serves page 1 for 60 s in production #1560 OPEN P-high — Durable Cache ignores querystring on /api/user/consultants: page2 serves page1 for 60s.Cache-Control: public,s-maxage=60,SWR=300 + runtime netlify-vary: query=__nextDataReq|_rsc → key varies only on 2 internal params, collapses page,limit,sort,domain,minRating,.... Prod 2026-09-11: ?page=2 returned meta.page:1 same 3 ids, cache-status: Netlify Durable hit ttl=56. Same defect /api/user/reviews (s-maxage=120 + rating,consultantId,search). 10+ public,s-maxage routes share it (recordings, orgs public, plans, slots/availability, currency 3600).
Deploy previews never report to Sentry, and the join toast claims they do #1086 CLOSED — deploy previews never report to Sentry.NEXT_PUBLIC_SENTRY_DSN inlined at build; Netlify per-context env separate from GH secrets, prod-only value absent on previews → enabled:false. 6h org-wide Sentry query during preview-1067 join failures: zero events.
Compute has no free tier. Sync 60s (good for >10s, tight for react-pdf 20–40s), scheduled 30s (risk if 5-min ticker does rollups > 30s), background 15min with 202 (fixes long PDF but needs async poll/webhook — extra requests+compute). 1GB default; 4GB for PDF quadruples burn. Example doc: 2.5GB×37min = 1.54 GB-hr = 15.4 credits.
Worked example: 100GB BW = 2000cr + 60 deploys = 900cr + 27 GB-hr compute (~500k×200ms @1gb) = 277cr = ~3177 > 3000 base → auto-recharge fires. At 100s–1000s users this is avoidable (offload PDFs/images, cut deploys, ISR more); at worldwide image-heavy scale it is not.
Single region (cmh default). Prisma to ap-south-1 adds 200ms+/query → longer GB-hr + need Supavisor 6543 + ?connection_limit=1. No multi-region functions.
ISR via adapter: time + on-demand supported, but via Function layer not edge-stitched. High revalidation rate = compute+BW+requests triple-count.
Stay on Legacy if: 1–2 seats + predictable ~1TB + low compute — switching is one-way. Move to Credit if: 3+ seats (seat savings dwarf usage delta) or you want hard caps (Auto-Recharge OFF → pause not bill; legacy has NO caps, only 50/75/90/100% email alerts).
Site plan evidence: #1482 API readout account teetangh/Practitionist-Deploys, Pro plan — does not state legacy vs credit. Action before any decision: confirm in Netlify dashboard → Team settings → Billing whether this team shows "Legacy Pro" or "Credit Pro / 3000 credits", and whether Auto-Recharge is ON/OFF.
4. Platform landscape (2026-09-11 list prices, USD)
4.1 Vercel Pro — best DX/ISR/PPR, worst seat economics for us
Base Pro $20/seat/mo incl. 1 deploy seat + $20 usage credit/seat. Viewers free. SSO $300, HIPAA $350, preview-suffix $100, Observability Plus $1.20/M.
Incl (per team): 1TB Fast Data Transfer + 10M Edge Requests. Then: FT $0.15/GB · Edge $2.00/M · Origin transfer $0.06/GB from byte 1 · Invocations $0.60/M from req 1 · Active CPU (Fluid, code-only, I/O free) $0.128/CPU-hr (BOM $0.14) · Provisioned mem $0.0106/GB-hr · Build $0.126/min.
Real bills (MakerKit 2026-05): 3 seats + 250k visitors/5M API ≈ $305/mo ($78 BW + $130 edge + $63 builds). 1.5M/10TB ≈ $3,096/mo. BW + edge dominate, not seats/CPU.
4.2 Cloudflare Workers + OpenNext — cheapest/fastest edge, blocked for this stack today
Direction 2026: new → Workers + @opennextjs/cloudflare (GA Feb 2026) or vinext for Next 16. next-on-pages maintenance. Docs 2026-08-25 list vinext recommended.
Egress NA/EU $0.02 / APAC/SA $0.04 / Africa/India $0.12 — no free allowance new orgs. 7.5× cheaper than Render $0.15 in NA/EU, 6× spread hurts multi-region India (still cheaper than Netlify $0.133/Vercel $0.15 at our volumes).
Reservation −40% ($36/yr for $5/mo shared). Real SaaS 2 machines+PG+Redis ~$29/mo, 3-region perf ~$226/mo.
Fit: full Node (react-pdf fine), no timeout, persistent pool (10 conns, skip Supavisor latency if single-region; keep Supavisor if scaled), any region incl. BOM/SIN near Supabase, PR machines, fly deploy + fly logs.
Compute/sec: Starter $7 (0.5/512MB) · Standard $25 (1/2GB) · Pro $85 (2/4GB) → Ultra $450 (8/32GB). BW overage $0.15/GB, builds 1k free then $5/1k-min, disks $0.25/GB, KV $10/256MB–$32/1GB, PG $6–$19.
Floor: Starter $7 + PG $6 = $13 solo; Pro ws + Standard + PG Pro + KV = $115 team before traffic. Native Cron Jobs, full-stack previews, private networking. Single region (pick Singapore for India), rolling deploys need config.
4.6 Railway — fastest solo iteration
Trial $5 once/30d · Hobby $5 incl $5 · Pro $20 incl $20 · Enterprise custom. Credit resets, no rollover. Rates RAM $10/GB + vCPU $20/vCPU + egress $0.05/GB + vol $0.15/GB, per-sec, stopped $0. 1vCPU+2GB always-on = $40 → Hobby bill $40, Pro bill $40 ($20 covered). Tiny standalone (0.5/512MB) ~$15/mo. PR envs, cron, Dockerfile. 2026 reliability/storage reports weaker; 1-region; front with CF if India-heavy.
Cloud Run: request-based (scale-to-zero) CPU active $0.000024/vCPU-s ($0.086/hr) + mem $0.0000025/GiB-s + req $0.40/M. Free 2M req + 180k vCPU-s + 360k GiB-s. Instance-based (min-instances) CPU $0.000018/s + mem $0.000002/s (no req fee). Example 10M×400ms×1vCPU/512MB/20 conc EU ≈ $81.72/mo after free. Tier1 vs Tier2 regions, Registry+Build+Logging+LB+egress separate.
ACA Consumption: per-sec vCPU+GiB+req. Free/grant per sub/mo 180k vCPU-s + 360k GiB-s + 2M req. Active vs idle (<0.01 CPU + <1KB/s) discounted. Scale-to-zero $0.
Rolling deploys need config else brief 502. Private networking helps pool.
Autoscale CPU/mem target, healthcheck /api/health, zero-downtime rolling
Cloud Run/ACA
1000/instance (tunable 1–1000) + max-instances
Up to 60m / none
Scale-to-zero cold ~500ms–2s, then linear. Best spiky cost.
concurrency, min-instances=1 for checkout/webhook, max-instances cap = cost cap
SST Lambda
1000/account/region (burst)
15m
Throttles → retry + DLQ + SQS. Fargate alt has no timeout.
Reserved concurrency for webhooks, DLQ on Razorpay route
CF Workers
1000s (isolate)
10–50ms CPU / ~30s wall
Instant, but CPU-kills long tasks.
Move react-pdf/Prisma to Queue + R2 + D1/Hyperdrive
Vendor cliffs bind BEFORE infra at our current scale: Stream 100 MAU, Resend 100/d, Novu 30k/mo, Upstash 10k/d (all ~$10–20/mo to lift per #874). Caching absence moves wall 2–3k→10k (#734 highest leverage). 125+60 moves to 10k (Pro+Supabase bump). 100k needs workers/replicas/queue.
5. Feature-fit matrix (for THIS stack)
Capability
Vercel Pro
Netlify Credit Pro
CF Workers/OpenNext
SST+AWS
Fly
Render/Railway
Cloud Run/ACA/ECS
ISR time-based
✅ Native sub-sec
✅ Via adapter, occasional stale
✅ Via R2/KV, eventual ~60s
✅ Native (Dynamo/SQS) / ✅ Node
✅ Just Node + CDN headers
✅ Same
✅ Same
ISR on-demand (revalidateTag/Path)
✅ Full
✅ Supported
🟡 Maturing
✅ Yes (SST), ❌ Amplify
✅ Yes
✅ Yes
✅ Yes
PPR / use cache
✅ Only true edge-stitched
✅ Via Function (functional, perf gap)
🟡 Maturing, Adapter API 16.2
🟡 Depends
✅ Just Node
✅ Just Node
✅ Just Node
>10s functions
✅ 300–1800s
✅ Sync 60s, Bg 15m (background:true), Sched 30s
❌ 50ms CPU — no for react-pdf
✅ Lambda 15m / Fargate none
✅ None
✅ None (60–100s tunable)
✅ 60m / none
react-pdf (Node/sharp/canvas/bundle)
✅ 4GB, 250MB (5GB large)
✅ 4GB, 6MB buffered/20MB streamed
❌ Native fails, Images add-on
✅ Lambda+Sharp layer / Fargate best
✅ Full Docker
✅ Full Docker
✅ Full Docker
Cron 5-min ticker (~8640/mo)
✅ Vercel Cron sec-precision
⚠️ Scheduled 30s/256KB
✅ Cron Triggers + Queues
✅ EventBridge in sst.config
⚠️ Separate machine + superfly/cron or external
✅ Native Cron (Render) / Cron (Railway)
✅ Scheduler/Logic/EventBridge
Razorpay webhooks (raw body, idempotent)
✅ force-dynamic + after()/waitUntil
✅ Bg 202 + retry 1m/2m, careful body parse
⚠️ Streaming/signing quirks, tail logs
✅ API GW raw + DLQ
✅ Stable anycast + volume replay
✅ Stable URL + disk
✅ Stable + VNet + DLQ
Prisma + Supabase pooling
✅ 6543 + directUrl 5432 + attachDatabasePool
⚠️ Single-region, connection_limit=1, no Fluid helper
⚠️ TCP needs Hyperdrive, prefer HTTP/Data API
✅ VPC + RDS Proxy/Supavisor, warm control
✅ Long-lived pool (10, no pooler) + Supavisor if scaled
✅ Same long-lived
✅ Same + private link
Preview envs
✅ Best (PR URL, Skew, comments)
✅ Free previews/branch, instant rollback
✅ Branch previews / opennext preview
⚠️ DIY (--stage pr-123 + GH)
✅ PR machines + volumes
✅ Full-stack previews (Pro) / PR envs
⚠️ DIY (revisions + GH)
Monorepo
✅ Turbo cache, root settings
✅ 3+ concurrent, shared env, per-app adapter
⚠️ Turbo pain, npm workspaces advised
✅ Multi-component sst.config
✅ Multi-process fly.toml
✅ Monorepo + private net
✅ ACR + pipelines
Lock-in
Highest (Fluid/after/Blob/KV/Image/WAF/Skew)
Medium, improving (OpenNext adapter mid-2026)
Runtime (V8+KV/R2/D1/Queues/Hyperdrive)
Most portable serverless (CF/Lambda/S3/Dynamo/SQS)
Highest portability (Dockerfile+standalone)
Same
Same
Pooling notes: runtime DATABASE_URL=…pooler…:6543 + DIRECT_URL=db…:5432 migrations. Disable prepared statements (pgbouncer=true or prepare:false) unless PgBouncer ≥1.21 server-side. Supabase 6543 = txn-only since 28 Feb 2025, 5432 = session. Vercel Fluid MUST attachDatabasePool else suspended leaks. Containers with 1 always-on Node can use direct + small in-process pool and skip Supavisor latency (+2ms/query, −50% throughput vs co-located PgBouncer). Redis: none include managed Redis for this pattern — bring Upstash/Redis Cloud (edge) or ElastiCache/Memorystore. Stream.io outbound HTTPS only — any platform works; pin region near Supabase to cut tail. India: CF 348 PoPs wins TTFB (35–48ms São Paulo vs Vercel 120–145ms; India 10–30ms vs 40–80ms benchmarks) but loses on react-pdf/Prisma — pair CF CDN in front of Fly/BOM or SST ap-south-1 if audience India.
2026 equalizer: Next 16.2 Deployment Adapter API (stable Mar 2026) — Netlify/CF/AWS building official adapters on same contract. Code written to OpenNext today survives transition.
6. Stay path: 5 fixes + guardrails (do these even if we pivot — they move with us)
Netlify Durable Cache ignores the query string on /api/user/consultants: page 2 serves page 1 for 60 s in production #1560 — vary cache by real query params (P-high, 1-line-class fix). Either (a) Netlify-Vary: query=page|limit|sort|domain|minRating|minPrice|maxPrice|companies|search|languages on /api/user/consultants (+ rating|consultantId|search on /api/user/reviews), or (b) smallest/cannot-be-wrong: CDN-cache only default page else private,no-store. Grep all 10+ public,s-maxage routes before merge.
Cron on Fly: separate process = "cron" running tsx jobs/ via superfly/cron, OR keep GH Actions backstop + Upstash QStash for Class-A (#1010). Front with Cloudflare DNS/CDN (10–30ms India) + R2 for PDFs/images (#1314).
Hosting landscape 2026: stay on Netlify (Credit Pro) vs pivot — ranked recommendation + configs
0. TL;DR + recommendation (phased stay-then-pivot)
Do NOT hard-pivot this week. Stay on Netlify short-term, fix 5 known-bad configs, make the app portable in parallel, and pivot to Fly.io (BOM/SIN) only when a numeric trigger fires.
react-pdf+ Razorpay + 5-min cron + India audience. Full Docker, no function timeout, persistent pool kills Supavisor pain, BOM region kills cross-region latency, cheapest persistent egress.standaloneMVP. 2026 reliability reports weaker than Fly/Render.maxDuration 800s, FluidattachDatabasePool. Bill shock risk withreact-pdf+ 8.6k cron runs/mo + image/ISR. Per-seat kills seat economics vs Netlify flat $20.react-pdf/ Prisma TCP / 10–50ms CPU / 128–256MB / Images all need rework. Re-evaluate after official Adapter API adapter + Containers GA.Why phased, not hard pivot: re-platforming does NOT fix our top incidents (#1124 stall is Netlify-specific and goes away on Fly, but #1560 cache-key, #1436 pool=1 deadlock family, #1298 RESEND key, #1377 test-keys-in-prod, #920 build-hits-DB all move with us if we lift-and-shift). Fix-then-port is cheaper than port-then-debug.
Pivot triggers (any one fires → start Fly port, §8):
#1124-class p95 TTFB on cold paths > 8s for 7 consecutive days after §6 stay-fixes, OR BetterStack#1557false-down > 3/day.reconcile-*needing > 30s (scheduled-function cap) more than weekly.1. Context / constraints (what this ranking is optimised for)
ap-south-1data gravity matters more thaniad1DX today.package.json:next ^15.5.0,react ^18.3.1, Node 22 (.nvmrc,Dockerfile,netlify.toml:7). App Router only (app/layout.tsx, 100+app/**/page.tsx,app/api/**/route.ts,middleware.ts,instrumentation.ts). Nopages/.middleware.ts:1-494= Edge: maintenance gate (lib/maintenance-edge.ts, 30s cache, fail-open), Upstash edge rate-limits (lib/rate-limit.ts, ~30 named limiters — Implement layered rate limiting strategy for Netlify deployment #407/security: move IP-based rate limiters to middleware edge for DDoS cost-amplification protection #459), cookie-presence auth only (real session inlib/auth.ts:customSession, edge lacksnode:crypto).export const revalidate300–3600 onapp/page.tsx:54, explore recordings/organisations/experts pages;force-dynamicon recordings[slug], programs, trial checkout;fetch(...,{revalidate:3600,tags});staleTimes {dynamic:30,static:180}(next.config.mjs:169-188,316-323). Guard tests__tests__/explore/isr-routes-never-fail-open.test.ts.netlify.toml:1-63[build] command="npm run build" publish=".next",NODE_VERSION=22,NODE_OPTIONS=--max-old-space-size=6144(raised 4096→6144 per ADR-24, infra: cross-region latency (Netlify us-east-2 ↔ Supabase ap-south-1) causes Postgres pooler connection timeouts #932). No[[plugins/redirects/headers/functions]]. Runtime@netlify/plugin-nextjs@5.15.13(platform-injected, not in deps) single function___netlify-server-handler(v2 name — v1___netlify-handlernames match NOTHING,netlify.toml:34-38gotcha). Nonetlify/edge-functions/, no_redirects/_headers. Redirects/headers in code (next.config.mjs:62-105,316-323,middleware.ts:156-210).build=db:generate && next build;eslint/typescript.ignoreDuringBuilds=!!process.env.NETLIFY(infra: cross-region latency (Netlify us-east-2 ↔ Supabase ap-south-1) causes Postgres pooler connection timeouts #932);webpackMemoryOptimizations+optimizePackageImports;outputFileTracingExcludestoolchain ~40MB (feat(content): document review versioning, curated recordings marketplace, org material scoping #1244 250MB cap);outputFileTracingIncludesfonts/react for PDF routes ([finance][P1 HIGH] B2C Place-of-Supply Never Captured — GST Split Latent #1365/Organisation invoice PDF route answers 500 on the Netlify build: @react-pdf/renderer throws React error #31 (objects are not valid as a React child) #1468). Explicitruntime="nodejs"onapp/api/webhooks/razorpay/route.ts:26(edge lacksnode:crypto, Set Razorpay LIVE keys on production and delete RAZORPAY_ALLOW_TEST_KEYS_IN_PRODUCTION before signup reopens #1377).provider="postgresql"(7038-lineschema.prisma, frozen Pre-MVP infrastructure & schema freeze — Redis gaps, analytics stack, Postgres extensions, queue strategy #705).prisma.config.tsusesDIRECT_URL+ placeholder. Runtimelib/prisma.ts:48-68PrismaPg({connectionString:DATABASE_URL, connect 3s/query 6s, PG_POOL_MAX}). Host Supabase+Supavisor (.env.sample:1-8,README):DATABASE_URL :6543?pgbouncer=truetxn,DIRECT_URL :5432direct/session. Redis Upstash REST (lib/redis.ts,with-cron-lock.ts15m TTL / 35m payout). Stream.io (@stream-io/node-sdk 0.7.64, chat 9.52, video-react 1.42). Razorpay primary (razorpay ^2.9.6,KEY_ID/SECRET/WEBHOOK_SECRET(+_PREVIOUS), RazorpayX + Route). Stripe fenced contingency [P0 CRITICAL] Stripe Implementation Parity — Idempotency, Timeouts, Guards, and Validation #1351 (stripe ^20.2.0). Storage Supabase Storage + R2 (SUPABASE_S3_*,R2_*,documentsprivate bucket signed URLs, Recording storage vendor decision: Cloudflare R2, with the full cost, compliance and Stream-compatibility research #1314). Resend (resend ^6.8.0), Novu (@novu/api ^3.13), Better-Auth 1.6.3, Sentry@sentry/nextjs ^10.59(+sentry.{server,edge,shared}.config.ts).netlify/functions/cron-tick.mts:19{schedule:"*/5 * * * *"}POSTs 10xapp/api/cleanup/*(sweep-stuck-webhook-events,cascade-refund-earnings,reconcile-refunds,abandoned-payments limit 10,reconcile-payment-status,reconcile-orphaned-confirmations,sweep-orphaned-topup-captures,dispatch-outbound-webhooks,sync-payment-earnings,release-earnings) withCRON_SECRET, 6s per-target timeout,200/207=ok,409=lockHeld(chore(cron): a Netlify scheduled ticker drives the sub-hourly money sweeps #1390/[enterprise][P0 CRITICAL] walletCredit increments a NULL walletBalance, so the cached balance stays NULL while the ledger is credited (ledger-vs-cache drift on any account created without a zero balance) #1459, ADR-27 state-as-outbox ticker). Fleetjobs/**~60 files each with HTTP twinapp/api/cleanup/*~48 routes (cleanup-route.tswrapper:CRON_SECRET||VERCEL_CRON_SECRET,?limitcap 500 +with-cron-lock+abortIfMaintenance)..github/workflows/*.yml~30 crons as backstop (e.g.sweep-stuck-webhook-events 4-59/10,send-appointment-reminders :47,stream-sync 40 3 * * *).after()in razorpay/stream/verify-signature/document routes — best-effort, killed on freeze (lib/stream/recording-handlers.ts:319, [payments][P1 HIGH] Post-commit work in after() starves the single-connection pool: two unawaited ~39 s Novu triggers overlap the chat-channel step and it dies at the 3 s connect timeout #1446).Dockerfile,Dockerfile.prod:1-84,docker-compose*.yml(HEALTHCHECK /api/health), shimslib/url.ts:42-43(VERCEL_URL),cleanup-route.ts:116(VERCEL_CRON_SECRET).2. What keeps breaking on Netlify (measured, linked)
2.1 One fat function + cold-stall (the #1 platform tax)
___netlify-server-handler(1024MB ~0.58 vCPU, RSS 675–795MB/1018MB heap). 37/40 warm 400–453ms. Burst-scaled, cannot be bounded from app code. Module-load exonerated (uptime 3.3s, own module 39–100ms).memory=2048A/B 2026-08-22 correctly targeted: 11/12 still slow 35–39s + platform-500 — CPU-share hypothesis dead, reverted08b10ce4. Mitigations only: retry past stall + serve from ISR. Keep-warm PR Implement ISR with RSC seeding for explore pages #1148 never merged (per /api/health pages ~8×/day on Netlify cold-instance stalls, and reports the database unreachable on every one of them #1557). Full recorddocs/perf/netlify-stall-ticket-draft.md,.claude/skills/nextjs-netlify-caching/SKILL.md./api/healthpages ~8×/day on cold-instance stalls, reports DB unreachable. BetterStack 100 incidents/30d to 2026-09-11 (99.48%, 3h55m "downtime", 8–10/d since Sep 3). Homepage 3 incidents. None real outage. Shape: 30.0s timeout one region + 30s confirm + 2 regions timeout → recover 2m later. 3×500/502with Netlify request-ID (stall past ceiling ~39s). Root: (1) A newly created function instance stalls its event loop for ~24s before any application work #1124 stall trips 30s checker, re-checks spawn 2 more stalled instances; (2) ours:app/api/health/route.tsarms DB-probe timers BEFORE stall, they fire first tick after, reportdegraded/unreachablewith no retry whilelib/prisma.tswould connect in ~330ms on retry.connectionTimeoutMillis=3000fired 29.78s,Duration:30113mson preview 1118, 42 cold renders bimodal (no sample 6.8–30.8s). Root:setTimeoutcan't fire on blocked loop — superseded by A newly created function instance stalls its event loop for ~24s before any application work #1124, closed 2026-09-05 moot. Lesson preserved inlib/prisma.ts:11-20comment.POST /api/admin/reconcile-ledgers~27s → Netlify edge 504 while report row still lands. Preview test(finance): union of the finance train for deploy-preview verification — DO NOT MERGE #1422 E2E 2026-09-04. Full-scope reconcile at function ceiling, browser 504 butledger_reconciliation_reportswritten. Worse on prod data. Proposed:?limit/scope like cleanup twin, full scope only from scheduled job, admin enqueue-and-poll.parked/stream-call-filtersafter 18/18 deploy failures. Standing risk: Lambda 250MB unzipped (Invalid AWS Lambda parameterson handler, not raisable; Vercel 5GB flag has no Netlify equivalent). Parked pkg only ~5.4MB but handler already ~245MB (node_modules1.5GB,@prisma164MB,@sentry78MB). Next dep of any size breaks deploy with green checks + localnext buildOK. Wantsnetlify build; du -sh .netlify/functions-internal/___netlify-server-handlerbudget in CI.getSlotBookingStatus+ 30-min windows +formatInTimeZonetens of thousands times. Fixed per-view fetch, kill per-slot tz-format, index, dedup/Abort, cache(consultant,window,tz)+ compute-outside-tx, write-only tx. Family of pool-starvation, not just algorithm.2.2 DB cross-region +
PG_POOL_MAX=1(the #2 tax, interacts with #1)Netlify us-east-2 ↔ Supabase ap-south-1causes pooler timeouts. Sentrytimeout exceeded when trying to connect(/explore/experts) +Connection terminated(/api/announcements),cloud.region:us-east-2 Lambda nodejs22.xvsaws-0-ap-south-1.pooler.supabase.com:6543. Cold TCP+TLS+Supavisor auth 200ms+/RT, observed 5–9.6s hangs vs 3s budget → fail-open. Mitigated byPG_POOL_MAX=1, per-route fail-open,unstable_cache. Interim Singaporesin(no Mumbai on Netlify), durable Accelerate/co-locate.lib/prisma.tschange + usage bill + proxy. Corrects framing: nearest Netlify self-servesin/nrt/syd, still cross-regionap-southeast-1↔ap-south-1.EAUTHTIMEOUTfrom pooler on slots under E2E load.PrismaClientKnownRequestErrorpg auth > 3s on availability endpoint. Asks: pooler mode/limits, is 3s too tight cross-region (infra: cross-region latency (Netlify us-east-2 ↔ Supabase ap-south-1) causes Postgres pooler connection timeouts #932), retry once?PG_POOL_MAX=1makesPromise.allover Prisma reads a no-op. Sequential median 1142ms vs parallel 1176ms (noise) over 20 roundsGET /api/auth/get-session. Deliberate: 125 functions×10 default = 1250 sockets vs Supavisor ~200 cap. Rule: collapse to nestedselect/relationJoinsuntil measured.validateSlotAvailability→checkConsent (lib/compliance/dpdp.ts:194 global)insidecalculateAmountAndValidateholds sole connection, nested read waits 3s → everyPOST /api/checkout500 since20fef46Wave 7. Local E2E passed only because devpoolMax=10. Fixed PR fix(payments): the checkout consent gate reads through the transaction, not the pool it is blocking #1435checkConsent(tx?). Jest pin models single-connection pool.after()starves pool: 2×~39s Novu triggers overlap chat-channel step dies at 3s. Tracecc6c5d41ack 1.8s, thenvoid PromiseNovu 39s each overlapensure-channels.ts:48six-relationincludeon global →pg-pool.connect 3.5s. Money unaffected (committed pre-Phase 2, healed by reconciler). Fix:Promise.allSettledNovu ~5s timeout before channel step, deadline onensureChannels, narrowinclude. KeeppoolMax=1.2.3 Caching / ISR footguns (safe alone, unsafe together)
/api/user/consultants: page2 serves page1 for 60s.Cache-Control: public,s-maxage=60,SWR=300+ runtimenetlify-vary: query=__nextDataReq|_rsc→ key varies only on 2 internal params, collapsespage,limit,sort,domain,minRating,.... Prod 2026-09-11:?page=2returnedmeta.page:1same 3 ids,cache-status: Netlify Durable hit ttl=56. Same defect/api/user/reviews(s-maxage=120+rating,consultantId,search). 10+public,s-maxageroutes share it (recordings, orgs public, plans, slots/availability, currency 3600).fallbackOnTransientDbErrorrethrows at build but returns fallback at request time → on-demand ISR 200 cachesConsultantUnavailableshell (2/42 cold renders, then 0.3s with climbingage, 200 + warning only). Fix: rethrow on cacheable render or mark uncacheable. Root The 3s Prisma connect budget is not enforced — connect timeout fires at t+29.8s and pins the function for 30s #1120.fetch, 0unstable_cache/revalidateTag, 1357includevs 875select, 9Suspense. Hottest 84 includesslots/appointments/[id]. 970-line Navbar everywhere, offsetskip/take, nopg_trgm/FTS/GIN, Stream 771KB. Must re-runANALYZE=true.2.4 Build / deploy / preview / env sync
force-dynamic(drop fix(build): build-time DB connect timeout so prerendering survives a slow pooler #919 workaround). PR fix(build): build-time DB connect timeout so prerendering survives a slow pooler #919 gave build 30s vs runtime 3s (IS_NEXT_BUILDinlib/prisma.ts) to survive Netlify build outage. Proper fix page-by-page audit underapp/explore/*.NEXT_PUBLIC_SENTRY_DSNinlined at build; Netlify per-context env separate from GH secrets, prod-only value absent on previews →enabled:false. 6h org-wide Sentry query during preview-1067 join failures: zero events.dev.familiarisenow.com→dev.dev/prod.dev. Sitefamiliarise 1a1ad7d0Pro,custom_domain familiarisenow.com,branch_deploy_custom_domain dev.familiarisenow.com, no branch context in toml. Auto<branch>.<base>leaks into UI/DEPLOY_PRIME_URL/allow-lists.@react-pdf/rendererReact All CUIDs in prisma should be replaced by UUIDs #31.invoice-renderer.tsxreconciler dispatches onReact.version; Netlify functionreactresolves differently. All 3 statutory routes undownloadable deployed. Fix external whole@react-pdffamily or__non_webpack_require("react")+ pinning test.SUPPLIER_STATE_CODEenv without GSTIN — mis-decides CGST/SGST vs IGST), P0: production email delivery dead since 2026-06-18 — invalid RESEND_API_KEY hard-locks signup and password reset #1298 OPEN P0 (prod email dead since 2026-06-18 invalidRESEND_API_KEY, 16+7+1+1DEAD_LETTER, 18/249 usersemailVerified:falseloop), Set Razorpay LIVE keys on production and delete RAZORPAY_ALLOW_TEST_KEYS_IN_PRODUCTION before signup reopens #1377 OPEN (prod carriedrzp_test_…, fix(payments): fail fast on Razorpay test keys in production; money-cron failures page (#677 PM-10, PM-34) #1219 guard throws at module load underNODE_ENV=production→ cancel/preview/reject/checkout 500 since 2026-08-26; gate KYC→live keys prod-context only→unset opt-out→webhook secret→redeploy→then P0: production email delivery dead since 2026-06-18 — invalid RESEND_API_KEY hard-locks signup and password reset #1298), [notifications][P2 MEDIUM] useNovuSubscriberSync fetch to /api/novu/subscriber fails in production and a dashboard fetch parses an HTML error page as JSON #1443 OPEN P2 (Novu hookFailed to fetch+ HTML-as-JSON), Audit what console.error/warn payloads serialise, now that they reach Netlify function logs #1127 OPEN (709console.error/warnsites now reach team-scoped Netlify logs — PII sweep), Plan white-label custom-domain routing for multi-tenant orgs (Indian market standard) #1476 OPEN (white-label custom-domain plan: stay path-based…/dashboard/[orgWorkspaceId], need per-tenant domain+auto-SSL confirm).2.5 Cron / scheduler (better than GA, still fragile)
*/10→ ~8/d; 50/6d vs 576/144 expected. Silent failures (33/55 echo-only), schema drift (GA runs dev-HEAD vs shared DB), 60d auto-disable. Decision ~40 daily/weekly stay GA,10 Class-A → QStash ($1–5/mo). Superseded by ADR-27 ticker.delayUntil1y, no cron, opaque credits) + Upstash Workflow fallbacks.detect-consultant-no-showshas no HTTP twin, ticker can't drive it. Onlyscripts/via GA wrapper, noapp/api/cleanup/detect-consultant-no-shows/route.tswithcleanupRoute()unlike 36 twins. OnFINANCIAL_JOB_NAMES(detect-consultant-no-shows issues refunds but is not in FINANCIAL_JOB_NAMES, so it keeps running in DEGRADED maintenance while every other refunding job stops #1506) so DEGRADED hold correct.FINANCIAL_JOB_NAMES), [cron][P2 MEDIUM] reconcile-refunds cleanup route throws a non-Error value, so Sentry records "Error: [object Object]" with no message #1441 OPEN P2 (reconcile-refundsthrows non-Error →[object Object]), Audit GH Actions cron schedules — multiple jobs collide on the Supabase pooler #709 CLOSED (35 workflows collide on pooler — stagger/concurrency:prisma-pool), [payments][P1 HIGH] GitHub Actions Crons Missing concurrency Groups — 56 UnGuarded Scheduled Workflows (20 Money Crons) #1413 CLOSED P1 (56/67 scheduled withoutconcurrency), Cron jobs report into an uninitialised Sentry — 58 job files, every error silently dropped #1066 CLOSED (58 job files Sentry-blind — shared bootstrap init+flush), [booking][P0 CRITICAL] Cron lock is fail-open — concurrent unlocked runs double-refund / double-notify during a Redis outage #1341 CLOSED P0 (lock fail-open double-refund on Redis outage → fail-closed for money + CAS), P0: the money-reconciliation cron layer has never run — React 18 has no cache() #1275 CLOSED P0 (8 money reconcilers never imported — React 18 nocache()), Infrastructure / platform layer audit (Redis, maintenance, feature flags, cron health) #697 OPEN (no Razorpay breaker, env-boolean flags need DB override), Pre-MVP infrastructure & schema freeze — Redis gaps, analytics stack, Postgres extensions, queue strategy #705 OPEN (Redis gaps, Realtime, pgvector, Sentry tags).2.6 Capacity / readiness umbrellas
rateLimit:{enabled:false}intentional?,SEED_PASSWORDin.env.sample, deleteapi/test-race-condition|test-redis, maintenance bypass cookie → single-use token), scaling roadmap, Sentry landscape (v10, traces 100% → 0.1 prod, replay/tunnel off for bundle/function cost), cybersecurity 6 P0s.3. Netlify Legacy Pro → Credit Pro: what actually changed (read this before clicking Migrate)
$19/member/moincl. Git Contributors$20/mo/team, unlimited seats (Apr 14 2026 change, retroactive next cycle)$403.1 Credit burn math for OUR workload (model, then measure)
Meters (Pro pack rate): deploy 15 · compute 10/GB-hr · BW 20/GB · requests 2/10k.
netlify.tomlalready skips Dependabot).202(fixes long PDF but needs async poll/webhook — extra requests+compute). 1GB default; 4GB for PDF quadruples burn. Example doc: 2.5GB×37min = 1.54 GB-hr = 15.4 credits.cmhdefault). Prisma toap-south-1adds 200ms+/query → longer GB-hr + need Supavisor6543+?connection_limit=1. No multi-region functions.4. Platform landscape (2026-09-11 list prices, USD)
4.1 Vercel Pro — best DX/ISR/PPR, worst seat economics for us
$20/seat/moincl. 1 deploy seat +$20usage credit/seat. Viewers free. SSO $300, HIPAA $350, preview-suffix $100, Observability Plus $1.20/M.$0.15/GB· Edge$2.00/M· Origin transfer$0.06/GBfrom byte 1 · Invocations$0.60/Mfrom req 1 · Active CPU (Fluid, code-only, I/O free)$0.128/CPU-hr(BOM $0.14) · Provisioned mem$0.0106/GB-hr· Build$0.126/min.revalidateTag,maxDuration 300s default / 800s max / 1800s betasolves >10s, FluidattachDatabasePoolsolves leaks, best previews/monorepo/after(). Watch per-seat + zero-free compute + image/ISR +10–30%.4.2 Cloudflare Workers + OpenNext — cheapest/fastest edge, blocked for this stack today
@opennextjs/cloudflare(GA Feb 2026) orvinextfor Next 16.next-on-pagesmaintenance. Docs 2026-08-25 listvinextrecommended.1101. Mem 128MB free / 256MB paid.runtime="edge"must go for OpenNext.next/imageneeds Images binding. ISR needs R2 +r2IncrementalCacheelse SSR. Native modules (sharp/canvas) fail.4.3 SST v3 (Ion) + AWS — most portable serverless, heaviest ops
sst.aws.Nextjs→ Lambda+CloudFront+S3+Dynamo(ISR)+SQS(reval). Altsst.aws.Service→ ECS Fargatenext startstandalone.4.4 Fly.io — best fit default for us
shared-cpu-1x 256MB $2.02 / 1GB $5.92 / 2x/1GB $6.64 / perf-1x/2GB $32.19. Extra RAM ~$5/GB. Per-sec, stopped rootfs $0.15/GB. Volumes $0.15/GB, snapshots $0.08/GB (10GB free). Dedicated IPv4 $2, wildcard $1.fly deploy+fly logs.4.5 Render — easiest team DX
4.6 Railway — fastest solo iteration
4.7 GCP Cloud Run / Azure Container Apps / AWS ECS-Fargate — enterprise serverless containers
4.8 Concurrency + traffic-spike cheat sheet (what breaks first at 2× peak)
?limitsmall bites, ticker 6s timeouts, retry past stall, keep-warm only single-clickattachDatabasePoolelse leaks. Best burst absorb + Skew Protection.maxDuration, spend caps, Pause, Attack Challenge, WAFsoft_limit/hard_limit,min_machines_running=1,auto_stop, reservation/api/health, zero-downtime rollingconcurrency,min-instances=1for checkout/webhook,max-instancescap = cost capVendor cliffs bind BEFORE infra at our current scale: Stream 100 MAU, Resend 100/d, Novu 30k/mo, Upstash 10k/d (all ~$10–20/mo to lift per #874). Caching absence moves wall 2–3k→10k (#734 highest leverage). 125+60 moves to 10k (Pro+Supabase bump). 100k needs workers/replicas/queue.
5. Feature-fit matrix (for THIS stack)
revalidateTag/Path)use cachebackground:true), Sched 30ssst.configsuperfly/cronor externalforce-dynamic+after()/waitUntiltaillogs6543+directUrl 5432+attachDatabasePoolconnection_limit=1, no Fluid helperopennext preview--stage pr-123+ GH)sst.configfly.tomlafter/Blob/KV/Image/WAF/Skew)standalone)Pooling notes: runtime
DATABASE_URL=…pooler…:6543+DIRECT_URL=db…:5432migrations. Disable prepared statements (pgbouncer=trueorprepare:false) unless PgBouncer ≥1.21 server-side. Supabase6543= txn-only since 28 Feb 2025,5432= session. Vercel Fluid MUSTattachDatabasePoolelse suspended leaks. Containers with 1 always-on Node can use direct + small in-process pool and skip Supavisor latency (+2ms/query, −50% throughput vs co-located PgBouncer). Redis: none include managed Redis for this pattern — bring Upstash/Redis Cloud (edge) or ElastiCache/Memorystore. Stream.io outbound HTTPS only — any platform works; pin region near Supabase to cut tail. India: CF 348 PoPs wins TTFB (35–48ms São Paulo vs Vercel 120–145ms; India 10–30ms vs 40–80ms benchmarks) but loses on react-pdf/Prisma — pair CF CDN in front of Fly/BOM or SSTap-south-1if audience India.2026 equalizer: Next 16.2 Deployment Adapter API (stable Mar 2026) — Netlify/CF/AWS building official adapters on same contract. Code written to OpenNext today survives transition.
6. Stay path: 5 fixes + guardrails (do these even if we pivot — they move with us)
Netlify-Vary: query=page|limit|sort|domain|minRating|minPrice|maxPrice|companies|search|languageson/api/user/consultants(+rating|consultantId|searchon/api/user/reviews), or (b) smallest/cannot-be-wrong: CDN-cache only default page elseprivate,no-store. Grep all 10+public,s-maxageroutes before merge.lib/prisma.tsconnects in ~330ms on retry), don't arm timers before stall, separate liveness (200 if loop alive) from readiness (DB check with retry +cache-statusheader). Loosen BetterStack to 45s timeout + 5m confirm, or probe/+/api/healthcomposite.force-dynamicaudit onapp/explore/*DB pages so build never opens DB; route all 4 B2B sites throughresolveSupplierStateCode(GSTIN first, env fallback, disagree fail-closed); PII sweep on 709 log sites, preferreportSentryError/Sentry.logger.?limit/scope onreconcile-ledgerslike cleanup twins, full scope only from scheduled job, admin enqueue-and-poll; keepPER_TARGET_TIMEOUT_MS=6000(cron-tick.mts:50),abandoned-payments limit 10([enterprise][P0 CRITICAL] walletCredit increments a NULL walletBalance, so the cached balance stays NULL while the ledger is credited (ledger-vs-cache drift on any account created without a zero balance) #1459).netlify build; du -sh .netlify/functions-internal/___netlify-server-handler(fail > 220MB); Sentry prod sampling 0.1,sendDefaultPii:false, env-driven DSN, delete/sentry-example-*; Auto-Recharge OFF (hard cap = pause not bill), per-context env (fix Deploy previews never report to Sentry, and the join toast claims they do #1086/Set Razorpay LIVE keys on production and delete RAZORPAY_ALLOW_TEST_KEYS_IN_PRODUCTION before signup reopens #1377/P0: production email delivery dead since 2026-06-18 — invalid RESEND_API_KEY hard-locks signup and password reset #1298 ordering: KYC→live Razorpay keys prod-only→unset opt-out→webhook secret→redeploy→rotate Resend), offload PDFs/images to R2/S3 (never Netlify BW),take:100+select>include+ index advisor per Billing Guardrails: Prevent Surprise Bills Across All Services (Vercel, Netlify, Supabase, Stream, etc.) #481 §13–16 + emergency runbook §15.Stay-config patch (copy-paste):
7. Pivot-ready configs (no re-platform without these passing on preview)
7.1 Fly.io (1st pivot target) —
fly.toml+ DockerfileCron on Fly: separate
process = "cron"runningtsx jobs/viasuperfly/cron, OR keep GH Actions backstop + Upstash QStash for Class-A (#1010). Front with Cloudflare DNS/CDN (10–30ms India) + R2 for PDFs/images (#1314).7.2 Render (easiest team) —
render.yaml7.3 SST ECS/Fargate (if AWS) —
sst.config.tssketch7.4 Vercel (if ISR/PPR becomes core) — minimal diff
Plus Spend Management $100 + Pause, Attack Challenge, WAF bots,
ignoreCommand, offload PDFs to background/Fargate.7.5 Cloudflare front (works with ANY stay/pivot — do first)
DNS → Cloudflare, cache
/_next/static/*+public/*immutable, bypass/api/*except allow-listeds-maxageroutes WITHNetlify-Vary/CDN-Cache-Controlfixed per #1560. This alone cuts BW credits (Credit Pro) / FT $$ (Vercel) regardless of origin.8. Decision runbook: measure → trigger → migrate
EAUTHTIMEOUT/wk.bompreview (Dockerfile.prod +fly.toml§7.1), replay E2E + Razorpay webhook replay +reconcile-ledgersfull-scope (must pass >30s case that Netlify can't), load-test 2× peak, compare p95 + $/mo with REAL BW.sin/iadFly regions + read-replica (or Accelerate infra: evaluate Prisma Accelerate (ap-south-1 pool) as a durable cross-region fix — relates to #932 #937) + R2 multi-region; re-evaluate Vercel/Cloud Run when PPR/edge-SSR dominates.9. Open data needed (comment to unblock precise $/mo)
pzmbxqdgibfkhjwzeprfpooler mode/limits (for [infrastructure][P2 MEDIUM] EAUTHTIMEOUT from the Supabase pooler on the slots endpoint during the 2026-09-04 E2E load #1456 3s-too-tight call)?10. Sources (all accessed 11 Sep 2026 — re-verify before procurement)
Netlify pricing / credit plans / how-credits-work / Apr-2026 repricing / Jul-2026 Pro tiers · Vercel pricing / Pro plan / Functions usage / MakerKit May-2026 / AboveAPI Apr-2026 · Cloudflare OpenNext blog Apr-2025 / Workers Next.js docs Aug-2026 / Pages pricing Sep-2026 / Toolchew Jun-2026 · SST AWS Next.js Feb-2026 / Brandrums Jun-2026 / Starterpick Mar-2026 / SocialAnimal Apr-2026 · Fly pricing docs / AboveAPI Jun-2026 / Budgetforge Jul-2026 · Render pricing / workspace-plans Apr-2026 / Budgetforge Jul-2026 · Railway pricing/docs/plans · Cloud Run pricing / billing-settings / CloudCostKit · ACA pricing / billing Dec-2025 · Fargate/ECS pricing / Fortem May-2026 · ISR/PPR DevStacked Jun-2026 / SocialAnimal Apr-2026 · Vercel durations Aug-2026 / 30-min changelog Jun-2026 · Pooling Dusko Jul-2026 / Vercel KB Nov-2025.
Repo evidence:
netlify.toml,netlify/functions/cron-tick.mts,lib/prisma.ts:11-68,next.config.mjs,middleware.ts, ADR-27,.claude/skills/nextjs-netlify-caching/SKILL.md,docs/perf/netlify-stall-ticket-draft.md.Issues: #407 #459 #450 #481 #484 #639 #697 #705 #709 #734 #866 #874 #900 #907 #908 #920 #932 #937 #1010 #1066 #1086 #1117 #1119 #1120 #1124 #1127 #1158 #1160 #1275 #1298 #1314 #1341 #1377 #1413 #1436 #1441 #1443 #1446 #1447 #1449 #1450 #1454 #1456 #1468 #1476 #1482 #1487 #1506 #1517 #1530 #1557 #1560.
/cc @teetangh — needs your Billing screenshot + §9 numbers to lock Legacy-vs-Credit call. Proposed labels:
infrastructure,performance,production-readiness.