Source: https://architectingoncloudflare.com/chapter-02

# 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.

A Worker uses Cloudflare's network for request handling, including TLS termination and DDoS mitigation. Application controls still need deliberate design: which hostnames are protected, who can call each operation and whether another route bypasses those checks. Include both the bundled services and the work left to your team in the 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 measured compute requirements or commitment pricing favour their execution model, 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 different needs, or when risk tolerance requires gradual adoption with rollback capability. Hybrid isn't a compromise; it's often optimal for complex organisations.

> **Fundamental Platform Constraints**
>
> Some requirements represent genuine mismatches with Cloudflare's architecture rather than limitations to engineer around. These include: applications exceeding the 128 MB isolate memory budget where neither warm Container capacity nor external compute meets the requirement, workloads needing inbound UDP, or GA inbound TCP today (an inbound-TCP path is in private beta via Spectrum), a requirement for a native D1 database exceeding 10 GB that cannot be partitioned (an external database through Hyperdrive remains an option), 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 towards 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**: Deployment and isolated execution of customer applications at platform scale

Bindings connect these primitives through explicit resource access. Each service still has its own lifecycle, limits and billing units; a common integration model does not make their operating costs interchangeable.

### When your product hosts other applications

A platform that hosts thousands of customer applications needs a different assessment from one application serving thousands of customers. If every tenant runs the same trusted logic with different data, shared Workers and tenant-scoped storage may be sufficient. If tenants need independently deployed applications, Workers for Platforms provides a dispatch namespace for that fleet. The applications can come from your own templates as well as customer code.

Dynamic Workers address a related choice: load code at runtime instead of deploying each program beforehand. Durable Object Facets give that loaded code persistent state, while Dynamic Workflows give runtime-loaded process code durable steps, retries and waits. These mechanisms make application builders, integration platforms and generated automations worth evaluating on Cloudflare even when a deployment per program would be impractical.

Assess which limit your design actually encounters: the number of resources, the rate of starting work, or the capacity of one execution. A different deployment model can remove a resource-count obstacle while leaving memory, downstream capacity and cost constraints intact. Chapter 25 compares the choices and the platform operations you take on; include those operations in the adoption decision.

### 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 routing is managed by Cloudflare.** Cloudflare advertises the same service IP addresses from multiple locations; network routing selects which location receives a connection. This is anycast, and it supplies global entry without an application-managed global load balancer. The resulting latency still depends on routing, congestion and backend location; it is not guaranteed to beat every direct path to an origin.

**Global deployment avoids a regional application fleet.** Workers makes your code available through Cloudflare's network. Routing, placement and dependency locations determine where a request executes and how long it takes. State replication and recovery still need their own design.

**Bot controls require deliberate configuration.** Bot Fight Mode and Bot Management have their own scope and settings. Do not infer a configured bot policy from the fact that a request reaches a Worker.

Include the network services your application would otherwise need in the comparison. Count the configuration and operating work that remains on either platform.

### 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. Choose rules from the application's threat model, and test their coverage and false positives on the actual request path.

**Advanced rate limiting** operates at the Cloudflare edge with granular controls. Chapter 24 distinguishes approximate local abuse controls from strict quotas owned by a Durable Object. Compare the product's rule scope and enforcement behaviour with the abuse controls the application needs.

**Bot Management** adds classification and policy controls for automated traffic. Select rules for the actual threat model and test legitimate API clients as well as browsers; automated traffic is not inherently unwanted.

**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.

Map the required controls to the services and settings that provide them. DDoS protection does not establish an application authorisation policy, and a managed certificate does not validate an incoming payload. Include additional products where that control map requires them, then test the complete request path.

## 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** can avoid managing separate regional compute deployments. The latency benefit depends on the complete path: a nearby Worker may still call a distant database. Stateless request handling benefits most directly; replicated data and coordinated state require their own decisions.

**Latency-sensitive authentication** can avoid a remote round trip when a Worker verifies a token locally. Current permissions, revocation and session state may still require an authoritative lookup. Separate signature verification from those checks before estimating the latency benefit.

**Real-time coordination and collaboration** can fit Durable Objects when a room, document or match is a useful ownership boundary. The object combines state, routing and live connections. Clients still need reconnect and conflict-handling behaviour, and an existing actor or collaboration service may already meet the requirement. Chapter 7 examines when central authority simplifies the design.

