Why host Next.js on Cloudflare Workers?
Hosting Next.js on Cloudflare Workers gives you low running costs and code that runs close to visitors worldwide, with a database, file storage and image resizing on the same platform. Cloudflare is generally the cheapest of the main frontend hosts, and for new full-stack sites it now recommends Workers over Pages.
We run our own site, designify.design, this way: Next.js and Payload CMS on Workers, with content in D1 and uploads in R2. This guide is what we learned building it, including the parts that took longer than expected. It's not the easiest path to hosting Next.js; for the trade-offs against other hosts, see our website hosting guide for startups and the Vercel vs Netlify vs Cloudflare comparison.
What do you need before deploying Next.js on Cloudflare?
You need a Cloudflare account, the wrangler command-line tool, a Next.js app that doesn't depend on Node-only native libraries, and a decision about which Workers plan you'll use. The free plan works for mostly static sites; anything with real server work, such as a CMS admin, needs the paid plan.
- Check your dependencies. Native Node modules, such as the sharp image library, don't run on Workers. Find replacements before you start.
- Know your rendering. Static and cached pages are cheap and fast. Pages rendered on every request use CPU time on each visit; see static vs server rendering in Next.js.
- Pick the plan. On our own site, the free plan's CPU time per request was far too little for the Payload admin, its API and background page rebuilds.
- Read the official guide. Cloudflare's Workers documentation covers the current Next.js setup.
How do you deploy Next.js on Cloudflare Workers?
You deploy by adding the OpenNext Cloudflare adapter to your project, configuring wrangler, building with the adapter and deploying the resulting Worker. These are the steps we follow.
Install the adapter and wrangler
Add @opennextjs/cloudflare and wrangler to the project. The adapter converts the Next.js build output into a Worker plus static assets.
Configure wrangler
In wrangler.jsonc, set the Worker entry, turn on the nodejs_compat compatibility flag, and add an assets binding pointing at the adapter's assets folder.
Add bindings
Declare the D1 database, R2 buckets and Images binding your site uses, then generate TypeScript types for them.
Configure caching
In open-next.config.ts, choose an incremental cache. We use R2 for cached pages with a regional cache in front.
Preview locally
Build with the adapter and run the Worker locally in workerd, Cloudflare's runtime, before deploying. Plain next dev won't catch Workers-only problems.
Deploy
Run any database migrations first, then build and deploy with the adapter. We script both as one deploy command.
How do you add a database, storage and images?
On Workers you add services through bindings: D1 for an SQLite database, R2 for file storage, and the Images binding for resizing. Each binding appears in your code as an object on the environment, with no connection strings to manage.
Need | Cloudflare service | How we use it |
|---|---|---|
Database | D1 | Payload CMS content, with point-in-time restore |
Uploads | R2 | Images and videos uploaded in the CMS, stored as-is |
Image resizing | Images binding | Resizes uploads on request to AVIF or WebP; replaces sharp |
Page cache | R2 plus regional cache | Stores prebuilt pages for the edge cache |
Backups | R2 and a cron trigger | A nightly copy of every table and upload |
Images need the most thought. Because sharp can't run, we store uploads unchanged and serve them through a media route that resizes on request with the Images binding, saving each size back to R2 the first time it's made. In production the Worker answers media requests itself, before Next.js loads, which keeps them fast.
Deep dive: running Payload CMS on Workers
Payload adds a few extra requirements. Password hashing needed a patch, because Workers caps the PBKDF2 iteration count below what Payload uses by default, so sign-up and login failed until we patched it. GraphQL isn't fully supported on Workers yet, so we disabled it and use the REST and Local APIs.
The build loads the Payload config, which connects to remote D1 and R2 bindings, so builds must run somewhere signed in to Cloudflare or with an API token. We also made the build work without the Payload secret so automated builds can run. And we build with webpack, as Payload's official Cloudflare template does, because the adapter couldn't yet resolve Turbopack's server output. More in our Payload CMS marketing site write-up.
How do you cache Next.js pages at the edge on Cloudflare?
Cache pages by prebuilding them and storing them in the adapter's incremental cache, then letting Next.js revalidate them in the background. Visitors get a cached page; the Worker rebuilds it after content changes without anyone waiting.
On our site, home and case-study pages revalidate after about a minute, so an edit in the CMS shows up shortly afterwards while almost every request is served from cache. We also key the page cache on the deployed version, so a new deploy never serves pages built by old code. Caching is what keeps CPU time, cost and response times low. For the concepts, see CDN and edge caching.
What are the limits of Next.js on Cloudflare?
The main limits are CPU time per request, Worker size, Node compatibility and adapter timing. None stopped us, but each one cost time, and a team without a developer shouldn't take them on alone.
Pros
- Low running costs for typical marketing-site traffic
- Database, storage, images and cron on one platform
- Code and cache close to visitors worldwide
Cons
- The free plan's CPU limit is too small for a CMS admin or heavy server work
- Large apps need the paid plan for Worker size too
- Native Node libraries like sharp don't run
- New Next.js releases wait for adapter support
Plan maintenance with this in mind: Next.js, the adapter and your CMS all move quickly, so upgrades are a regular task. Our guide to Next.js maintenance covers a schedule. If performance is your reason for choosing Cloudflare, remember most Core Web Vitals gains come from the front end, as covered in Core Web Vitals fixes for Next.js sites.
Should you use Cloudflare Pages or Workers for Next.js?
Use Workers for a Next.js site that does any server work, and for new projects in general, since that's where Cloudflare now points full-stack frameworks. Pages still works for fully static exports, where Next.js outputs plain HTML files.
