When building early-stage products, infrastructure choices send immediate signals about team maturity. Over-engineer with Kubernetes and Terraform, and you spend half your runway maintaining cloud control planes. Under-engineer on a $5 virtual private server, and your database corrupts during the first traffic spike.
We settled on an architecture that delivers enterprise resilience at bootstrapped costs: Cloudflare Workers for logic, D1 for SQLite relational storage, R2 for object storage, and Hyperdrive for connection pooling when external Postgres is required.
Why Traditional Serverless Cloud Is Broken
AWS Lambda and Google Cloud Functions introduced a hidden bill tax: egress charges and VPC NAT gateways. Running a small service inside an AWS VPC requires a NAT Gateway costing over $30 monthly before a single request executes. Add S3 cross-region bandwidth fees, and a low-traffic application easily costs $200 per month.
Cloudflare Workers execute on V8 isolates rather than container micro-VMs. Cold starts are under 15 milliseconds globally, and outbound bandwidth on R2 is completely free of egress fees.
The Production Stack Blueprint
Our baseline application template consists of three core components bound directly inside Wrangler configuration:
| Component | Technology | Role in Stack |
|---|---|---|
| Compute | Cloudflare Workers | Global V8 isolate API handlers with automatic failover |
| Database | Cloudflare D1 | Serverless SQLite replicated to the edge with time-travel recovery |
| Storage | Cloudflare R2 | S3-compatible bucket storage with zero egress billing |
| Caching / Session | KV & Durable Objects | Low-latency session tokens and real-time state synchronization |
Structuring the Wrangler Configuration
Keeping environment bindings clean requires explicit TypeScript interfaces. Here is how we configure a typed environment binding in a production Worker:
src/types.tsexport interface Env { DB: D1Database; BUCKET: R2Bucket; SESSIONS: KVNamespace; API_SECRET: string; } export default { async fetch(request: Request, env: Env): Promise<Response> { const session = await env.SESSIONS.get("user-session-id"); if (!session) { return new Response("Unauthorized", { status: 401 }); } const { results } = await env.DB.prepare( "SELECT id, name, email FROM users WHERE org_id = ?" ).bind("org_123").all(); return Response.json({ users: results }); } };
Database Access: D1 vs External Postgres
For 90% of early products, D1 SQLite is fast and simple. Migrations run via wrangler d1 execute inside CI/CD pipelines. When clients require complex relational features like full-text search or PostGIS extensions, we pair Cloudflare Workers with an external PostgreSQL instance via Hyperdrive.
Hyperdrive pools database TCP connections at Cloudflare edge locations, eliminating connection setup overhead that usually slows down serverless SQL queries.
Where This Pattern Fits (and Where It Fails)
Edge serverless is ideal for REST/GraphQL APIs, webhook ingestion, SaaS backends, and multi-tenant applications. However, long-running CPU tasks exceeding 30 seconds should not run in edge isolates; offload heavy background jobs to dedicated queue processors or container services.
For details on how we structure deployment pipelines from day one, see our companion report on our client deployment pipeline.