**I/O-heavy orchestration** can benefit from Workers' CPU meter. A Worker awaiting an external call does not spend billable CPU on that wait; Lambda's ordinary invocation-duration meter includes it. Price the complete operation, including requests, backend calls and any Durable Object or Container activity. Those services have different meters.

**Multi-tenant SaaS platforms** can use a D1 database per tenant when tenants form independent transaction and query boundaries. Test the largest tenant and the cost of operating a database fleet before adopting the pattern. Workers for Platforms supports independently deployed customer applications when tenants need separate code or release lifecycles. Choose that boundary independently of the database layout.

**AI-powered applications with global users** can combine Workers AI, Vectorize and storage through platform bindings. That simplifies integration without guaranteeing that every stage runs near the user. Measure retrieval, inference (running a trained model on new input) and tool calls together; Chapter 17 develops the inference decision.

### Workloads that struggle

**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 GiB, with startup latency that depends on scheduling, the image and application initialisation. Measure the first useful operation against the request deadline; if it does not fit, compare warm capacity, an asynchronous handoff and external compute. Chapter 10 develops that choice.

**Long-running computation** can exceed a paid HTTP Worker’s five-minute CPU ceiling. Use Containers, external compute or shorter durable stages when the job needs more. Waiting and computing have different limits: an HTTP request using four minutes of CPU over an hour still depends on the client connection, while other triggers have their own execution budgets.

**Single large databases** conflict with D1's architectural assumptions. The 10 GB-per-database limit exists by design, guiding you towards horizontal patterns. If your application 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 UDP connections don't fit, and inbound TCP only partly.** Cloudflare's ingress is HTTP-centric; non-HTTP traffic reaches the network through Spectrum, its TCP and UDP proxy. Spectrum can hand an inbound TCP socket directly to a Worker or Container through a `connect()` handler, which is what lets you serve gRPC on Cloudflare, but that path is in private beta and TCP-only. Inbound UDP has no equivalent, so game servers expecting direct UDP connections and latency-sensitive custom protocols need traditional cloud infrastructure for ingress. Treat inbound TCP as a private beta, not something to stake a launch on.

### Assessing your workloads

For each significant workload, assessment reduces to key questions.

**Memory envelope?** Measure peak memory with representative payloads and concurrency. Workers share a 128 MB limit across requests in an isolate, so a request that fits alone may still leave too little headroom under load. If required working data cannot fit after streaming or chunking, use Containers or external compute.

**Compute profile?** Measure the CPU budget for the operation; up to thirty seconds fits the paid HTTP default. HTTP handlers can be configured for up to five minutes of CPU time. Beyond that, use Containers, external compute, or divide the work into shorter invocations. Queues decouple processing from the request; they do not provide unlimited CPU.

**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?** A database in one location can dominate request latency wherever the Worker runs. Placement can bring compute closer to it. Draw the path to every required dependency; using a Cloudflare binding does not by itself make that dependency local.

**What protocols?** HTTP and WebSocket have native support. Inbound UDP doesn't fit; inbound TCP is in private beta via Spectrum (which also lets you serve gRPC), so treat it as emerging rather than production-ready today.

**Need real-time coordination?** Compare how callers reach an entity, how concurrent operations are ordered and how state and live connections survive failure. A Durable Object may replace coordination machinery you currently operate; an existing actor service may already meet the requirement.

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 familiar assumptions fail, and identifies patterns that don't apply.

### The concept map

| Familiar service | Candidate on Cloudflare | Boundary to compare |
|---------------------|----------------------|----------------|
| Lambda / Azure Functions | Workers | Isolates avoid process startup; measure application initialisation |
| API Gateway | Worker HTTP handlers | Routing in application code; assess required gateway policies separately |
| 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 | Worker consumers or HTTP pull; at-least-once delivery |
| ECS / Container Apps | Containers | Must route through Workers; no direct inbound connections |
| CloudFront / Front Door | Workers network and caching services | Global entry is built in; response caching needs an explicit policy |
| WAF / Shield | Built-in (basic) or WAF product | DDoS protection included; advanced WAF separate |
| Secrets Manager | Worker secrets or Secrets Store | Per-Worker configuration versus reusable secrets; compare access and rotation |
| CloudWatch / Monitor | Workers Logs + Analytics Engine | 3-day Free / 7-day Paid log retention; export for longer retention |

