Cloudflare Browser Rendering vs Galley Render
The short version
- Cloudflare Browser Run is a raw primitive: a headless Chromium you drive from a Worker or a REST call, billed by browser time.
- Galley Render is a document product — templates, a JSON Schema per version, deterministic caching, signed delivery — and Cloudflare's browser is a perfectly sensible thing to build one on.
- On raw compute Cloudflare is dramatically cheaper. What you are choosing between is a bill and an engineering project.
| Item | Cloudflare Browser Run | Galley Render |
|---|---|---|
| The unit | Browser time, rounded to the hour per day | One PNG or JPG, or one PDF page |
| Floor | $5/mo on Workers Paid | $0 — 200 renders a month, plus a keyless 50-render trial |
| Included | 10 browser hours a month | 5,000 renders on the $19 plan |
| Beyond that | $0.09 per browser hour, $2.00 per extra concurrent browser | $4 per 1,000 renders on every paid plan |
| The template contract | Yours to write, host and version | A JSON Schema per immutable template version |
There is no per-request or per-PDF price on Cloudflare because none exists — it bills browser time. Any “$ per render” figure for Cloudflare is an estimate, and the worked scenarios below state their assumptions. Measure X-Browser-Ms-Used on your own workload before trusting any of it.
This one is not really a competition, and a comparison page that pretended otherwise would be lying to you. Cloudflare Browser Rendering is a raw primitive: a headless Chromium you drive from a Worker or a REST call, billed by browser time. Galley Render is a document product — templates, a JSON Schema per version, deterministic caching, signed delivery — and if you build it yourself, Cloudflare’s browser is a perfectly sensible thing to build it on. On raw compute Cloudflare is dramatically cheaper than Galley, and the numbers below say so plainly. What you are choosing between is a bill and an engineering project.
What each one is
Section titled “What each one is”Cloudflare Browser Run gives you two modes. Quick Actions are single-shot REST endpoints — /content, /screenshot, /pdf, /markdown, /snapshot, /accessibilityTree, /scrape, /json, /links and /crawl (Beta, REST only). Browser Sessions give you a real Puppeteer, Playwright or CDP connection you drive yourself. You supply the HTML or the URL; Cloudflare supplies the browser.
Galley Render takes a template name and a JSON payload and returns a signed URL to a PDF, PNG or JPG. Templates are HTML with a Liquid subset and a JSON Schema per version; versions are immutable and content-addressed; identical inputs hit a deterministic cache and cache hits are never billed. It cannot screenshot an arbitrary URL, scrape a page, or convert a site to Markdown. Those are Cloudflare jobs.
Pricing
Section titled “Pricing”| Workers Free | Workers Paid | |
|---|---|---|
| Browser hours | 10 minutes per day | 10 hours per month, then $0.09 per additional hour |
| Concurrent browsers (Browser Sessions only) | 3 | 10 (monthly average), then $2.00 per additional browser |
“Quick Actions: Charged for browser hours only. Browser Sessions (Puppeteer, Playwright, CDP): charged for both browser hours and concurrent browsers.”
Underneath sits a Workers plan. Free gives 100,000 requests/day and 10 ms CPU per invocation. Paid is $5/month, with 10M requests/mo (+$0.30 per additional million) and 30M CPU-ms/mo (+$0.02 per additional million CPU-ms). So the floor for Browser Run on Paid is $5/mo plus $0.09 per browser-hour past the first ten.
Daily rounding matters more than it looks: “1,800 seconds (30 minutes) or more is rounded up to the nearest hour, and 1,799 seconds or less is rounded down.” Every Quick Actions response returns an X-Browser-Ms-Used header so you can measure this yourself. And: “If a Quick Actions request fails with a waitForTimeout error, the browser session is not charged.”
Cloudflare’s own worked example: 50 hours on Paid is 40 billable hours × $0.09 = $3.60; concurrency averaging 15 is 5 × $2.00 = $10.00; total $13.60.
Galley, for contrast:
| Plan | Price | Includes |
|---|---|---|
| Free | $0 | 200 renders/mo, 3 templates, no watermark. Plus a keyless 50-render MCP trial |
| Pay as you go | $0.006/PNG or JPG, $0.015/PDF page | Default $50/mo spend cap |
| Starter | $19/mo | 5,000 renders, 25 templates, webhooks, 30-day retention |
| Growth | $79/mo | 30,000 renders, unlimited templates, cloud push, 90-day retention, priority queue |
| Scale | $249/mo | 150,000 renders, dedicated pool, SLA |
Overage $4 per 1,000 renders. Effective per-render: $0.0038, $0.00263, $0.00166.
Worked scenarios
Section titled “Worked scenarios”Our assumption, stated once: a single-page PDF render takes 3 browser-seconds end to end. That number is ours, not Cloudflare’s, and it is the single biggest lever in everything below. A heavy page with remote fonts and images will take longer; a trivial one less. Cloudflare’s default page-load timeout is 4,500 ms, which is a hint about the order of magnitude but not a measurement.
1. 10,000 single-page PDFs a month, spread evenly. Cloudflare: 10,000 × 3 s = 30,000 browser-seconds = 8.33 hours, which is inside the 10 free hours on Paid. Spread over 30 days that is 1,000 s/day, and 1,799 s or less rounds down, so the daily rounding may zero it out entirely. Estimated $5/mo — the Workers Paid floor, nothing more. Galley: 10,000 pages. Starter covers 5,000, plus 5,000 overage × $0.004 = $20. $19 + $20 = $39/mo.
2. 100,000 single-page PDFs a month, spread evenly. Cloudflare: 100,000 × 3 s = 300,000 s = 83.3 hours. Per day that is 10,000 s = 2 h 46 m 40 s; the 2,800-second remainder is over 1,800, so it rounds up to 3 h/day, or 90 billable hours a month. 90 − 10 free = 80 × $0.09 = $7.20, plus the $5 Workers Paid floor. Estimated $12.20/mo. The 100,000 Worker requests are far inside the 10M included. Galley: 100,000 pages. Scale includes 150,000. $249/mo.
3. The free tiers.
Cloudflare Free: 10 minutes of browser time per day. At our 3-second assumption that is roughly 200 renders/day, about 6,000/month — though Quick Actions on Free are also limited to one request every 10 seconds, and /crawl to 5 jobs/day and 100 pages per crawl.
Galley Free: 200 renders/month, 3 templates, plus 50 keyless renders over MCP with no signup at all.
On raw volume, Cloudflare’s free tier is larger by an order of magnitude.
So: Cloudflare is roughly 20x cheaper on the compute in scenario 2, and it is not a close call. What the $12.20 does not include is the templating system, the schema validation, the version pinning, the cache, the object storage, the signed-URL delivery, the retry and webhook plumbing, the font handling, and the person who builds and then owns all of it. That is the actual trade, and we are not going to put a dollar figure on your engineering time to make the comparison flatter.
Limits
Section titled “Limits”| Cloudflare Browser Run | Galley Render | |
|---|---|---|
| Browser timeout | 60 s, extendable “to up to 10 minutes” via keep_alive | Not applicable — you do not manage a browser |
| New browser instances | 1 per 20 s (Free), 3 per second (Paid) | Not applicable |
| Concurrent browsers | 3 (Free), 200 per account (Paid, increase on request) | Not applicable; dedicated pool on Scale |
| Total requests (Quick Actions) | 1 every 10 seconds (Free), 30 per second (Paid) | Not published on the pages in this comparison; see the render reference |
| Rate-limit response | HTTP 429 with Retry-After | rate_limited, HTTP 429 |
| Request body | “The PDF endpoint accepts request bodies up to 50 MB” | Large payloads queue rather than returning inline |
| Session lifecycle | “Sessions also close when Browser Run rolls out a new release.” Unclosed sessions keep burning browser time until timeout | No sessions to leak |
Feature comparison
Section titled “Feature comparison”| Cloudflare Browser Run | Galley Render | |
|---|---|---|
| PDF endpoint | POST https://api.cloudflare.com/client/v4/accounts/<accountId>/browser-rendering/pdf, Bearer token with “Browser Rendering – Edit”. “You must provide either url or html.” Returns a binary PDF | POST https://api.galleyrender.com/v1/render with a template name and data. Returns JSON with an expiring signed URL |
| PDF options | addStyleTag, viewport, gotoOptions, pdfOptions (format, margins, headers/footers, scale), cookies, authenticate, userAgent, resource allow/reject | page_size, landscape, margin, scale, background, print_background, css, and raster width/height/quality |
| Screenshot an arbitrary URL | Yes, /screenshot | No |
| Scrape, Markdown, links, accessibility tree, crawl | Yes — /markdown, /scrape, /json, /links, /accessibilityTree, /crawl (Beta) | No |
| Drive a real browser | Yes, Puppeteer, Playwright or CDP | No |
| Templating | You supply url or html on every call. There is no template store documented on the pages we read | HTML plus a Liquid subset, stored, named and versioned |
| MCP server | Yes — Cloudflare ships a Browser Run MCP server, plus llms.txt and llms-full.txt | Yes, at https://mcp.galleyrender.com/mcp, plus a skill file and llms.txt |
| Output delivery | The /pdf endpoint returns a binary PDF; storing and serving it is yours to build | Expiring signed URL, one hour by default, refreshable via get_render |
| JSON Schema contract per template | Not found on the pages we read | Yes, per version, with a free validate_data dry run |
| Deterministic render cache, unbilled on a hit | Not found on the pages we read | Yes — SHA-256 of template checksum, canonical data, canonical options and format |
Where Cloudflare is the better choice
Section titled “Where Cloudflare is the better choice”- Cost, if you are willing to build. Scenario 2 is an estimated $12.20 against $249. If render volume is large, predictable and the output is simple, the arithmetic is on Cloudflare’s side and you should take it seriously.
- You need the whole browser. Puppeteer, Playwright and CDP sessions let you log in, click, wait, intercept and scrape. Galley has no equivalent and no plans we can point you at.
- Arbitrary URLs.
/screenshot,/markdown,/scrapeand/crawloperate on the live web. Galley only renders your own templates with your own data. If your job is “turn this page into a PDF,” Cloudflare does that and Galley does not. - You are already on Workers. The browser is one binding away, it runs next to your code, and
X-Browser-Ms-Usedmakes the cost legible per request. - No per-request pricing at all. For bursty or unusual workloads, billing on time rather than on units can be much kinder than a per-render meter.
Where Galley is the better choice
Section titled “Where Galley is the better choice”- It is a document product, not a browser. Named, versioned templates; a schema that tells an agent what the payload must contain before it spends a render; field-level validation errors with a path, an expected type and an acceptable value.
- Caching is the billing model, not a project. Identical inputs produce the same file and cost nothing the second time. On Cloudflare you would build that.
- Delivery is included. A signed, expiring URL comes back from the render call. Cloudflare’s
/pdfhands you bytes and leaves storage, expiry and access control to you. - Page-level metering is predictable. You are billed for pages, not for however long a browser happened to take. No session leak can run up your bill.
- Nothing to operate. No Worker to maintain, no sessions to close, no release-window session closures to handle, no fonts to install.
Nothing above needs an account, a card or a key. The demo renders on the production service.
Migrating
Section titled “Migrating”If you are moving off a Worker that posts HTML to /pdf, the change is that you stop generating HTML in your own code and start storing it as a template. Create the template once:
curl -sS https://api.galleyrender.com/v1/templates \ -H "Authorization: Bearer $GALLEY_API_KEY" \ -H 'content-type: application/json' \ -d '{ "name": "packing-slip", "html": "<html><body><h1>Order {{ order_id }}</h1><p>{{ customer.name }}</p></body></html>", "schema": { "type": "object", "required": ["order_id"], "properties": { "order_id": { "type": "string" }, "customer": { "type": "object" } } } }'Then render it, from a Worker or anywhere else:
curl -sS https://api.galleyrender.com/v1/render \ -H "Authorization: Bearer $GALLEY_API_KEY" \ -H 'content-type: application/json' \ -d '{ "template": "packing-slip@1", "format": "pdf", "data": { "order_id": "SO-8841", "customer": { "name": "Acme" } }, "options": { "page_size": "Letter", "margin": "18mm" } }'{ "object": "render", "id": "rnd_7hq2m4x8k1bv", "status": "succeeded", "template": "packing-slip@1", "format": "pdf", "cached": false, "url": "https://<account>.r2.cloudflarestorage.com/galley-renders/renders/…?X-Amz-Expires=3600&X-Amz-Signature=…", "page_count": 1, "billable_units": 1}A reasonable hybrid exists and we will say so: keep Cloudflare for anything that touches the live web — screenshots, scraping, crawling — and use Galley for the documents you generate from your own data. They are not substitutes. See the quickstart and the template gallery.
Where the competitor’s numbers came from
Section titled “Where the competitor’s numbers came from”Sources
Section titled “Sources”All accessed 2026-09-16.
- Browser Rendering / Browser Run pricing — https://developers.cloudflare.com/browser-rendering/platform/pricing/ (page footer: “Last updated Apr 21, 2026”)
- Browser Rendering / Browser Run limits — https://developers.cloudflare.com/browser-rendering/platform/limits/ (page footer: “Last updated Aug 20, 2026”)
- Product landing page, where the “Browser Run” title and the
/browser-run/canonical path appear — https://developers.cloudflare.com/browser-rendering/ - REST API (“Quick Actions”) overview and endpoint list — https://developers.cloudflare.com/browser-rendering/rest-api/
- PDF endpoint reference — https://developers.cloudflare.com/browser-rendering/rest-api/pdf-endpoint/
- Workers platform pricing — https://developers.cloudflare.com/workers/platform/pricing/
- Galley Render pricing — /pricing
Prices and limits change, and Cloudflare’s two pages above were last updated on different dates. Check https://developers.cloudflare.com/browser-rendering/platform/pricing/ and our pricing page before deciding anything on these numbers. The per-render estimates on this page are ours and depend on a 3-second assumption you should replace with a measurement.