Placement (2)·续

List supported regions

Placement Hints support Amazon Web Services (AWS), Google Cloud Platform (GCP), and Microsoft Azure region identifiers:

Provider Format Examples
AWS aws:{region} aws:us-east-1, aws:us-west-2, aws:eu-central-1
GCP gcp:{region} gcp:us-east4, gcp:europe-west1, gcp:asia-east1
Azure azure:{region} azure:westeurope, azure:eastus, azure:southeastasia

For a full list of region codes, refer to AWS regions ↗︎, GCP regions ↗︎, or Azure regions ↗︎.

Placement Behavior

Workers placement behaves in similar fashion when either Smart Placement or Placement Hints are used. The following behavior applies to both.

Review limitations

The following limitations apply to both Smart Placement and Placement Hints:

cf-placement header

Cloudflare adds a cf-placement header to all requests when placement is enabled. Use this header to check whether a request was routed with placement and where the Worker processed the request.

The header value includes a placement type and an airport code indicating the data center location:

  • remote-LHR — The request was routed using Smart Placement to a data center near London.
  • local-EWR — The request was not routed using Smart Placement. The Worker ran in the default location near Newark.

Caution

The cf-placement header may be removed before Smart Placement exits beta.

Multiple Workers

If you are building full-stack applications on Workers, split your edge logic (authentication, routing) and back-end logic (database queries, API calls) into separate Workers. Use Service Bindings to connect them with type-safe RPC.

Smart Placement and Service Bindings

Enable placement on your back-end Worker to invoke it close to your database, while the edge Worker handles authentication close to the user.

Example: Edge authentication with a placed back-end

This example shows two Workers:

  • auth-worker — runs at the edge (no placement), handles authentication
  • app-worker — placed near your database, handles data queries
{
    "name": "auth-worker",
    "main": "src/index.ts",
    "upload_source_maps": true,
    "services": [{ "binding": "APP", "service": "app-worker" }],
}
name = "auth-worker"
main = "src/index.ts"
upload_source_maps = true

[[services]]
binding = "APP"
service = "app-worker"

auth-worker/src/index.tsts

import { AppWorker } from "../app-worker/src/index";

interface Env {
    APP: Service<AppWorker>;
}

export default {
    async fetch(request: Request, env: Env): Promise<Response> {
        const authHeader = request.headers.get("Authorization");
        if (!authHeader?.startsWith("Bearer ")) {
            return new Response("Unauthorized", { status: 401 });
        }

const userId = await validateToken(authHeader.slice(7));
        if (!userId) {
            return new Response("Invalid token", { status: 403 });
        }

// Call the placed back-end Worker via RPC
        const data = await env.APP.getUser(userId);
        return Response.json(data);
    },
};

async function validateToken(token: string): Promise<string | null> {
    return token === "valid" ? "user-123" : null;
}
{
    "name": "app-worker",
    "main": "src/index.ts",
    "upload_source_maps": true,
    "placement": {
        // Use one of the following options (mutually exclusive):
        // "mode": "smart", // Cloudflare automatically places your Worker closest to the upstream with the most requests
        "region": "aws:us-east-1", // Explicit cloud region to run your Worker closest to - e.g. "gcp:us-east4" or "aws:us-east-1"
        // "host": "db.example.com:5432", // A host to probe (TCP/layer 4) - e.g. a database host - and place your Worker closest to
        // "hostname": "api.example.com", // A hostname to probe (HTTP/layer 7) - e.g. an API endpoint - and place your Worker closest to
    },
}
name = "app-worker"
main = "src/index.ts"
upload_source_maps = true

[placement]
region = "aws:us-east-1"

app-worker/src/index.tsts

import { WorkerEntrypoint } from "cloudflare:workers";

export default class AppWorker extends WorkerEntrypoint {
    async fetch() {
        return new Response(null, { status: 404 });
    }

// Each method runs near your database - multiple queries stay fast
    async getUser(userId: string) {
        const user = await this.env.DB.prepare("SELECT * FROM users WHERE id = ?")
            .bind(userId)
            .first();
        return user;
    }

async getUserListings(userId: string) {
        // Multiple round-trips to the DB are low-latency when placed nearby
        const user = await this.env.DB.prepare("SELECT * FROM users WHERE id = ?")
            .bind(userId)
            .first();
        const listings = await this.env.DB.prepare(
            "SELECT * FROM listings WHERE owner_id = ?",
        )
            .bind(userId)
            .all();
        const reviews = await this.env.DB.prepare(
            "SELECT * FROM reviews WHERE listing_id IN (SELECT id FROM listings WHERE owner_id = ?)",
        )
            .bind(userId)
            .all();

return { user, listings: listings.results, reviews: reviews.results };
    }
}

The auth-worker runs at the edge to reject unauthorized requests quickly. Authenticated requests are forwarded via RPC to app-worker, which runs near your database for fast queries.

Durable Objects

Durable Objects provide automatic placement without configuration. Queries to a Durable Object's embedded SQLite database are effectively zero-latency ↗︎ because compute runs in the same process as the data.

Do as much work as possible within the Durable Object and return a composite result, rather than making multiple round-trips from your Worker:

src/index.tsts

import { DurableObject } from "cloudflare:workers";

type Session = { id: string; user_id: string; created_at: number };
type PromptHistory = {
    id: string;
    session_id: string;
    role: string;
    content: string;
};

export class AgentHistory extends DurableObject {
    async getSessionContext(sessionId: string) {
        // All queries execute with zero network latency — compute and data are colocated
        const session = this.ctx.storage.sql
            .exec<Session>("SELECT * FROM sessions WHERE id = ?", sessionId)
            .one();
        const prompts = this.ctx.storage.sql
            .exec<PromptHistory>(
                "SELECT * FROM prompt_history WHERE session_id = ? ORDER BY created_at",
                sessionId,
            )
            .toArray();

return { session, prompts };
    }
}

Was this helpful?

YesNo

On this page

Placement (2)·续 - 图2Docs

{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/workers/configuration/placement/#page","headline":"Placement","description":"Control where your Worker runs to reduce latency.","url":"https://developers.cloudflare.com/workers/configuration/placement/","inLanguage":"en","image":"https://developers.cloudflare.com/workers/configuration/placement/og.png?v=1bd74349c7db3306","dateModified":"2026-10-12","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}


description: Connect your Worker to an external endpoint (via Routes, Custom Domains or a workers.dev subdomain) such that it can be accessed by the Internet. title: Routes and domains image: https://developers.cloudflare.com/workers/configuration/routing/og.png?v=87156adbb8eafded


Skip to content

Documentation Index
Fetch the complete documentation index at: https://developers.cloudflare.com/workers/llms.txt
Use this file to discover all available pages before exploring further.