### Startup work changes

Workers creates isolates within an existing runtime, avoiding the process startup common to regional serverless functions. That removes much of the reason to maintain warming infrastructure for ordinary JavaScript handlers.

Application startup still matters. Module initialisation, Python dependencies and empty caches can add work to a first request. Benchmark the application before importing a warming strategy from Lambda or declaring startup irrelevant.

### Connection management changes

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 manages access without an application connection pool. Query capacity and downstream contention still need monitoring.

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.

Workers gives the application a global entry point by default. Where a residency requirement applies, identify which controls restrict request processing, stored data and logs; no single region setting governs them all.

Global compute does not make data uniformly local. D1 places a primary database and can use read replicas; Durable Objects place each entity at one location. Choose consistency and placement deliberately, then measure the distance between users, compute and state.

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. That setting follows an architectural decision about the dependencies on the request path.

### Responsibilities the platform takes on

Workers manages stateless invocation capacity and network ingress without application-owned node pools or a regional load balancer. Default outbound internet access also removes the need to provision a NAT gateway for an ordinary Worker.

The application still controls admission, retries and traffic policy. A service binding supplies a route to another Worker, but does not decide whether a call is authorised or whether a failing dependency should receive more work. Containers remove cluster administration while leaving instance sizing, scheduling and lifecycle choices. Evaluate the responsibilities that disappear and those that move into configuration or application code.

### 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. The CPU charge excludes external I/O waits; request charges and downstream services still bill separately. Measure both CPU and elapsed duration to compare with Lambda at the memory allocation the workload needs.

**R2 egress**: R2 has no egress charge. Storage, operations and the selected delivery path still contribute to cost. Compare those with the transfer charges the application would actually avoid.

**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. The pattern transfers; validate the supported operations, signed headers, S3 endpoint and browser CORS policy.

**Event-driven processing**: Queues trigger Workers just as SQS triggers Lambda. The consumer pattern is familiar, but acknowledgement, retry, ordering and batch behaviour need checking.

**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 configures a Worker and its bindings. Decide who owns provisioning, desired state and drift for shared resources; retain the team's infrastructure-as-code workflow for that lifecycle.

### What requires rethinking

Several patterns require fundamental rethinking rather than direct translation.

**Actor-based coordination** combines identity, state and execution in a Durable Object. Other managed actor systems, including Azure Durable Entities, provide related capabilities. Compare the operations your application needs, particularly request/response interaction, storage transactions and live connection ownership. Chapter 7 develops the object boundary and its concurrency rules.

**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.

**Hosted inference**: Workers AI supplies Cloudflare-hosted models through a binding or API. It does not make every model available at every request location. Compare task quality, full-path latency and capacity with the external providers available through AI Gateway or direct APIs.

## 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 plan allows 100,000 requests daily and 10ms CPU time per request. It can serve applications within those limits; assess required service features and support separately from traffic volume.

### Price the whole path

A compute-only comparison can miss transfer, gateway, storage and standing charges. Use the actual service, region and traffic path for each item.

**Internet and regional transfer have different meters.** AWS's internet-transfer allowances are shared across eligible services and regions. Count the billable volume after those allowances and any CDN arrangement. R2's no-egress policy can remove a substantial charge, but does not remove request processing or migration transfer costs elsewhere.

**Private networking can add standing costs.** A Lambda reaching the internet through a NAT gateway can incur both hourly and processing charges. Count only the gateways and traffic the architecture needs; private service endpoints and existing shared infrastructure change the comparison.

**Startup mitigation and reserved commitments need separate treatment.** Provisioned concurrency has a standing cost. Savings plans and reserved capacity can reduce rates while leaving a commitment that a migration does not cancel. Record which costs disappear, which remain and when their contracts expire.

Chapter 20 develops the full cost model, including engineering and operational work.

### A representative calculation

Consider 50 million requests a month at 20ms of CPU per request. That is one billion CPU milliseconds. On Workers Paid, after the included ten million requests and thirty million CPU milliseconds, the compute bill is $5 + $12 + $19.40 = $36.40. This covers Workers requests and CPU, not the application's database, logs or other services.

