July 2026
·3 min read
Cloudflare Workers vs Pages: Choosing the Right Edge Platform
Cloudflare Workers and Pages both run at the edge — but they have different deployment models, use cases, and limits. Here's how to pick the right one.
Introduction
- Cloudflare runs 300+ edge locations worldwide — Workers and Pages both deploy code to this network.
- The naming is confusing: Pages now supports full-stack via Functions, and Workers can serve static files.
- The real difference is in the deployment and development mental model, not just compute vs static.
Quick Comparison Table
| Cloudflare Workers | Cloudflare Pages | |
|---|---|---|
| Primary use case | APIs, middleware, edge logic | Full-stack web apps, JAMstack |
| Deploy model | wrangler deploy (imperative) | Git push (CI/CD built-in) |
| Static assets | Workers Static Assets (manual) | Automatic from build output |
| Functions | Native (the Worker itself) | Pages Functions (/functions dir) |
| CPU limit | 10ms–50ms (standard) | Same (via Functions) |
| Bundle size | 1MB (free), 10MB (Paid) | Same |
| KV/R2/D1/Durable Objects | Yes | Yes (via bindings) |
| Custom domains | Manual DNS setup | One-click with Cloudflare DNS |
| Preview deployments | Manual | Automatic per branch/PR |
When to Use Cloudflare Workers
- APIs and microservices: low-latency global endpoints, no cold starts.
- Middleware: auth, rate-limiting, geo-routing, request transformation in front of an origin.
- Scheduled tasks: Cron Triggers on Workers replace server-side cron jobs.
- Durable Objects: stateful edge logic (WebSocket rooms, distributed coordination).
- Projects that need granular routing or complex service worker-style request handling.
// workers/api/src/index.ts
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
if (url.pathname.startsWith('/api/posts')) {
const posts = await env.DB.prepare('SELECT * FROM posts').all();
return Response.json(posts.results);
}
return new Response('Not Found', { status: 404 });
},
} satisfies ExportedHandler<Env>;When to Use Cloudflare Pages
- Full-stack web apps: Next.js, Remix, SvelteKit, Astro — deploy with
next-on-pagesor the framework adapter. - JAMstack / static sites: zero config, CDN distribution, automatic branch previews.
- Monorepo with frontend + functions: Pages Functions live in
/functionsalongside your app — onegit pushdeploys both. - Best developer experience for frontend-first projects: Vercel-like UX without leaving Cloudflare.
my-nextjs-app/
app/ ← Next.js app
functions/ ← Pages Functions (optional extra API routes)
api/
webhook.ts
wrangler.tomlThe Convergence: Workers Assets + Pages Functions
- Cloudflare is merging the models: Workers now supports serving static assets directly (Workers Assets, 2024).
- Pages Functions are compiled into Workers under the hood.
- The practical line: use Pages for apps where Git-driven CI/CD and branch previews matter; use Workers for standalone APIs, scheduled tasks, and advanced routing middleware.
Bundle Size Limits and Next.js
- Next.js apps can quickly exceed the 1MB Workers bundle limit on the free plan.
- Mitigation:
next-on-pagessplits routes into separate Workers; each chunk stays under the limit. - Watch for: large dependencies in server-rendered routes (e.g., Shiki for syntax highlighting can be several hundred KB).
- Debug with
wrangler deploy --dry-run --outdir distand inspect chunk sizes.
D1, KV, and R2 Bindings
- KV: key-value store — fast reads globally, eventual consistency. Good for caching, feature flags.
- R2: S3-compatible object storage — zero egress fees. Good for user uploads, static assets.
- D1: serverless SQLite at the edge — relational queries in Workers/Pages Functions.
# wrangler.toml
[[d1_databases]]
binding = "DB"
database_name = "my-app-db"
database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"Local Development
- Workers:
wrangler dev— runs a local miniflare environment. - Pages:
wrangler pages dev ./distor framework-specific adapters. - Both support local bindings (KV, D1, R2) via
wrangler dev --local.
Pricing
- Free plan: 100,000 Workers requests/day; unlimited Pages sites + 500 builds/month.
- Workers Paid ($5/mo): 10M requests/month, 30s CPU time limit.
- Egress is free — Cloudflare's biggest pricing advantage over AWS/GCP/Azure.
Conclusion
- If you're deploying a web app and want Git integration and branch previews → Pages.
- If you're building a standalone API, cron job, or middleware layer → Workers.
- For serious apps: Workers for the API/logic layer, Pages (or Workers Assets) for the frontend — connected via service bindings or standard HTTP.