デフォルトでは、Workers と Pages Functions は、リクエストを受け取った場所に最も近いデータセンターで実行されます。Worker がデータベースや API などのバックエンドインフラへリクエストする場合、エンドユーザーよりバックエンドに近い場所でその Worker を実行した方が、パフォーマンスが良くなることがあります。
{
"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": "gcp:us-east4", // 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
},
}[placement]
mode = "smart"
region = "gcp:us-east4"
host = "db.example.com:5432"
hostname = "api.example.com"配置を使うと、Worker とバックエンドサービス間の往復レイテンシを最小化し、Worker リクエスト全体のレイテンシを下げられます。レガシーなクラウドインフラ上で動くデータベース、API、その他のサービスへ、数ミリ秒のレイテンシを実現できます。
| オプション | 向いている場合 | 設定 |
|---|---|---|
| Smart | バックエンドサービスが複数ある、またはインフラの場所が不明 | mode = "smart" |
| Region | 既知のクラウドリージョンにある単一のバックエンドサービス | region |
| Host | 主要なクラウドプロバイダー上にない単一のバックエンドサービス | host または hostname |
シドニー(オーストラリア)のユーザーが、Workers 上で動くアプリケーションにアクセスする場面を考えます。このアプリケーションは、フランクフルト(ドイツ)のデータベースへ複数回往復します。
シドニーとフランクフルト間の往復が重なると、レイテンシは積み上がります。Worker をデータベースの近くに置くと、Cloudflare はリクエスト全体の所要時間を短縮できます。
Smart Placement は、Worker のトラフィックパターンを自動分析し、最適な場所に配置します。次の場合に Smart Placement を使います。
- Worker が複数のバックエンドサービスに接続する
- インフラの正確な場所が分からない
- バックエンドサービスが分散または複製されている
Smart Placement は Worker 単位で有効にします。有効化すると、異なる Cloudflare 拠点での Worker の リクエスト所要時間 を定期的に分析します。
各候補拠点について、Smart Placement は Worker の性能と、リクエスト転送で増えるネットワークレイテンシを考慮します。候補拠点が明らかに速い場合は、リクエストをそこに転送します。そうでなければ、リクエストに最も近いデフォルトの拠点で Worker が実行されます。
Smart Placement が検討するのは、その Worker が以前に実行された拠点だけです。通常トラフィックを受け取らない拠点には配置できません。
- Smart Placement が影響するのは fetch イベントハンドラー の実行だけです。RPC メソッド や 名前付きエントリポイント には影響しません。
- fetch イベントハンドラーのない Worker は、Smart Placement の対象外です。
- 静的アセット は、常に受信リクエストに最も近い拠点から配信されます。コードが 静的アセットバインディング 経由でアセットを取得する場合、アセットは Worker が実行される拠点から配信されます。
Smart Placement は、すべての Workers プランで利用できます。
Wrangler の設定ファイルに次を追加します。
{
"placement": {
"mode": "smart",
},
}[placement]
mode = "smart"デプロイ後、Smart Placement が Worker を分析するまで最大 15 分かかることがあります。
-
Workers & Pages を開きます。
Workers & Pages を開く ↗ -
Worker を選択します。
-
Settings > General を開きます。
-
Placement で Smart を選択します。
Smart Placement が配置を決めるには、複数拠点から Worker への安定したトラフィックが必要です。分析には最大 15 分かかることがあります。
Workers API で Worker の配置ステータスを照会します。
curl -X GET https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/workers/services/$WORKER_NAME \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" | jq .取りうる配置状態は次のとおりです。
| ステータス | 説明 |
|---|---|
| (なし) | Worker はまだ分析されていません。リクエストに最も近いデフォルトの拠点で実行されます。 |
SUCCESS |
Worker は分析済みで、Smart Placement によって最適化されます。 |
INSUFFICIENT_INVOCATIONS |
複数拠点からのリクエストが不足しており、配置を決められません。 |
UNSUPPORTED_APPLICATION |
Smart Placement によって Worker が遅くなったため、配置を元に戻しました。この状態はまれです(Worker の 1% 未満)。 |
Smart Placement を有効にすると、リクエスト所要時間のデータが収集されます。リクエスト所要時間は、エンドユーザーに最も近いデータセンターで計測されます。比較のベースラインとして、デフォルトではリクエストの 1% は Smart Placement でルーティングされません。
Smart Placement の効果を測るには、Worker の リクエスト所要時間の分析 を確認します。
配置が有効なとき、Cloudflare はすべてのリクエストに cf-placement ヘッダーを追加します。このヘッダーで、リクエストが Smart Placement でルーティングされたかどうかと、Worker がリクエストを処理した場所を確認できます。
ヘッダー値には、配置の種類と、データセンターの場所を示す空港コードが含まれます。
remote-LHR— リクエストは Smart Placement でロンドン近郊のデータセンターへルーティングされました。local-EWR— リクエストは Smart Placement でルーティングされていません。Worker はニューアーク近郊のデフォルト拠点で実行されました。
Placement Hints を使うと、Worker の実行場所を明示的に指定できます。次の場合に Placement Hints を使います。
- バックエンドインフラの正確な場所が分かっている
- Worker が単一のデータベース、API、またはサービスに接続する
- インフラがシングルホームである(複製や Anycast ではない)
例としては、特定リージョンのプライマリデータベース、仮想マシン、Kubernetes クラスターがあります。クエリあたり 20〜30 ミリ秒の往復レイテンシを 1〜3 ミリ秒に下げると、応答時間が改善します。
インフラが AWS、GCP、または Azure 上にある場合は、{provider}:{region} 形式で placement.region プロパティを設定します。
{
"placement": {
"region": "aws:us-east-1", // Explicit cloud region to run your Worker closest to - e.g. "gcp:us-east4" or "aws:us-east-1"
},
}[placement]
region = "aws:us-east-1"Cloudflare は、指定したクラウドリージョンへのレイテンシが最も低いデータセンターへマッピングします。ネットワークメンテナンスや変更に応じて配置は自動調整されるため、フェイルオーバーリージョンを指定する必要はありません。
インフラが主要なクラウドプロバイダー上にない場合は、Cloudflare がプローブするエンドポイントを指定できます。Cloudflare は外部ホストの位置を三角測量し、近くのリージョンに Workers を配置します。
レイヤー 4 のサービスを識別するには placement.host を設定します。Cloudflare は TCP CONNECT チェックでレイテンシを計測し、最適なデータセンターを選びます。
{
"placement": {
"host": "my_database_host.com:5432", // A host to probe (TCP/layer 4) - e.g. a database host - and place your Worker closest to
},
}[placement]
host = "my_database_host.com:5432"レイヤー 7 のサービスを識別するには placement.hostname を設定します。Cloudflare は HTTP HEAD チェックでレイテンシを計測し、最適なデータセンターを選びます。
{
"placement": {
"hostname": "my_api_server.com", // A hostname to probe (HTTP/layer 7) - e.g. an API endpoint - and place your Worker closest to
},
}[placement]
hostname = "my_api_server.com"プローブは Cloudflare の IP 範囲ではなく、パブリック IP 範囲から送信されます。Cloudflare は一定間隔でサービスの場所を再確認します。これらのプローブはシングルホームのリソースを特定するためのもので、ブロードキャスト、Anycast、マルチキャスト、複製されたリソースでは正しく動作しません。
Placement Hints は、Amazon Web Services(AWS)、Google Cloud Platform(GCP)、Microsoft Azure のリージョン識別子に対応しています。
| プロバイダー | 形式 | 例 |
|---|---|---|
| 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 |
リージョンコードの完全な一覧は、AWS リージョン ↗、GCP リージョン ↗、Azure リージョン ↗ を参照してください。
Smart Placement と Placement Hints のどちらを使っても、Workers の配置動作は似ています。次の動作は両方に当てはまります。
次の制限は、Smart Placement と Placement Hints の両方に当てはまります。
- 配置が影響するのは fetch イベントハンドラー の実行だけです。RPC メソッド や 名前付きエントリポイント には影響しません。
- fetch イベントハンドラーのない Worker は、配置の対象外です。
- 静的アセット は、常に受信リクエストに最も近い拠点から配信されます。コードが 静的アセットバインディング 経由でアセットを取得する場合、アセットは Worker が実行される拠点から配信されます。
配置が有効なとき、Cloudflare はすべてのリクエストに cf-placement ヘッダーを追加します。このヘッダーで、リクエストが配置によってルーティングされたかどうかと、Worker がリクエストを処理した場所を確認できます。
ヘッダー値には、配置の種類と、データセンターの場所を示す空港コードが含まれます。
remote-LHR— リクエストは Smart Placement でロンドン近郊のデータセンターへルーティングされました。local-EWR— リクエストは Smart Placement でルーティングされていません。Worker はニューアーク近郊のデフォルト拠点で実行されました。
Workers 上でフルスタックアプリケーションを構築する場合は、エッジロジック(認証、ルーティング)とバックエンドロジック(データベースクエリ、API 呼び出し)を別の Workers に分けます。Service Bindings を使って、型安全な RPC で接続します。
バックエンド Worker で配置を有効にすると、データベースの近くで呼び出せます。一方、エッジ Worker はユーザーの近くで認証を処理します。
この例では、2 つの Workers を示します。
auth-worker— エッジで実行(配置なし)、認証を担当app-worker— データベースの近くに配置、データクエリを担当
{
"name": "auth-worker",
"main": "src/index.ts",
"services": [{ "binding": "APP", "service": "app-worker" }],
}name = "auth-worker"
main = "src/index.ts"
[[services]]
binding = "APP"
service = "app-worker"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",
"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"
[placement]
region = "aws:us-east-1"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 };
}
}auth-worker はエッジで実行され、未認可のリクエストをすばやく拒否します。認証済みリクエストは RPC 経由で app-worker へ転送され、app-worker はデータベースの近くで実行されるため、クエリが速くなります。
Durable Objects は、設定なしで自動配置を提供します。Durable Object に埋め込まれた SQLite データベース へのクエリは、コンピュートがデータと同じプロセスで動くため、実質的に ゼロレイテンシ ↗ です。
Worker から複数回往復するのではなく、Durable Object 内でできるだけ多くの処理を行い、合成した結果を返します。
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 };
}
}