The useful comparison is with a measured alternative. Lambda bills execution duration and allocated memory, so CPU time alone does not establish its cost. API Gateway pricing depends on the API type, and database costs need explicit read and write volumes. Compare the same request path, traffic profile, caching assumptions and included allowances on both platforms.

For an I/O-heavy service, investigate duration billing and gateway charges first. For a media-heavy service, investigate egress. Those are hypotheses to test against your bill, not a universal savings percentage.

### 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. Compare measured Workers CPU with Lambda duration at the required memory allocation. Neither unit price alone establishes which service costs less.

**Very low traffic** may not justify the $5/month Workers Paid base cost. First check whether the workload fits the Free plan’s daily request, CPU and service limits; 10,000 monthly requests alone do not imply a paid bill. Compare the allowances and required features on both platforms.

**Heavy hyperscaler service integration** can make adding Cloudflare more expensive. If you're using AWS services charging for external access (RDS data transfer, SQS requests and transfer, Kinesis streaming), Cloudflare as a front layer may increase total cost.

**Existing reserved commitments** may remain payable after migration. Include that continuing charge and whether the released capacity can serve another workload; do not count the same commitment as an avoidable saving.

### 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 transfer volume and cost**: distinguish internet delivery, regional traffic and internal service calls. Identify which charges the proposed architecture removes and which it adds.

**Cold start mitigation costs**: count provisioned concurrency, which keeps execution environments initialised and ready, or other warming infrastructure that the new workload would avoid. Retest application initialisation and dependency loading before assuming that entire cost disappears.

**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

Separate portable data from portable behaviour. An export may preserve every record while leaving routing, authorisation and recovery semantics to rebuild.

**Application logic** using standard JavaScript, TypeScript and Web APIs can travel with modest adaptation. Keep business decisions separate from platform adapters where that makes the contract easier to test.

**R2 data** can move through S3-compatible tools. Rehearse the supported operations, metadata and delivery behaviour; API familiarity alone does not prove a complete exit.

**D1** exports schema and data as SQL for import into a compatible SQLite database. Check export restrictions for the features you use and test restoration. The file does not reproduce D1's placement, replication or fleet-management model.

**Durable Objects** create a substantial execution-model commitment. A replacement must reproduce the routing, storage, concurrency and connection behaviour the application uses. Related actor systems can be candidates, but an exported dataset is only part of that migration.

**Bindings and platform APIs** need replacement contracts. A resource handle may be easy to wrap; reproducing its permissions, retry behaviour or placement can require architectural work. Workers for Platforms adds tenant-code deployment and isolation to that assessment.

Accept the switching cost when the operating benefit justifies it. Record what an exit would require for the stateful path, then test the hardest part before it becomes a contractual obligation. Chapter 26 develops exit planning in more detail.

## Team readiness

A pilot should test whether the team can operate the application as well as build it. Familiar JavaScript and HTTP APIs shorten the first deployment; they do not establish that someone can diagnose a stale read, recover a stuck workflow or explain a cost spike.

### Test the unfamiliar parts

Actor-model experience helps with Durable Objects. Database experience helps with partitioning and migrations. Existing Terraform and CI practices still matter: bindings describe what code can access, while infrastructure tooling manages resources and their lifecycle. Chapter 5 covers the local and deployed tests that exercise those boundaries.

Avoid promising a standard ramp-up period. Have the team build one representative slice, explain its failure modes to a colleague, and recover it from a deliberately introduced fault. The gaps in that exercise give you a more useful training plan than a forecast of “two months to proficiency”.

### Put operations inside the pilot

Name the people who will investigate failures, review costs and maintain deployment tooling. Give them access to logs and budgets before the first production release. A prototype operated only by its enthusiastic author can conceal a substantial support burden.

Record the decisions that a new on-call engineer would need: which resource owns the state, which writes can be replayed, how to disable a failing path, and what a rollback restores. If a second engineer cannot follow those instructions, the pilot has more work to do.

Check the agreement covering each required service: support access, escalation ownership and any service-level commitment. A vendor's response target does not establish a restoration time or the application's recovery promise. Compare the purchased coverage with the application's service-level objectives; paid usage or beta access alone does not settle that decision.

### Set an evidence threshold

Choose a bounded workload with a measurable problem: a slow request path, expensive data transfer or coordination that is difficult to operate. Include its hardest dependency. A disconnected demonstration may be easy to finish but prove little about the intended application.

