Guide
JavaScript rendering cost - headless browsers at 10k, 100k and 1M URLs
How much does it cost to render JavaScript at scale? Compute, browser orchestration, invalidation, and the hidden team cost of self-hosting at 10k, 100k, and 1M URLs.
Introduction
The visible cost of JavaScript rendering is usually the smallest number in the spreadsheet. Raw Chrome compute can look cheap at first glance. The expensive part is the system around it: concurrency control, queueing, retries, stale-snapshot detection, invalidation triggers, storage, monitoring, and the people who keep it healthy when crawler volume spikes. If you are comparing architecture first, keep dynamic rendering vs SSR open alongside this guide.
That is why build-vs-buy decisions go wrong so often. A team models 100,000 URLs with two-second renders, multiplies by cloud CPU pricing, and concludes the DIY path costs almost nothing. Then the first month of real operation introduces browser crashes, stale HTML incidents, queue backlog, crawl bursts, and on-call work that were never in the estimate.
This guide is meant to fix that blind spot. Not by arguing that managed service is always cheaper. It is not. The point is to show where cost changes shape at 10k, 100k, and 1M URLs, and when the hidden team-cost model matters more than raw compute.
How to: JavaScript rendering cost
- 1
Measure render time by template, not by a single average
Pick a representative sample across your real templates: products, categories, docs, listings, booking inventory, search result pages, and any API-fanout pages. A 2-second average can hide a brutal long tail of 8-15 second renders that drives browser concurrency and timeout policy. Cost modeling based on one happy-path median usually underestimates production load.
- 2
Translate render time into browser-hours and memory pressure
CPU is only half the story. Chrome usually wants 1-2 GB RAM per normal render and more on media-heavy or JS-heavy pages. At 100,000 URLs with 2-second renders, you can estimate the core-hours. But you also need to estimate how many concurrent browsers your peak recrawl window needs and whether memory spikes force you to overprovision. That operational burden becomes clearer on large sites (100k+ pages).
- 3
Add the real infrastructure around the browser pool
A rendering system is not only Chrome. You need job orchestration, retries, failure queues, storage for snapshots, invalidation triggers, cache policy, metrics, and a way to inspect bad output. Cloud providers and edge platforms charge separately for parts of that stack. This is where a DIY Cloudflare or hybrid build starts looking more like a platform product than a script.
- 4
Price the team cost as a real line item
Someone owns incidents. Someone writes invalidation logic. Someone debugs why crawler HTML diverged from the app after a frontend release. Even 0.2 to 0.5 FTE of platform time changes the model fast. That is the hidden cost most spreadsheets ignore, and it is also why this guide should be read next to ostr.io vs Cloudflare.
- 5
Apply a build-vs-buy rule by scale tier
At very low scale, self-hosting can be rational because the browser layer stays simple and the team can tolerate manual fixes. At mid-scale, managed service often wins because cost and ownership complexity rise together. At very large scale, the answer depends on whether you already have a platform function capable of owning rendering as an internal service. If you do not, the apparent savings can disappear into engineering time.
- 6
Re-check the model after the first crawler surge
Do not trust the first quiet month. Re-check after a sitemap expansion, content migration, launch, or AI crawler discovery event. That is when queue lag, browser concurrency, and hidden incident cost surface. The first realistic budget is usually the second one you write.
Monthly cost shape by operating model
Illustrative all-in ranges for April 2026. The point is cost behavior, not one exact number. DIY and hybrid ranges include a partial team-cost allocation because browser systems do not run themselves.
Model | BestTypical monthly cost shape |
|---|---|
| Self-hosted browser pool at 10k URLs | Low compute, low to moderate ownership |
| Self-hosted browser pool at 100k URLs | Moderate compute, meaningful team overhead |
| Cloudflare Workers + external render pool | Lower edge cost, higher ownership complexity |
| Managed pre-rendering service | Higher sticker price, lower operational burden |
| Dedicated internal rendering platform at 1M+ URLs | Can win, but only with real platform ownership |
The cost curve changes shape at 10k, 100k, and 1M URLs
At 10,000 URLs, most teams can keep a DIY browser pool alive cheaply if refresh cadence is slow and the public surface is simple. At 100,000 URLs, the question changes from 'Can we afford compute?' to 'Can we keep freshness, invalidation, and incident response reliable?' At 1M URLs, rendering is no longer a utility task. It is a platform discipline with capacity planning, tiering, and explicit ownership.
That is why two sites with the same URL count can still need different answers. A 100k-site with low volatility and one template family can be easier to self-host than a 30k-site with API-heavy pages, volatile inventory, and aggressive invalidation. URL count matters, but template volatility and ownership burden matter just as much.
The hidden team-cost model is usually bigger than the raw browser bill
The raw browser bill is the number teams love to quote because it looks precise. The hidden team-cost model is fuzzier, so it gets left out. That is a mistake. Platform engineers, SREs, or senior backend engineers end up owning retries, browser version drift, crawler parity checks, queue monitoring, and post-release incidents. Those hours have a cost even if they never appear as a cloud invoice.
In practice, the smaller the team, the more expensive that hidden cost becomes. A large platform group can absorb a rendering subsystem as one more internal service. A startup or mid-market team often cannot without slowing other roadmap work. That is why build-vs-buy is partly an organization design question, not only an infrastructure question.
When self-hosting or hybrid builds actually win
DIY or hybrid setups win when three things are true together: the public surface is either small or extremely large, the team already owns adjacent browser or queue infrastructure, and the business explicitly values control more than simplicity. A team already running browser automation at scale may have enough of the substrate to make rendering comparatively cheap.
The catch is that many teams satisfy only one of those conditions. They already use Cloudflare, for example, but they do not own a browser fleet. Or they already have backend infra, but they do not have clean invalidation events. In those cases the hybrid path can become the most expensive option because it inherits both vendor cost and ownership cost.
When managed service is cheaper even if the cloud bill looks higher
Managed service wins whenever the core problem is not raw rendering, but reliable rendering. If you need event-driven invalidation, predictable freshness, stable crawler HTML, and support during incidents, a service can be cheaper even when the sticker price exceeds raw compute. That is because the service replaces part of the engineering burden rather than only replacing CPUs.
This is most obvious in the middle of the market: not hobby scale, not huge platform-company scale. Teams with 20k-500k meaningful URLs and no dedicated rendering owner are the ones that most often underestimate the cost of keeping the browser layer healthy. That is also where comparisons such as ostr.io vs Vercel SSR become useful, because the real decision is often between two operating models, not between two line items.
Questions engineers ask about this guide
Treating raw CPU as the whole problem. The usual underestimate is ownership: queueing, retries, browser crashes, invalidation, monitoring, and the people who handle incidents.
Usually at the edges. Very small sites can keep it simple enough to justify DIY, and very large platform teams can justify building it as an internal service. The middle is where self-hosting most often looks cheap and turns out expensive.
Because that is where rendering volume, invalidation frequency, and incident load begin to interact. The raw compute can still look manageable, but the operational surface stops being trivial.
Not by itself. Cloudflare can reduce parts of the edge and routing bill, but it does not remove the need for an external browser layer, invalidation logic, and ownership. That is why the full answer lives in [vs Cloudflare](/compare/vs-cloudflare), not in edge pricing alone.
Model at least a fraction of one engineer for setup and ongoing care, then increase that estimate if the site has volatile inventory, complex templates, or release-heavy frontend teams. If the budget assumes zero ownership after launch, it is almost certainly wrong.
When the business needs reliability more than custom control and the team does not already operate browser infrastructure well. In that case the managed fee often replaces a broader operational burden that would otherwise surface unpredictably.
Related guides and deep dives
Compare - vs Cloudflare
Where build-vs-buy economics become concrete.
Compare - vs Vercel SSR
Execution-cost model vs render-pool cost model.
Guide - large sites 100k+
Scale thresholds and tiering once rendering becomes a platform concern.
Technology - dynamic rendering vs SSR
Use this when cost is really an architecture decision.
Guide - headless browser overhead
Deeper operational anatomy of the browser layer.
Guide - crawl frequency signals
Cost only matters if the expensive recrawls are actually useful.
Editorial trust
Written by ostr.io engineering team · Engineering Team. We build and run pre-rendering infrastructure for more than 200 engineering teams, which is where the numbers and code samples on this page come from.
Last updated . Editorial scope and review policy: About prerender.info.