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:
- Placement only affects the execution of fetch event handlers. It does not affect RPC methods or named entrypoints.
- Workers without a fetch event handler are ignored by placement.
- Static assets are always served from the location nearest to the incoming request. If your code retrieves assets via the static assets binding, assets are served from the location where your Worker runs.
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.

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 authenticationapp-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
{"@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
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.
