Chapter 2: Strategic Assessment
Should we adopt the Cloudflare Developer Platform, and what are the implications?
Platform adoption is never purely technical. The architecture you choose must fit team capability, budget cycles, vendor relationships, and incentives. A platform that is technically strong but organisationally incompatible will fail as reliably as one with fundamental technical flaws.
This chapter focuses on the Cloudflare Developer Platform: Workers, Durable Objects, D1, R2, Queues, Workflows, Containers, Realtime, and the primitives covered throughout this book. Cloudflare also offers networking and security products (WAF, DDoS protection, rate limiting, bot management, Zero Trust access), but those serve different architectural decisions and deserve separate evaluation.
The distinction matters because the Developer Platform delivers substantial networking and security benefits automatically. When you deploy a Worker to a custom domain, your application receives Cloudflare's DDoS mitigation, TLS termination, and network optimisation without configuration. Your traffic flows through infrastructure handling billions of attack requests daily. The platform you're evaluating for compute runs on one of the world's most capable security networks.
Understanding what you receive automatically versus what requires explicit enablement shapes both evaluation and architecture. This chapter helps you make that assessment.
The decision in brief
The core framework follows. The rest of the chapter substantiates these recommendations.
Choose Cloudflare when users are globally distributed and latency matters, when you need real-time coordination that would require significant custom infrastructure elsewhere, when egress costs dominate your cloud budget, or when operational simplicity matters more than maximum flexibility. Greenfield projects benefit most by designing for Cloudflare's model from the start.
Choose hyperscalers when you need specific managed services (SageMaker, BigQuery, Cosmos DB), when workloads are compute-intensive rather than I/O-heavy, when your team has deep hyperscaler expertise and time-to-market is critical, or when regulations mandate specific clouds. Significant reserved capacity commitments also shift the economics until they expire.
Choose hybrid when you're migrating incrementally, when different workloads have genuinely different needs, or when risk tolerance requires gradual adoption with rollback capability. Hybrid isn't a compromise; it's often optimal for complex organisations.
Some requirements represent genuine mismatches with Cloudflare's architecture rather than limitations to engineer around. These include: applications requiring more than 128 MB memory per request where Containers' cold starts are unacceptable, workloads needing inbound TCP/UDP connections that bypass HTTP, databases exceeding 10 GB that cannot be horizontally partitioned, or contractual requirements mandating a specific hyperscaler. If any of these apply today, the relevant sections of this book will help you understand why and what alternatives exist. If none apply today, understanding these boundaries helps you recognise when future requirements might push you toward hybrid architectures.
The following sections develop these recommendations with the detail needed to apply them.
The platform in context
Before evaluating workload fit and migration paths, understand what the Developer Platform includes and how it relates to Cloudflare's broader offerings.
What the developer platform comprises
The Developer Platform includes the compute and storage primitives you deploy and operate:
- Workers: Core compute executing JavaScript, TypeScript, Python, and WebAssembly at the edge
- Durable Objects: Stateful coordination through globally-unique, strongly-consistent actors
- D1, R2, KV: Storage for structured data, objects, and key-value pairs
- Queues and Workflows: Asynchronous processing and durable execution
- Containers: Extended compute for workloads exceeding isolate constraints
- Workers AI and Vectorize: Inference and vector storage for intelligent applications
- Workers for Platforms: Multi-tenant isolation for platform builders
These primitives share a deployment model, billing model, and operational philosophy. They compose through bindings and represent the compute layer you architect upon.
What comes bundled
Deploying on the Developer Platform automatically provides capabilities that would require separate products, configuration, and cost on other platforms.
DDoS protection operates continuously on all traffic reaching your Workers. Cloudflare's network absorbs volumetric attacks before they reach your code. The same systems protecting the world's largest websites protect your application from deployment. Enterprise customers gain additional controls and analytics, but core protection works for everyone.
TLS terminates automatically with certificates provisioned and renewed without intervention. Your Workers receive requests over HTTPS; certificate management complexity disappears.
Network optimisation happens transparently through Cloudflare's Anycast network. Requests route to the nearest data centre, traverse Cloudflare's backbone where beneficial, and reach your code with lower latency than the public internet provides. Argo Smart Routing compounds this if enabled, but baseline performance already exceeds direct routing to origin servers.
Global distribution requires no configuration. Deploy once and your code runs in over 300 locations. The alternative (replicating infrastructure across AWS regions, configuring multi-region databases, implementing failover logic) represents weeks of engineering and ongoing operational burden. On Cloudflare, it's the default.
Basic bot protection applies automatically. Advanced bot management requires additional products, but Cloudflare's network fingerprints and blocks obvious malicious automation.
These capabilities aren't upsells positioned as standard; they're architectural consequences of building on Cloudflare's network. Traffic to your Workers traverses Cloudflare infrastructure, which includes DDoS mitigation, TLS termination, and network optimisation by design.
The strategic implication: evaluating the Developer Platform purely on compute and storage undersells the value. You're also acquiring networking and security infrastructure that would otherwise require separate evaluation, negotiation, and operational investment.
What requires additional products
Some enterprise requirements exceed what the Developer Platform provides automatically.
Web Application Firewall (WAF) provides application-layer protection beyond basic DDoS mitigation: OWASP ruleset enforcement, custom rules blocking specific attack patterns, and managed rules updated for emerging threats. Many applications operate safely with bundled protections; those handling sensitive data or facing sophisticated attackers benefit from explicit WAF deployment.
Advanced rate limiting operates at the Cloudflare edge with granular controls. Chapter 22 discusses implementing rate limiting within Workers using KV or Durable Objects, which suits many use cases. For edge-level rate limiting with complex rules, geographic conditions, and threat intelligence integration, Cloudflare's rate limiting products exceed what you'd build yourself.
Bot Management distinguishes sophisticated automated traffic from legitimate users through fingerprinting, machine learning, and behavioural analysis. Bundled protections block obvious bots; Bot Management handles credential stuffing, inventory hoarding, and advanced scraping evading simple detection.
Access and Zero Trust control who reaches your applications based on identity, device posture, and context. If your Workers serve internal tools, administrative interfaces, or B2B applications with controlled user populations, Access policies enforce authentication before requests reach your code.
The distinction isn't quality; bundled capabilities are genuinely valuable and would cost significantly elsewhere. The distinction is scope: bundled capabilities provide broad automatic protection, while dedicated products offer depth for specific threat models.
For most applications, bundled capabilities suffice. Applications with heightened security requirements should factor additional Cloudflare products into evaluation. They integrate seamlessly with the Developer Platform and often prove simpler than third-party alternatives.
Workload fit
Cloudflare's architecture favours globally distributed, I/O-heavy, coordination-intensive workloads. It's less suited to memory-hungry, compute-bound workloads or those tightly coupled to hyperscaler services.
Workloads that thrive
The platform's sweet spot becomes clear once you understand the underlying model.
API backends with global users eliminate multi-region complexity consuming engineering time on hyperscalers. Each request executes at the edge closest to the user; deploy once and it's everywhere. No region failover to design, no cross-region replication to manage, and no latency variance to explain to users in different geographies. APIs deployed on Cloudflare also inherit the network's security posture: volumetric DDoS attacks dissipate against Cloudflare's network before reaching your code.
Latency-sensitive authentication benefits disproportionately from edge execution. Every millisecond of auth latency multiplies across your entire application. Moving token validation, permission checks, and session management to the edge removes a round-trip to a centralised server. A JWT validation adding 200ms in us-east-1 becomes a 5ms operation at the edge.
Real-time coordination and collaboration find their natural home in Durable Objects. The globally-unique, single-threaded actor model with strongly-consistent state provides capabilities requiring significant custom infrastructure on hyperscalers. Multiplayer games, collaborative documents, live auctions, and presence systems (anything requiring coordination across distributed clients) can be built with primitives rather than assembled from disparate services. A collaborative design tool with real-time updates requires Redis clusters and careful distributed systems engineering on hyperscalers. With Durable Objects, the consistency guarantees are built in.
I/O-heavy orchestration exploits the billing model's deepest advantage. API aggregation, webhook processing, and service composition spend most of their time waiting on external calls. Cloudflare's pricing favours workloads that wait; you pay for waiting on hyperscalers but not on Cloudflare. A Worker making five API calls and waiting 500ms might consume only 10ms of billable CPU time.
Multi-tenant SaaS platforms benefit from horizontal scaling patterns matching the platform's design. The database-per-tenant pattern aligns naturally with D1's architecture. Rather than fighting a 10 GB limit on a single database, embrace thousands of isolated tenant databases, each well under the limit with natural isolation boundaries. Workers for Platforms extends this to tenant-specific code execution.
AI-powered applications with global users can run inference at the edge rather than routing to centralised GPU clusters. Workers AI, Vectorize, and RAG patterns serve intelligent responses from edge locations: embedding generation, vector search, and response generation all happen close to the user.
Workloads that struggle
These constraints are hard, not soft. Understanding them prevents costly discoveries in production.
Memory-intensive processing hits the 128 MB isolate limit without recourse. Image manipulation libraries buffering entire images, data processing loading large datasets into memory, and ML inference with substantial model sizes cannot run in Workers. Containers offer up to 12 GB but introduce cold-start latency measured in seconds. If your workload routinely needs more than 128 MB and cannot tolerate those cold starts, you need different infrastructure.
Long-running computation exceeds the 5-minute CPU time limit on paid plans. Video transcoding, complex simulations, scientific computing, and batch processing requiring sustained compute beyond this threshold need hyperscaler compute or dedicated infrastructure. Note: this limit is CPU time, not wall time. A process running for an hour but computing for only four minutes fits fine.
Single large databases conflict with D1's architectural assumptions. The 10 GB-per-database limit exists by design, guiding you toward horizontal patterns. If your application genuinely requires a monolithic relational database with complex joins across hundreds of gigabytes, D1 won't work, but Cloudflare still can. Hyperdrive accelerates connections to external PostgreSQL or MySQL databases, providing connection pooling and query caching at the edge. Many production systems run permanently with Workers connecting to external databases via Hyperdrive. You're operating that external database with its associated complexity, but you're also gaining edge compute benefits for your application logic.
Inbound TCP/UDP connections don't fit the model. Cloudflare's architecture is HTTP-centric. Game servers expecting direct UDP connections, IoT protocols using custom TCP, and applications requiring raw socket access cannot use Workers or Containers. You need traditional cloud infrastructure for network ingress, though Cloudflare can add value at other layers.
Assessing your workloads
For each significant workload, assessment reduces to key questions.
Memory envelope? Under 50 MB typical means excellent fit; 50-100 MB is workable with care; over 100 MB means Workers won't work. Evaluate Containers or look elsewhere.
Compute profile? Under one second of CPU time per request is ideal; under thirty seconds is workable; over thirty seconds needs Containers, Queues (whose consumers have no CPU limit), or hyperscaler compute.
Where are your users? Global or distributed users benefit from edge execution. Users concentrated in one region see less advantage, though operational simplicity may still justify adoption.
Where are your backends? If your Worker calls a database in us-east-1 for every request, you've reintroduced the latency you were trying to eliminate. Smart Placement helps by running Workers near backends, but the architecture works best when backends are distributed, latency-insensitive, or on Cloudflare itself.
What protocols? HTTP and WebSocket fit perfectly; custom TCP/UDP protocols don't fit at all.
Need real-time coordination? Durable Objects provide capabilities unavailable elsewhere without significant custom work. This alone can justify adoption even if other factors are neutral.
A workload doesn't need perfect scores to succeed on Cloudflare, but multiple poor-fit dimensions signal you'll fight the platform rather than benefit from it.
Which of your current workloads would benefit most from edge execution, and which suit centralised compute? The answer often reveals that hybrid architecture is optimal rather than a compromise.
Translating hyperscaler experience
Engineers from AWS, Azure, or GCP carry accumulated intuitions about cloud platforms. Some translate directly; others require deliberate unlearning. This section maps familiar hyperscaler concepts to Cloudflare equivalents, highlights where mental models differ fundamentally, and identifies patterns that don't apply.
The concept map
| Hyperscaler Concept | Cloudflare Equivalent | Key Difference |
|---|---|---|
| Lambda / Azure Functions | Workers | Sub-millisecond cold starts; no provisioned concurrency needed |
| API Gateway | Workers Routes | Integrated into compute; no separate service or pricing |
| DynamoDB / Cosmos DB | D1 + Durable Objects | D1 for relational queries; Durable Objects for coordination |
| S3 / Blob Storage | R2 | Zero egress fees; S3-compatible API |
| ElastiCache / Redis | KV (caching) or Durable Objects (coordination) | KV for eventual consistency; DO for strong consistency |
| Step Functions / Durable Functions | Workflows | Simpler model; automatic retry and state persistence |
| SQS / Service Bus | Queues | Integrated with Workers; no visibility timeout complexity |
| ECS / Container Apps | Containers | Must route through Workers; no direct inbound connections |
| CloudFront / Front Door | Built-in | Every Worker deployment includes global CDN automatically |
| WAF / Shield | Built-in (basic) or WAF product | DDoS protection included; advanced WAF separate |
| Secrets Manager | Workers Secrets | Encrypted at rest; accessed via environment bindings |
| CloudWatch / Monitor | Logpush + Analytics Engine | No automatic log persistence; explicit export required |
Cold starts: the non-problem
Lambda cold starts have spawned an industry of mitigation strategies: provisioned concurrency, SnapStart, keep-warm pings, careful dependency management. Azure Functions offers similar workarounds through Flex Consumption's always-ready instances.
Workers eliminate this problem category. The V8 isolate model initialises in under a millisecond because the runtime is already loaded. Your code loads into an existing process rather than spawning a new one. No provisioned concurrency because there is no cold start worth provisioning against. No SnapStart equivalent because there is no initialisation latency worth snapshotting.
This isn't a small improvement. It's a fundamental difference removing an entire category of architectural concern. If you're designing for Workers and thinking about warm-up strategies, step back. You're solving a problem that doesn't exist here.
Connection management: the disappeared problem
Traditional serverless architectures struggle with database connections. Lambda functions spin up independently, each wanting its own connection, quickly exhausting database connection limits. Solutions include RDS Proxy, PgBouncer, connection pooling layers, and careful timeout tuning.
Cloudflare's binding model eliminates this for platform-native storage. D1, KV, R2, and Durable Objects use bindings the platform manages, not connection pools. Your code references env.DB and the platform handles everything else: no connection string, no pool size to tune, no connection exhaustion to monitor.
For external databases, Hyperdrive provides connection pooling at the edge. You configure once; the platform manages globally. The mental shift: connections become someone else's problem for native storage, and a simpler problem for external databases.
Regional architecture: the inverted model
Hyperscaler architecture starts with a region decision: which region hosts primary infrastructure, which need replicas, how to handle failover. Multi-region deployment is an advanced pattern requiring explicit design.
Cloudflare inverts this. Global deployment is the default: deploy once and code runs everywhere. The advanced pattern is restricting deployment to specific jurisdictions for compliance, not expanding it to multiple regions for performance.
This inversion affects data locality thinking. On hyperscalers, you choose where data lives and accept latency for distant users. On Cloudflare, D1 databases place themselves based on creation location, with read replicas distributing globally automatically. Durable Objects place themselves near the first user accessing them. The platform optimises locality; you design for it rather than implementing it.
Smart Placement further inverts expectations. Instead of running compute near users and accepting backend latency, Smart Placement runs compute near backends when that produces better total latency. You enable it with configuration, not architecture.
The services that don't exist
Some hyperscaler services have no Cloudflare equivalent because the need they address doesn't exist or manifests differently.
NAT Gateway: Workers have outbound internet access by default. No VPC to escape, no NAT to provision, no hourly charge accumulating invisibly.
Load Balancer: The Anycast network routes requests to the nearest available location automatically. Load balancing is inherent to the deployment model.
Auto Scaling Configuration: Workers scale instantly to any load without configuration. No scaling policy, no minimum or maximum instance count, no target tracking.
Container Orchestration: Containers exist but don't require orchestration in the Kubernetes sense. Deploy a container; the platform runs it. No cluster to manage, no node pools to size, no pod specifications.
Service Mesh: Worker-to-Worker communication uses service bindings with RPC semantics. No sidecar proxy, no service mesh control plane, no traffic policies. Bindings provide type-safe communication without network configuration.
These absences aren't gaps; they're consequences of the model. When the platform handles distribution, load balancing, and scaling inherently, services configuring those concerns become unnecessary.
Pricing model translation
Hyperscaler serverless pricing typically combines request charges, duration charges, and memory allocation. Lambda charges per GB-second (memory multiplied by duration). API Gateway adds per-request fees. Data transfer adds egress fees.
Cloudflare's model differs in ways affecting cost intuition.
CPU time, not wall time: Workers charge for CPU milliseconds, not elapsed time. A request waiting 500ms for external APIs but computing for 5ms pays for 5ms. On Lambda, you'd pay for 500ms. I/O-heavy orchestration becomes dramatically cheaper, though compute-heavy workloads don't benefit.
Zero egress: R2 charges nothing for data leaving the platform. If egress exceeds 20% of your current cloud bill, this single factor may dominate all other comparisons.
No API Gateway equivalent: Workers handle HTTP routing directly. No separate API Gateway service with its own per-request pricing; compute includes what hyperscalers charge separately for routing.
Usage-based storage queries: D1 charges per rows read and written, not per provisioned capacity unit. Costs align with actual usage but require different capacity planning: you're forecasting query patterns, not instance sizes.
Patterns that transfer
Not everything requires unlearning.
Presigned URLs for direct upload: R2 supports presigned URLs with S3-compatible APIs. Existing client-side upload patterns work unchanged.
Event-driven processing: Queues trigger Workers just as SQS triggers Lambda. The consumer pattern is familiar; only configuration syntax differs.
Scheduled execution: Cron Triggers work like CloudWatch Events or Azure Timer Triggers. Specify a cron expression; the platform invokes your code.
Environment-based configuration: Workers Secrets and environment variables work like Lambda environment configuration. Sensitive values encrypted, non-sensitive plaintext. The binding model provides type-safe access, but the concept is familiar.
Infrastructure as code: Wrangler configuration files serve the same purpose as CloudFormation or Terraform. You can also use Terraform with the Cloudflare provider if that's your team's standard.
What requires rethinking
Several patterns require fundamental rethinking rather than direct translation.
Actor-based coordination stands out as Cloudflare's most distinctive capability. Durable Objects have no direct hyperscaler equivalent. The closest patterns (Step Functions with DynamoDB, Durable Functions with entity functions, self-managed Orleans) require multiple services and significant custom code. If your application needs coordination, Durable Objects likely replace an entire architectural layer you'd otherwise build from components.
Horizontal database scaling: D1's many-small-databases model differs from RDS's scale-up approach or DynamoDB's horizontal sharding. If you're used to one database handling everything, shifting to database-per-tenant requires rethinking data architecture, not just translating configuration.
Edge-first AI: Workers AI runs inference at the edge, not in centralised GPU clusters. The latency profile differs from Bedrock or Azure OpenAI. Model selection differs too: Workers AI runs open-source models Cloudflare hosts, not proprietary models from OpenAI or Anthropic (though AI Gateway can proxy to external providers).
The economics
The sticker price of any cloud platform misleads. Real cost includes direct charges, indirect operational overhead, and savings through architectural efficiency.
How Cloudflare charges
Workers charge for requests and CPU time. The paid plan ($5/month base) includes 10 million requests and 30 million CPU-milliseconds monthly. Beyond that, you pay $0.30 per million requests and $0.02 per million CPU-milliseconds.
Storage services add costs. D1 charges per rows read and written plus storage. R2 charges for storage and operations but zero egress. KV charges for reads, writes, and storage. Durable Objects charge for requests, duration, and storage.
The free tier (100,000 requests daily, 10ms CPU time per request) suffices for development and low-traffic applications but doesn't represent production capabilities.
What hyperscalers actually cost
Hyperscaler pricing appears straightforward until you deploy. The compute cost you model is rarely what you pay.
Egress fees compound invisibly. AWS charges $0.09 per GB leaving a region. An API serving 1 TB monthly pays $90 in egress alone, before compute, storage, or anything else. Organisations often discover egress costs only when the bill arrives. R2's zero-egress model eliminates this category.
NAT Gateway fees accumulate for VPC-connected functions. Lambda functions requiring external connectivity through NAT Gateway pay $0.045 per hour plus $0.045 per GB processed. A moderately active architecture processing 100 GB monthly through NAT pays approximately $40/month, rarely appearing in initial estimates.
Cold start mitigation isn't free. Provisioned concurrency eliminates Lambda cold starts but charges continuously for provisioned instances. Keeping 10 instances warm at 1 GB memory costs approximately $50/month regardless of usage. Workers' sub-millisecond cold starts eliminate this cost category.
Cross-AZ traffic charges for every internal interaction. Communication between availability zones costs $0.01 per GB in each direction. Architectures with load balancers, databases, and compute in different AZs pay for internal traffic that appears free until you examine the bill.
Reserved capacity commits regardless of usage. Reserved instances and savings plans reduce per-hour costs but lock you to capacity regardless of demand. Traffic dropping 50% still costs 100% of your reserved commitment.
A representative comparison
Consider an API workload handling 50 million requests monthly with 20ms average CPU time per request, a 10 GB database, and 500 GB of data served monthly.
AWS breakdown:
- Lambda compute: 50M requests × 20ms × 128 MB ≈ 12,500 GB-seconds = $2.50 (beyond free tier); minimum charge considerations bring this to ~$17
- API Gateway: 50M requests × $3.50/million = $175
- DynamoDB: 10 GB storage ($2.50) + read/write capacity (~$22) = ~$25
- S3 storage: 10 GB × $0.023/GB = $0.23
- S3 egress: 500 GB × $0.09/GB = $45
- CloudWatch: Logs, metrics, dashboards = ~$15
- Total: ~$280/month
Cloudflare breakdown:
- Workers: Base $5 + (50M - 10M requests) × $0.30/million + 1B CPU-ms × $0.02/million = ~$35
- D1: 10 GB storage ($0.75) + row operations (~$14) = ~$15
- R2 storage: 10 GB × $0.015/GB = $0.15
- R2 egress: 500 GB × $0 = $0
- Total: ~$50/month
For I/O-heavy workloads, Cloudflare typically costs 70-80% less than AWS. The savings come from two sources: no API Gateway equivalent (Workers handle routing) and zero egress fees from R2. The gap widens with higher egress volumes and narrows with compute-intensive workloads.
Cloudflare costs roughly 80% less for this workload profile. The $225/month difference stems from two factors: API Gateway's per-request pricing ($175 versus Workers' ~$17) and R2's zero egress ($45 saved).
The gap widens with egress volume: at 2 TB monthly, AWS adds $180 while Cloudflare adds $0. The gap narrows for compute-intensive workloads; at 100ms average CPU time, Workers' CPU charges climb to ~$85 while Lambda's increases modestly.
When Cloudflare isn't cheaper
Cost advantages disappear in predictable scenarios.
Compute-intensive workloads consuming hundreds of milliseconds of CPU time per request pay for that computation. Workers' per-CPU-millisecond pricing becomes expensive for sustained computation. Lambda's per-GB-second model may cost less for workloads needing significant memory but modest CPU.
Very low traffic doesn't amortise the $5/month base cost. A Lambda function handling 10,000 requests monthly might cost pennies; the same on Workers costs at least $5.
Heavy hyperscaler service integration can make adding Cloudflare more expensive. If you're using AWS services charging for external access (RDS data transfer, cross-account SQS messaging, Kinesis streaming), Cloudflare as a front layer may increase total cost.
Existing reserved commitments represent sunk costs. Organisations with multi-year reserved instance or savings plan commitments don't recoup that investment by migrating. Hyperscaler compute is effectively cheaper until those commitments expire.
Modelling your own costs
The representative comparison illustrates dynamics but doesn't tell you your costs. To model your situation, gather these data points:
Monthly request volume drives base Workers cost directly.
Average CPU time per request: if unknown, instrument a sample. The ratio of CPU time to wall time determines whether Cloudflare's billing model advantages you.
Current egress volume is often buried in bills or unknown entirely. It's the largest hidden cost on hyperscalers and the largest potential saving with R2.
Cold start mitigation costs: provisioned concurrency, pre-warmed Lambdas, over-provisioned containers all disappear with Workers.
Operational overhead: multi-region deployment, capacity planning, scaling policy tuning, cold start debugging consume engineering time. This cost doesn't appear on cloud bills but is real.
With these numbers, construct a comparison meaningful for your situation rather than relying on representative examples.
Lock-in and portability
Switching costs exist with any platform. Understanding them enables informed commitments rather than accidental ones. Lock-in is proportional to differentiation: the features hardest to leave are the features you can't get elsewhere.
Accept lock-in proportional to the value it creates. The features you can replicate elsewhere impose low lock-in cost; those you cannot should deliver value justifying the switching costs if you ever need to leave.
What travels with you
Application logic ports readily. Workers use standard JavaScript and TypeScript with Web APIs. Business logic (request handling, data transformation, algorithmic code) runs elsewhere with modest adaptation.
R2 data extracts via standard S3 tools. The S3-compatible API means your data isn't trapped. You can migrate to any S3-compatible storage using tools you already know.
D1 data exports as SQLite. Schemas and data move to any SQLite-compatible database. The data model is standard; only the runtime is Cloudflare-specific.
Queue message formats are your own. The semantics (at-least-once delivery) are standard. Migrating means implementing equivalent consumers elsewhere, not reformatting messages.
What requires rewriting
Durable Objects have no direct equivalent elsewhere. The globally-unique, single-threaded actor model with output gating is Cloudflare's most distinctive offering and its deepest lock-in. Migrating requires redesigning coordination patterns around external Redis, DynamoDB, or custom solutions. This is an architecture change, not configuration.
Binding semantics don't exist elsewhere. The env.RESOURCE pattern for resource access is Cloudflare-specific. Code heavily dependent on bindings needs modification, though changes are mechanical rather than architectural.
Workers-specific APIs require alternatives. HTMLRewriter for streaming HTML transformation, specific caching APIs, and other Cloudflare-native features need replacement. These are typically small codebase portions but require attention during migration.
The global deployment model doesn't port. Architectures assuming instantaneous global deployment need rethinking for hyperscalers' regional models. This is a design assumption affecting application structure.
Calibrating your tolerance
Lock-in correlates with feature depth. Stateless Workers for APIs create low lock-in with moderate migration effort. D1 for CRUD applications increases lock-in slightly. R2 for storage creates minimal lock-in due to S3 compatibility. Durable Objects for coordination create high lock-in with high migration effort but deliver capabilities unavailable elsewhere. Workers for Platforms for multi-tenant architectures creates very high lock-in.
The question isn't whether to accept lock-in but how much value justifies it. Durable Objects' lock-in reflects genuine differentiation: capabilities you cannot replicate without significant custom infrastructure. That lock-in buys something real.
Accept lock-in consciously, understanding what you're trading for what you're getting. Accidental lock-in (discovering dependencies you didn't know you'd created) is the risk to avoid. Intentional lock-in for genuine value is often the right choice.
Team readiness
Technology decisions are ultimately team decisions. A platform your team cannot effectively use proves worse than a theoretically superior platform mismatched to existing skills, no matter how elegant the architecture.
What transfers
JavaScript and TypeScript proficiency transfers directly. Workers use standard Web APIs that frontend developers already know and backend developers learn quickly.
The deployment model transfers by being simpler than what hyperscaler developers expect. No IAM policies to configure, no VPCs to create, no security groups to manage. Write code, run wrangler deploy, and it's live globally. Teams accustomed to complex deployment pipelines often find this disorienting; they keep looking for steps that don't exist.
HTTP fundamentals transfer completely. Request/Response patterns, headers, status codes, caching semantics are all standard. Teams comfortable with web protocols are equally comfortable with Workers.
What requires learning
Durable Objects demand a mental model shift. The single-threaded, globally-unique actor pattern is unfamiliar to developers who haven't worked with actor systems. The "one object per entity" design (one object per user, per document, per game session) feels counterintuitive to those trained to minimise resource creation. Chapter 6 addresses this comprehensively; budget for learning time.
The binding model replaces infrastructure-as-code. Teams accustomed to Terraform or CloudFormation find wrangler.toml surprisingly minimal. Resources connect through configuration rather than infrastructure graphs. Simpler but different, and "different" requires adjustment even when "simpler" applies.
Testing distributed edge systems requires new practices. The execution model differs between local development and production. Behaviours working in wrangler dev may differ at the edge. Chapter 5 addresses this; teams need testing practices beyond what hyperscaler serverless required.
Observability tooling is less mature. Cloudflare provides logging, analytics, and basic tracing, but the ecosystem is younger than CloudWatch or Datadog's deep integrations. Teams with sophisticated observability requirements may need custom tooling or must accept gaps.
Predicting your ramp-up
Several factors predict whether teams ramp quickly or struggle.
Prior serverless experience accelerates learning. Teams that have built on Lambda understand the stateless, event-driven model. Specific APIs differ, but the mental model transfers.
Actor model exposure dramatically accelerates Durable Objects adoption. Teams familiar with Orleans, Akka, or Erlang grasp Durable Objects immediately; teams without this background face a steeper curve.
Frontend-heavy teams often adapt faster than backend-heavy teams. The Web API foundation (fetch, Request, Response) is more familiar to frontend developers than the Node.js patterns backend developers expect.
Strong testing culture predicts success. Teams investing in automated testing adapt their practices. Teams relying on manual testing or "deploy and pray" struggle with edge systems where bugs affect all users instantly.
Tolerance for less mature tooling matters. Teams expecting enterprise-grade observability, debugging, and operational tooling will find gaps.
Ramp-up takes longer than adopting a new library but shorter than adopting Kubernetes. Expect two months to basic proficiency and four to six months to architectural confidence. Teams with actor model experience or strong serverless backgrounds may move faster.
Who feels the consequences
Platform adoption health depends on feedback loops. When people making architectural decisions experience operational consequences, architecture improves. When they don't, problems accumulate until someone else must solve them.
Consider how team structure maps to operational concerns. Who monitors cost? If developers deploy without cost visibility, expensive patterns proliferate until finance complains. Who investigates latency anomalies? Global distribution means latency varies by user location; someone must understand why São Paulo users experience different performance than Singapore users. Who responds to errors? The team writing code should understand how failures manifest.
Teams where developers carry operational responsibility (formal SRE practices or on-call rotations) adopt new platforms more successfully. The feedback loop between "I deployed this" and "I got paged for this" creates incentives for careful work. Teams where operations is someone else's problem often discover that "someone else" doesn't understand the new platform well enough to operate it.
Structure adoption so consequences flow back to decision-makers. This isn't about blame; it's about learning. The fastest path to platform expertise is feeling the results of your choices directly.
Building adoption momentum
Platform adoption rarely happens in a single decision. Teams start with pilot projects, demonstrate success, and gradually expand scope. This incremental pattern is sensible for risk management but creates a momentum challenge: each phase requires renewed organisational commitment, and lost momentum is difficult to recover.
The hardest adoption problems aren't technical; they're organisational. A successful pilot can fail to expand if stakeholders lose interest, competing priorities absorb the team, or early advocates leave. Understanding what builds and kills momentum helps you navigate these dynamics.
What builds momentum
Start with a measurable win. Choose a pilot project with clear success metrics mattering to stakeholders beyond your immediate team. "Reduced p99 latency from 200ms to 15ms" compels more than "successfully migrated"; "Eliminated $8,000/month in egress costs" resonates with finance in ways "adopted modern architecture" cannot. The metric needn't be dramatic, but it must be real and matter to someone with budget authority.
Choose low-dependency workloads first. Pilot projects with minimal connections to other systems move quickly. A standalone API, new microservice, or edge function not requiring coordination with legacy systems lets you demonstrate value without integration complexity. Quick success builds credibility for harder migrations. Starting with your most entangled system, reasoning that success there proves everything, often produces a slow, complex project making fair evaluation difficult.
Make progress visible. Share metrics, dashboards, and cost comparisons regularly. Invisible progress is indistinguishable from no progress. This visibility also protects against organisational memory loss: when your executive sponsor changes roles, their replacement needs to understand why this investment is happening.
Celebrate small wins publicly. Platform adoption is a long game requiring sustained motivation. Recognising milestones (first production deployment, first cost savings, first performance improvement) maintains team energy and organisational attention.
What kills momentum
Waiting for complete parity. If migration is blocked until the new system does everything the old system does, migration never completes. Legacy systems accumulate features over years; expecting to replicate all before declaring success sets an impossible bar. Define acceptable scope reductions and timeline them explicitly. Some features may never migrate, and that's often fine.
Silent parallel runs. Running old and new systems in parallel without visible comparison metrics makes the new system a cost without demonstrated benefit. Parallel operation is often necessary for safety, but it must produce evidence. Instrument both systems, compare behaviour, share results. Otherwise the new system is just an expense line item.
Scope creep disguised as improvement. "While we're migrating, let's also add these features" turns migrations into multi-year projects losing executive patience and team morale. Complete the migration first; improve second. The discipline to defer enhancements, even obviously good ones, keeps migrations on track.
History of failure. Organisations with previous failed platform adoptions face deep scepticism. Teams have seen initiatives start with enthusiasm and end with quiet abandonment. Overcoming this requires demonstrating quick, tangible value proving this time is different. You cannot argue away scepticism; you can only show results making it untenable.
Protecting momentum
Minimise approval gates. Each multi-stakeholder approval is an opportunity for delay, competing priorities, and lost attention. Where possible, frame adoption within existing programmes, budgets, or architectural standards: "Extending our edge capability" encounters less friction than "adopting a new platform."
Calculate and communicate opportunity costs. The cost of not migrating is invisible by default; you're already paying it, so it feels like baseline. Make it visible: what engineering time goes to managing cold starts, multi-region deployment, or capacity planning? What features aren't being built because the team is maintaining infrastructure? What customers are you losing to latency you could eliminate? These opportunity costs, presented in business terms, make the case when competing priorities arise.
Build coalitions beyond your immediate team. Platform adoption depending on a single advocate is fragile. If that person leaves, gets promoted, or gets busy with other priorities, momentum collapses. Cultivate stakeholders across the organisation: finance people caring about cost savings, product people caring about latency, operations people caring about simplicity. Distributed advocacy survives personnel changes.
Migration realities
Migration is where theoretical benefits meet practical friction. Understanding what makes migrations hard (not just what steps to follow) determines whether yours succeeds. This section covers strategic thinking. Chapter 25 provides detailed playbooks for specific scenarios including S3 to R2, Lambda to Workers, and container migrations.
Interrogate your requirements first
Before mapping Lambda to Workers or DynamoDB to D1, ask: what problem was this system actually solving?
Systems accumulate features, workarounds, and cargo-cult patterns. Not all serve the original purpose. Migration is an opportunity to shed accumulated complexity, but only if you define success through outcomes rather than feature parity.
Instead of "migrate our user service from Lambda to Workers," try "achieve sub-50ms authentication response times globally." Instead of "replicate our DynamoDB schema in D1," try "support 10,000 concurrent users with consistent read-after-write semantics." These framings licence your team to use Cloudflare's primitives as designed rather than contorting them to match AWS patterns.
Ask your team: if we were building this today with no legacy constraints, would we build it this way? The answer is often no, and migration is your chance to act on that knowledge.
This reframing has practical benefits. When success is defined by outcomes rather than feature parity, teams make autonomous decisions about implementation without constant approval cycles. "Does this help us hit sub-50ms latency?" is a question engineers can answer themselves. "Does this exactly replicate what Lambda did?" requires archaeology into decisions nobody remembers making.
The fundamental challenge
Data migration is where timelines fail. Teams budget months for code and weeks for data; they should budget the reverse.
Code migration is largely mechanical: handlers rewrite to new APIs, logic transfers with syntax changes, and tests adapt to new mocking patterns. The work is tedious but predictable. Estimate by counting handlers and measuring complexity.
Data migration is unpredictable because your data contains surprises: edge cases code never handled, implicit assumptions never documented, format inconsistencies accumulated over years, referential integrity existing only in application code. Data migration surfaces these; code migration doesn't.
Running parallel systems with data synchronisation compounds complexity. Dual writes must handle failures on either side. Consistency windows create edge cases. Cutover timing affects users. The longer you run parallel, the more edge cases you discover, and the more you need to run parallel to handle them.
Map the overgrowth before you cut
Every system operating for more than a year has accumulated dependencies you don't know about. Some are documented in code; many aren't. Before beginning migration, discover what your system actually depends on, not just what you think it depends on.
Timing assumptions hide everywhere. Does your code assume specific latency ranges for database queries, queue processing, or external API calls? Cloudflare's global distribution may violate these. A process assuming "database queries return in under 10ms" may behave incorrectly when Smart Placement puts your Worker in Frankfurt while your backend remains in Virginia.
Consistency assumptions deserve particular attention. KV provides eventual consistency; writes can take up to 60 seconds to propagate globally. Code reading immediately after writing may see stale data. D1 supports transactions within a single database, but not across databases or between D1 and R2. Chapter 11 maps these guarantees precisely; the strategic implication is simpler: audit what your code assumes and verify those assumptions hold in the new environment.
SDK behaviours don't transfer. The AWS SDK's automatic retry with exponential backoff doesn't exist in fetch calls to external services. You'll need to implement it yourself or accept different failure modes.
IAM patterns need consolidation. Authorisation logic distributed across IAM policies, resource policies, and application code must consolidate into Workers-native patterns or Cloudflare Access rules.
Filesystem assumptions fail immediately. Workers don't have filesystems. This sounds obvious, but filesystem usage hides remarkably often in dependencies, logging libraries, or configuration loaders.
The goal isn't eliminating all dependencies before migration; that's rarely practical. The goal is knowing what they are, so surprises become planned transitions rather than emergency debugging sessions.
Migrating from Lambda and DynamoDB
Difficulty correlates directly with how deeply you've used DynamoDB's patterns.
Teams estimate migration time by counting Lambda functions, then discover data model translation takes 3x longer than expected. Assess DynamoDB access patterns first: GSIs, sparse indexes, and composite keys require schema redesign surfacing buried assumptions.
Simple key-value access translates cleanly to D1 or KV. Single-table design with GSIs, sparse indexes, and composite keys requires schema redesign. If your DynamoDB usage looks like SQL with a different API, migration is straightforward. If it exploits DynamoDB's unique capabilities, expect significant design work.
Assess DynamoDB access patterns exhaustively first. Identify every query pattern, every GSI, every scan operation. Understand which patterns translate to SQL and which require rethinking. The data model assessment, not the function count, determines migration difficulty.
The coordination question matters too. Lambda functions coordinating through DynamoDB conditional writes, transactions, or streams may be implementing patterns belonging in Durable Objects. Recognising coordination logic masquerading as database operations, and migrating it to purpose-built coordination primitives, often improves the resulting architecture significantly.
Migrating from S3 to R2
This migration is genuinely straightforward because R2's S3 compatibility is comprehensive.
Primary work is validating your S3 API usage falls within R2's supported operations. Most does. Some advanced features (certain analytics, inventory reports, cross-region replication, object lock compliance mode) have no R2 equivalent.
Event-driven architectures need attention. S3 events triggering Lambda functions don't have a direct equivalent; R2 offers event notifications triggering Workers, but the integration pattern differs. Architectures built around S3 events need rewiring, not reconfiguration.
The migration mechanics are simple: configure R2, update SDK endpoints and credentials, migrate data, switch traffic. Simple doesn't mean careless: run parallel reads comparing responses, verify data integrity, monitor error rates.
Migrating from ECS or Fargate
First question: should you migrate at all?
Many ECS workloads can run as Workers with acceptable constraints. If your container exists because "that's how we deploy" rather than because you need specific container capabilities, evaluate Workers first. Operational simplification often justifies modest code changes.
Containers make sense when you genuinely need more than 128 MB memory, arbitrary runtimes that won't compile to WebAssembly, existing container images whose rewrite cost exceeds migration benefit, or CPU time beyond Workers' limits.
If you need Containers, understand how differently they work from ECS: traffic routes through Workers or Durable Objects, not directly to containers; container instances tie to Durable Objects for coordination; maximum resources (4 vCPU, 12 GB RAM, 20 GB disk) may be less than current instances; cold starts measure in seconds; no VPC equivalent, so network isolation patterns need rethinking.
This isn't lift-and-shift; it's restructure-and-shift. Teams expecting to move container images unchanged discover they're redesigning architecture.
Common failure patterns
The Big Bang fails because one component failure stalls everything. Teams get stuck running both platforms indefinitely, paying for both while neither works well. Migrate incrementally, one workload at a time. Prove each migration before starting the next.
Underestimating data migration fails for reasons discussed above. Start early, run parallel writes during transition, validate continuously. Budget twice your estimate; then budget more.
Assuming parity fails because "it works the same way" is rarely true. Subtle differences in timing, consistency, error handling, and edge cases cause production issues testing missed. Run parallel implementations comparing results. Don't declare victory until production traffic has run for weeks.
Ignoring operational readiness fails when the new system works but nobody knows how to operate it. Alerts aren't configured, runbooks don't exist, 3am incidents find teams unprepared. Build operational capability alongside migration: train the team, set up monitoring, write runbooks.
Feature creep fails by turning migration into transformation. "While we're migrating, let's also add these features" expands scope, slips timelines, loses momentum. Migrate first, improve second.
Hybrid architectures
If you're uncertain, start hybrid. This path proves value with minimal commitment and builds expertise for future decisions.
Deploy Cloudflare at the edge while keeping existing backends. Workers handle authentication, rate limiting, and caching. Backends remain unchanged. You've added capability without removing anything that works.
Static assets move to R2 for immediate egress cost savings with no backend changes, just storage migration. The savings often fund further experimentation.
Edge personalisation (A/B testing, geographic customisation, response transformation) adds value without backend modification. Workers transform responses; backends serve content.
From this foundation, evaluate further migration with data rather than projections. You understand the development experience. You've measured operational impact. The decision to migrate more, or stay hybrid permanently, rests on evidence from your environment, not spreadsheet estimates.
Staying hybrid permanently is valid. Many architectures are optimal with Cloudflare handling edge concerns and hyperscalers handling backend compute. Hybrid isn't a transition state you must exit; it's an architecture that may be right indefinitely.
Hybrid security architectures
Hybrid doesn't only mean hybrid compute. You can deploy Cloudflare's networking and security products in front of existing infrastructure without migrating compute at all.
Deploy Cloudflare's WAF, DDoS protection, and CDN in front of existing AWS/Azure/GCP infrastructure without migrating compute. This delivers immediate value while building organisational familiarity with Cloudflare operations.
Consider an organisation with significant AWS investment. The Developer Platform evaluation might conclude migration is premature: team expertise, existing commitments, and risk tolerance all favour staying on AWS. But that doesn't preclude using Cloudflare's WAF, DDoS protection, and CDN in front of AWS origins.
This pattern delivers immediate value while building organisational familiarity. Traffic flows through Cloudflare's network for performance and security, then reaches AWS backends unchanged. The AWS investment remains protected, the organisation gains Cloudflare operational experience, and the path to Developer Platform adoption becomes clearer.
When you eventually deploy Workers, they integrate naturally with security products already in place. WAF rules configured for AWS origins work identically for Worker-based applications. Rate limiting policies transfer. Access controls apply. Each step adds capability without compromising what came before.
This is the strategic case for Cloudflare beyond any single product category: security products, networking products, and the Developer Platform share operational model, configuration interface, and deployment philosophy. Adopting any subset creates familiarity with the whole.
The global blast radius
One operational reality differs fundamentally from hyperscaler experience.
On hyperscalers, a bug typically affects one region. You discover the problem through alerts from us-east-1 while eu-west-1 continues serving traffic. Users in unaffected regions don't notice.
On Cloudflare, a bug affects everyone simultaneously. Deploy a broken Worker and every user hits that broken code instantly. No regional isolation limits the blast radius; no time window where some users are fine while you debug.
This changes how you work.
Deployment discipline matters more. Canary deployments, gradual rollouts, and automated rollback become essential. Your ability to detect and rollback quickly determines impact duration.
Testing requirements increase. You cannot rely on regional rollout catching issues before they go global. Issues must be caught before production deployment because production means everywhere.
Monitoring must be immediate. By the time you notice problems through slow channels, every user has been affected. Real-time error rates and latency monitoring become operationally critical.
Rollback capability is non-negotiable. Instant rollback to the previous working version is your primary incident response tool. Ensure your deployment pipeline supports it and your team has practised it.
This isn't a reason to avoid Cloudflare; the same global deployment creating blast radius risk also provides global performance and operational simplicity. But teams accustomed to regional isolation must adapt. The speed that accelerates feature delivery also accelerates bug delivery. Plan accordingly.
Organisational readiness
Technical evaluation is necessary but insufficient. Before committing, assess whether your organisation can execute.
Does your procurement process accommodate consumption-based pricing? Some organisations require fixed annual commitments for budget predictability. Cloudflare's usage-based model may conflict with how finance operates. Not a technical problem, but it blocks adoption just as effectively.
Do you have executive sponsorship that will survive personnel changes? Platform adoption spanning six months or more will likely outlast some stakeholder's tenure. If the initiative depends entirely on one executive's support, succession planning matters. Who else understands the strategic rationale?
Can your team absorb the learning curve while maintaining current responsibilities? Adopting a new platform while delivering features on existing platforms divides attention. Some organisations parallelise effectively; others cannot. Honest assessment prevents the common failure mode of adoption starting strong and stalling when other priorities intrude.
Is there organisational patience for incremental value? Platform adoption delivers returns over months rather than weeks. Organisations expecting immediate transformation often abandon efforts before value materialises.
These questions don't have right or wrong answers, but they have honest and dishonest ones. An organisation that cannot answer favourably can still adopt Cloudflare, with eyes open about non-technical challenges ahead.
Leveraging the wider platform for enterprise requirements
Some architectural decisions benefit from deliberate integration with Cloudflare's networking and security products rather than relying solely on bundled capabilities. Understanding when to reach beyond the Developer Platform helps design systems meeting enterprise requirements without unnecessary complexity.
Edge security before compute
By default, traffic reaches your Workers after passing through Cloudflare's infrastructure. Adding security products filters and transforms requests before your code executes.
WAF rules block malicious requests entirely, reducing Worker load and preventing attack traffic from consuming billable compute. If your Workers process financial transactions or healthcare data, deploying WAF rules for relevant attack categories adds defence in depth. Your Workers still validate inputs (you can't rely solely on WAF rules) but the combination reduces risk more than either alone.
Edge rate limiting complements or replaces Worker-based rate limiting. Edge limiting operates before any compute, so blocked requests incur no Worker invocations. For public APIs where abuse is common, edge rate limiting keeps costs predictable while Workers handle legitimate traffic. The choice depends on precision requirements: edge limiting is approximate but free of compute costs; Worker-based limiting with Durable Objects is precise but incurs invocations.
Access policies gate entire applications or specific routes before requests reach Workers. For administrative dashboards, internal tools, or B2B applications, Access policies verify identity and authorisation at the edge. Workers receive only authenticated requests from verified users, simplifying code and centralising access policy management.
Network connectivity and isolation
Chapter 21 covers Cloudflare Tunnel and VPC Services for connecting Workers to private backends. The wider platform offers additional options.
Magic WAN connects your corporate networks to Cloudflare, enabling Workers to reach internal resources across your entire organisation rather than individual tunnel endpoints. For enterprises with complex network topologies, Magic WAN provides unified connectivity individual tunnels cannot match.
Gateway and CASB extend protection beyond inbound requests. If your Workers interact with third-party SaaS applications or make outbound requests to untrusted endpoints, Gateway policies enforce data loss prevention, malware scanning, and acceptable use policies on outbound traffic.
Observability and analytics
Worker observability through wrangler tail, real-time logs, and integrated dashboards (covered in Chapter 21) serves most operational needs. The wider platform adds security-specific observability.
Security Analytics aggregates threat data across WAF, DDoS, and bot management into unified dashboards. Correlate attack patterns, identify targeted endpoints, and understand your threat landscape beyond what Worker logs reveal.
Logpush delivers logs from both Workers and security products to external SIEM systems for compliance and long-term analysis. If your organisation requires centralised security logging, Logpush feeds necessary data to existing security operations tooling.
The integration advantage
These products integrate through shared infrastructure rather than bolted-on APIs. WAF rules and Access policies evaluate before Workers invoke, not through separate request chains. Rate limiting counts against the same request flow, not a parallel proxy layer. Logs from Workers and security products share context and correlation identifiers.
This matters for operational simplicity. On hyperscalers, assembling equivalent capability requires combining CloudFront with WAF with Shield with API Gateway with Lambda, each with its own configuration surface, pricing model, and failure modes. On Cloudflare, a single dashboard spans compute, security, and networking. A single bill covers all products. A unified API manages configuration across concerns.
The Developer Platform evaluation can proceed independently; you're evaluating compute and storage, not security products. But knowing security products exist, integrate well, and share operational simplicity reduces evaluation risk. If requirements expand, the path forward is clear.
Making the decision
The evaluation framework from the chapter's opening now has substance.
Choose Cloudflare when workload fit is good, economics favour you, your team can ramp effectively, and you can accept the lock-in accompanying the features you need. The platform delivers genuine advantages for the right workloads, advantages requiring significant custom infrastructure to replicate elsewhere.
Choose hyperscalers when workload fit is poor, specific managed services are essential, team expertise strongly favours them, or contractual requirements mandate them. Concluding that Cloudflare isn't right for your situation is a successful evaluation.
Choose hybrid when you want to prove value before committing, when different workloads have different needs, or when risk tolerance requires gradual adoption. Hybrid is often optimal, not a compromise to escape.
If this evaluation points toward adoption, Chapter 3 begins the technical depth: execution model, resource constraints, and performance characteristics you need before building production systems.
If this evaluation points away from adoption, that's valuable too. Better to know now than after significant investment. Chapter 24 returns to limitations in depth.
If you're uncertain, run a bounded proof of concept. Implement one workload, measure results, and evaluate the development experience. The platform's low operational overhead means experiments cost engineering time, not infrastructure commitment. Experience resolves uncertainty more reliably than analysis.