Every new project I start in 2026 runs on a single provider: Cloudflare. Not “mostly on Cloudflare with Postgres on Neon and Redis on Upstash and email through Resend.” On Cloudflare. Pages, Workers, D1, R2, KV, Durable Objects, Queues, Workers AI, Email Routing, Turnstile, Web Analytics — one bill, one dashboard, one mental model.
That’s a constraint, and the constraint is the point.
Table of contents
Open Table of contents
The story the constraint tells
The traditional story for a new SaaS goes: pick a backend host, pick a database, pick a cache, pick a queue, pick a transactional-email provider, pick a static-site host, pick a CDN, pick an analytics tool, pick an error tracker, pick a feature-flag service. Wire them together. Pay nine invoices. Hope none of the SOC 2 attestations expire on the same day.
The Cloudflare-native story is shorter:
npm create cloudflare@latest my-app
That’s a Worker. Bind a D1 database to it for SQL, a KV namespace for session state, an R2 bucket for blobs, a Queue for async work. Add Workers AI for a model call. Put Pages in front for the marketing site. Email Routing for hello@. Web Analytics for traffic. The whole stack is one wrangler.toml.
I’m not saying every project deserves this stack. I’m saying when it fits, the savings compound.
Where it actually shows up
Three areas where “everything on one provider” pays real dividends:
1. Latency budgets stay sane
The Worker lives at the edge. So does its database (D1 replicas), its cache (KV), and its storage (R2). When a request comes in, it doesn’t bounce across continents to hit a primary in us-east-1. The whole request graph collapses into a single region.
I have one project — a multi-tenant project-management platform — where the median API response is 14ms and the p99 is 60ms. Not because I optimized it. Because the components share a region by default.
2. State sync is somebody else’s problem
Durable Objects are the underrated star. When you need strongly consistent state — a chat room, a lock, a per-tenant counter — you instantiate a Durable Object. Cloudflare handles routing every request for that ID to the same machine. You write code as if there’s a single in-memory instance, because there is.
export class WorkspaceHub {
state: DurableObjectState;
sessions = new Map<string, WebSocket>();
constructor(state: DurableObjectState) {
this.state = state;
}
async fetch(request: Request) {
const pair = new WebSocketPair();
this.state.acceptWebSocket(pair[1]);
this.sessions.set(crypto.randomUUID(), pair[1]);
return new Response(null, { status: 101, webSocket: pair[0] });
}
}
The equivalent on AWS is Lambda + DynamoDB streams + WebSocket Gateway + a careful re-implementation of session affinity. Or it’s a long-lived EC2 box you have to baby. Or it’s a Redis cluster pretending to be a coordinator. Durable Objects are the primitive those tools are trying to be.
3. One log to grep
Every Cloudflare service emits structured logs to Logpush, Workers Logs, and the Tail. When something is broken at 23:00, I open one tail. I don’t correlate request IDs across Vercel, Supabase, Resend, and Sentry. I read one stream.
What you give up
You give up a few things, and it’s worth being honest about them.
- Heavy compute — Workers cap at 30s CPU on the paid plan, and image/video processing isn’t their strength. R2 + a sidecar service handles this for me when it comes up, but it’s not zero work.
- The “official” everything — there’s no Cloudflare Stripe, no Cloudflare Auth0, no Cloudflare AlgoliaSearch. You either use third parties from inside Workers (which is fine) or build the primitive yourself (D1 + a few hundred lines beats hosted auth more often than people admit).
- A specific tool you love — if your favourite is a Postgres extension or a Redis-only feature, you’ll feel the loss. D1 is SQLite; KV is eventually consistent.
These are real trade-offs. For 90% of the SaaS I build, none of them matter.
The compound effect
The reason I keep choosing this stack isn’t any single feature. It’s that every new project gets cheaper. The fifth Worker takes an afternoon. The fifth D1 migration takes a minute. The fifth Pages deploy is wrangler pages deploy dist.
Compound improvement on one platform beats marginal improvement across ten.
In the next post I’ll walk through what my AI-assisted workflow looks like on top of this stack — because the same compound logic applies to tooling.