Skip to content

fix(ci): cap V8 heap below Cloudflare's 8 GB build container#223

Merged
dcrawbuck merged 2 commits into
mainfrom
dcrawbuck/fix-production-worker-deploy
Jun 25, 2026
Merged

fix(ci): cap V8 heap below Cloudflare's 8 GB build container#223
dcrawbuck merged 2 commits into
mainfrom
dcrawbuck/fix-production-worker-deploy

Conversation

@dcrawbuck

@dcrawbuck dcrawbuck commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

Problem

Cloudflare Workers Builds (the git-connected CI that builds & deploys the docs Worker on push to main) has been intermittently failing on main. Builds end with:

[prerender] Prerendering pages...
[prerender] Crawling: /
An internal error occurred. Please retry your build. If this problem persists, contact Cloudflare support.

(outcome: terminated). The client and SSR bundles build fine — the build dies the instant the prerender crawl starts.

Root cause

The build runs NODE_OPTIONS=--max-old-space-size=8192 — an 8 GB V8 heap — but Workers Builds containers have exactly 8 GB of RAM (20-min timeout, so this is not a timeout). Telling V8 it may grow to 8 GB on an 8 GB box defers the major GC until RSS already exceeds the container, so the kernel OOM-kills the build during the prerender crawl (its peak-memory moment). The abrupt stop with no stack trace — just Cloudflare's "internal error" — is the OOM-kill signature.

GitHub PR CI never caught this because its runners have 16 GB, so the same 8 GB heap fits.

Fix

  • Lower the V8 heap ceiling to 5 GB (--max-old-space-size=5120) in the build and build:cf:staging scripts — above the ~4 GB the SSR bundle needs (4096 flaky-crashes with V8 "heap out of memory"), and below the 8 GB container so the major GC fires before RSS hits the ceiling.
  • Drop prerender concurrency 2 → 1 to trim the crawl's peak memory.

Prerendering stays fully enabled; site output is byte-for-byte identical.

Verification

  • Local build with the shipped config: 556 pages prerendered, bun test 65 pass / 0 fail, ~2.2 min.
  • Confirmed the 8 GB container limit (CF docs), real-node heap-cap enforcement, and the ~4 GB SSR floor.
  • Final 8 GB-container proof: this PR's Cloudflare preview build.

Same fix also covers staging (shares the build script). Do not merge until the preview build is green.


Note

Low Risk
Build-time memory tuning only; no runtime app, auth, or data-path changes, and prerender output is intended to stay identical.

Overview
Lowers the Node/V8 old-space heap limit for production docs builds from 8 GB to 5 GB (--max-old-space-size=5120) on the main build script so prerender can run inside Cloudflare’s 8 GB RAM build containers without the kernel OOM-killing the process when the heap matches container size.

The build:cf:staging script no longer sets its own NODE_OPTIONS=8192; it only sets CLOUDFLARE_ENV=staging and delegates to build, so staging uses the same 5 GB cap.

Reviewed by Cursor Bugbot for commit 5272278. Bugbot is set up for automated code reviews on this repo. Configure here.

Cloudflare Workers Builds run in an 8 GB container, but the build
requested an 8 GB V8 heap (--max-old-space-size=8192). V8 defers its
major GC until the heap nears that ceiling, so during the prerender
crawl total RSS exceeds 8 GB and the container is OOM-killed
("An internal error occurred... contact Cloudflare support", terminated).
GitHub PR CI passes only because its runners have 16 GB.

Lower the heap ceiling to 5 GB -- above the ~4 GB the SSR bundle needs,
below the 8 GB container limit -- and prerender one page at a time to
trim the crawl's peak memory. Prerendering stays enabled; build output
is unchanged (556 pages, tests green).
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 25, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
superwall-docs 5272278 Commit Preview URL

Branch Preview URL
Jun 25 2026, 04:57 PM

The heap cap alone addresses the OOM (it's what stopped V8 from growing
toward the 8 GB container during prerender). concurrency:1 was over-
conservative and added ~2.3 min to the build, so revert it to the original
2 -- keeps build time at the historical ~8 min. Also drop the redundant
NODE_OPTIONS from build:cf:staging, since it calls `build`, which already
sets the cap on the only V8/node step (vite build).
@dcrawbuck dcrawbuck changed the title fix: cap V8 heap below Cloudflare's 8 GB build container fix(ci): cap V8 heap below Cloudflare's 8 GB build container Jun 25, 2026
@dcrawbuck dcrawbuck merged commit 2b91841 into main Jun 25, 2026
3 checks passed
@dcrawbuck dcrawbuck deleted the dcrawbuck/fix-production-worker-deploy branch June 25, 2026 17:55
Sign up for free to 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