Agree on the baseline, the acceptable result and the conditions for stopping. Share the result with engineering, operations and the budget owner, including the parts that became harder. A pilot that rules out a poor fit has earned its cost.

Keep unrelated product additions outside the migration's acceptance criteria. Changing the platform and expanding the feature set together makes regressions harder to explain and completion harder to recognise.

## Migration realities

Define what the move must preserve before choosing the destination. Response shape is only part of compatibility: permissions, read-after-write behaviour, retry outcomes and accepted work also form the application's contract. Keep intentional behaviour changes explicit so a comparison does not reproduce an old defect by accident.

Estimate runtime adaptation, data conversion, reconciliation and cutover separately. Handler count says little about a conditional write protecting an invariant or a retry that can send a second payment. Rehearse the boundary with the greatest consequence of failure before committing to the schedule.

Consistency deserves an early test. KV can serve cached values and misses for 60 seconds or longer. D1 transactions cover one database, not writes spanning D1 and R2. A schema that imports successfully can still support the wrong behaviour. Chapter 12 maps the storage choices; Chapter 27 develops service-specific migration and cutover procedures.

Keep one write authority while transferring data through a recoverable path. Reconcile through a known position before moving that authority, and establish what rollback would do with writes accepted afterwards. Include those rehearsals and repairs in the estimate. Parallel response comparison alone cannot establish that state or external effects remain correct.

## Hybrid architectures

A Worker can handle a bounded edge concern while the existing backend retains state and business operations. For example, local token verification or cacheable response delivery may remove a round trip without moving the database. Measure the benefit alongside the extra deployment, observability and incident-response surface.

Moving object delivery to R2 is another independent boundary. Validate API compatibility, browser access and transfer mechanics, then compare the complete delivery bill. Keeping a database or specialised backend elsewhere may remain the best long-term design.

Security and networking adoption can also stand alone. Existing WAF or Access policies may remain useful when requests traverse the same protected hostnames and rules. Introducing a Worker requires checking alternate entry points and direct backend access. The complete request-path assessment below determines which policies still apply.

Expand only when the next boundary has a demonstrated benefit and a recovery plan. A successful first migration is evidence about that workload, not an obligation to move the rest.

## Control the release boundary

A Worker deployment can serve users worldwide. Regional isolation will not limit a faulty release unless you have deliberately created such a boundary. The release strategy must supply the containment.

Gradual deployments split traffic between versions, so global availability does not require exposing every request to new code at once. Promote against error rates and latency, keep a tested rollback path, and consider how a rollback interacts with writes already made. Rolling back code does not reverse a database migration or an external side effect.

The relevant question is how many users and which state a release can affect before you detect failure. Answer it in the deployment design, rather than assuming geography will answer it for you.

## Organisational readiness

Before expanding beyond the pilot, settle three commitments. Finance needs a way to approve and monitor variable usage. Engineering needs time to learn the platform while maintaining the current system. Operations needs an owner for the additional deployment and incident-response surface.

Keep the decision record independent of its sponsor: the workload, measured benefit, remaining risks, expected cost and review date should survive a change of personnel. Adoption that depends on one advocate is difficult to sustain and difficult to question.

## Evaluate the complete request path

Cloudflare's security and networking products may form part of the design, but their presence in the same account does not mean every request passes through them. Record the public hostname, Worker entry point, private bindings and outbound path; then identify which controls apply to each.

Price and validate additional products against that path. An Access policy on one hostname, for example, should not be treated as proof that every route to the application is authenticated. Chapter 22 covers identity verification, private connectivity and deployment authority; Chapter 21 covers operational evidence.

## Making the decision

Proceed when the pilot demonstrates a useful improvement, the workload fits the limits, and a named team can support it. Record the switching costs you accept and the evidence that would make you reconsider.

Keep a hybrid architecture when the useful boundary lies between systems: Workers close to users, an existing database close to its dependent services, or R2 serving objects while compute stays elsewhere. There is no requirement to complete a migration that has already delivered its benefit.

If the evidence remains uncertain, test the uncertain assumption next. If it points away from Cloudflare, keep the result and stop the adoption work. Chapter 26 examines those limits in more detail. For workloads that fit, Chapter 3 begins with the execution model your production design will depend on.
