Cloudflare Worker Size Limit + @vercel/og: Exclude resvg.wasm (2026 Guide)
Hit the Cloudflare Worker 1 MB (free) or 3 MB (paid) size limit trying to ship @vercel/og on OpenNext? The culprit is resvg.wasm — the WebAssembly rasterizer Satori pulls in to convert JSX-to-SVG-to-PNG. Excluding resvg.wasm and switching to raw SVG concatenation drops your Worker bundle by ~90%, cuts p99 latency from 521 ms to 54 ms, and drops per-million cost from $2 to $0.30. Below: the exact wrangler.toml exclude, a drop-in raw-SVG replacement, and the full 2026 benchmark that got us there.
The quick fix: exclude resvg.wasm in wrangler.toml
[build] command = "..." [[rules]] type = "CompiledWasm" globs = ["**/*.wasm"] fallthrough = false # Then in your worker code, don't import @vercel/og's PNG path — # use the SVG-only render or drop @vercel/og entirely for raw SVG strings.
If you must keep @vercel/og for JSX ergonomics, use its SVG-only mode (skip toPNG()) — that alone drops the wasm dependency. Twitter/X, Slack, LinkedIn all render OG SVG cards fine in 2026.
The two approaches in one paragraph
Cloudflare Workers + SVG strings — concatenate an SVG template, return as image/svg+xml. No image library, no rasterization. Tiny bundle.
Vercel OG / Satori — render React JSX to SVG with Satori, optionally rasterize to PNG with resvg-wasm. Larger bundle, more flexible.
Test setup
- Workload: 10,000 OG image requests, randomized titles 30-90 chars, random templates
- Concurrency: 50 parallel requests
- From: Mumbai, ap-south region
- Tools: autocannon for load testing, vmstat for resource monitoring
Latency results
| Metric | CF Workers SVG | Vercel OG (PNG) | Vercel OG (SVG-only) |
|---|---|---|---|
| p50 | 11ms | 187ms | 94ms |
| p95 | 28ms | 312ms | 156ms |
| p99 | 54ms | 521ms | 241ms |
| Cold start | 22ms | 1,840ms | 1,420ms |
Cloudflare Workers SVG is 10-20x faster on every metric. The Satori library (a few hundred KB of WASM) has to be loaded and warmed; SVG concatenation is plain JavaScript.
Throughput
- CF Workers SVG: sustained 4,200 req/sec from a single Worker
- Vercel OG (PNG): ~340 req/sec before queueing
- Vercel OG (SVG): ~720 req/sec
For high-volume sites (1M+ shares/month), this matters. Vercel OG queues requests and you pay for compute time.
Cost per million requests
Both platforms have generous free tiers, but the per-unit economics diverge as you scale.
| Provider | Free tier | Cost per 1M (after free) | Compute time |
|---|---|---|---|
| Cloudflare Workers | 100K req/day free | $0.30 per 1M | Counts CPU only (10-20ms/req) |
| Vercel Edge Functions | 500K invocations/mo | $2.00 per 1M | Counts wall time (200ms/req) |
For 5M OG image requests per month, Cloudflare costs ~$1.50, Vercel costs ~$10.
Bundle size
| Stack | Compiled bundle |
|---|---|
| CF Workers SVG (raw) | ~12KB |
| CF Workers + Satori + resvg | ~3.2MB (just under Workers limit) |
| Vercel OG (Satori) | ~2.8MB |
The Workers free tier limits scripts to 1MB compressed; the paid tier allows 10MB. SVG-only approach uses 1% of the limit.
Output quality
Where Vercel OG wins:
- Pixel-perfect PNG output (vs SVG which some social platforms misrender)
- JSX flexibility — design with React
- Easy custom font loading
- Better text-fitting algorithm (Satori auto-shrinks)
Where SVG approach wins:
- Speed (10-20x faster)
- Cost (1/7th)
- Simplicity (no React, no rasterizer)
- Edge cache hit rate higher (smaller responses)
The hybrid approach
The pattern og.hjlabs.in uses: SVG-first for instant response, with optional ?format=png that rasterizes via Resvg-WASM only when needed. The vast majority of social platform crawlers accept SVG; only Facebook and iMessage occasionally need PNG.
When to choose Vercel OG
- You're already on Vercel and want zero new infrastructure
- You need pixel-perfect PNG output for Facebook reliability
- You have designers who want JSX-driven layouts
- You publish <500K OG images per month (cost is irrelevant)
When to choose Cloudflare Workers
- You publish 100K+ OG images per month and care about cost
- You need sub-50ms p99 (e.g., for crawler retries)
- You're already on Cloudflare
- You don't need designer-grade JSX flexibility — fixed templates are fine
The hosted middle path
Don't want to run either? Use a hosted service. og.hjlabs.in runs the Cloudflare Workers SVG approach for you — free, no signup, latency 10-30ms globally. The hosted route saves you the maintenance and gets you 90% of the value.
Updated July 2026: the current Worker size limits
The numbers in the bundle-size table above were written against the old 1 MB free-plan ceiling. Cloudflare has since raised the free plan to 3 MB compressed per Worker; the paid plan stays at 10 MB compressed. That changes the arithmetic but not the conclusion: a Satori + resvg bundle at ~3.2 MB still does not fit the free plan, and on the paid plan it burns a third of your budget before you have written a line of application code. The raw-SVG path at ~12 KB uses 0.4% of the free-plan limit, which is why it remains the default recommendation. Note that the limit is measured after compression on the uploaded bundle, so a wasm binary that looks acceptable on disk can still fail the upload once your framework, router, and fonts are in the same script.
Bottom line
For raw performance and cost: Cloudflare Workers + SVG wins by 10x. For developer experience: Vercel OG wins for Next.js shops. For minimum-effort: a hosted service like og.hjlabs.in wins for everyone else. Pick based on your constraints, not the loudest marketing.
Frequently asked questions
Why does @vercel/og blow past the Cloudflare Worker size limit?
The culprit is resvg.wasm, the WebAssembly rasterizer Satori pulls in to convert JSX to SVG to PNG. A Worker bundling Satori plus resvg compiles to roughly 3.2 MB, versus about 12 KB for raw SVG string concatenation, so the wasm rasterizer alone accounts for almost the entire bundle.
How do I exclude resvg.wasm from my Worker bundle?
Add a CompiledWasm rule in wrangler.toml with globs ["**/*.wasm"] and fallthrough = false, then stop importing the PNG path of @vercel/og. If you want to keep @vercel/og for JSX ergonomics, use its SVG-only mode and skip toPNG() — that alone drops the wasm dependency.
How much faster is raw SVG than @vercel/og on the edge?
Across 10,000 requests at 50-way concurrency: p50 of 11 ms versus 187 ms, p99 of 54 ms versus 521 ms, and cold start of 22 ms versus 1,840 ms. Throughput is 4,200 req/sec from a single Worker versus about 340 req/sec for Vercel OG in PNG mode. That is 10-20x on every metric.
What does each option cost per million OG images?
Cloudflare Workers bills CPU time only and costs $0.30 per million after a free tier of 100K requests/day. Vercel Edge Functions bill wall time and cost $2.00 per million after 500K invocations/month. At 5M OG image requests per month that is roughly $1.50 on Cloudflare versus $10 on Vercel.
Will social platforms render SVG OG images?
The vast majority of social platform crawlers accept SVG in 2026 — Twitter/X, Slack and LinkedIn all render OG SVG cards fine. Only Facebook and iMessage occasionally need PNG, which is why the hybrid pattern is SVG-first with an optional ?format=png that rasterizes via Resvg-WASM only when asked.
When should I still choose Vercel OG over Cloudflare Workers?
When you are already on Vercel and want zero new infrastructure, when you need pixel-perfect PNG output for Facebook reliability, when designers want JSX-driven layouts, or when you publish under 500K OG images per month so cost is irrelevant.
Generate your OG images and favicons
Free. URL-based API. Edge-cached. No signup.
Open the generator →