Files
dotfiles/.agents/skills/cloudflare-deploy/references/smart-placement/api.md
2026-03-17 16:53:22 -07:00

5.4 KiB

Smart Placement API

Placement Status API

Query Worker placement status via Cloudflare API:

curl -X GET "https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/workers/services/{WORKER_NAME}" \
  -H "Authorization: Bearer <TOKEN>" \
  -H "Content-Type: application/json"

Response includes placement_status field:

type PlacementStatus = 
  | undefined  // Not yet analyzed
  | 'SUCCESS'  // Successfully optimized
  | 'INSUFFICIENT_INVOCATIONS'  // Not enough traffic
  | 'UNSUPPORTED_APPLICATION';  // Made Worker slower (reverted)

Status Meanings

undefined (not present)

  • Worker not yet analyzed
  • Always runs at default edge location closest to user

SUCCESS

  • Analysis complete, Smart Placement active
  • Worker runs in optimal location (may be edge or remote)

INSUFFICIENT_INVOCATIONS

  • Not enough requests to make placement decision
  • Requires consistent multi-region traffic
  • Always runs at default edge location

UNSUPPORTED_APPLICATION (rare, <1% of Workers)

  • Smart Placement made Worker slower
  • Placement decision reverted
  • Always runs at edge location
  • Won't be re-analyzed until redeployed

cf-placement Header (Beta)

Smart Placement adds response header indicating routing decision:

// Remote placement (Smart Placement routed request)
"cf-placement: remote-LHR"  // Routed to London

// Local placement (default edge routing)  
"cf-placement: local-EWR"   // Stayed at Newark edge

Format: {placement-type}-{IATA-code}

  • remote-* = Smart Placement routed to remote location
  • local-* = Stayed at default edge location
  • IATA code = nearest airport to data center

Warning: Beta feature, may be removed before GA.

Detecting Smart Placement in Code

Note: cf-placement header is a beta feature and may change or be removed.

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const placementHeader = request.headers.get('cf-placement');
    
    if (placementHeader?.startsWith('remote-')) {
      const location = placementHeader.split('-')[1];
      console.log(`Smart Placement routed to ${location}`);
    } else if (placementHeader?.startsWith('local-')) {
      const location = placementHeader.split('-')[1];
      console.log(`Running at edge location ${location}`);
    }
    
    return new Response('OK');
  }
} satisfies ExportedHandler<Env>;

Request Duration Metrics

Available in Cloudflare dashboard when Smart Placement enabled:

Workers & Pages → [Your Worker] → Metrics → Request Duration

Shows histogram comparing:

  • Request duration WITH Smart Placement (99% of traffic)
  • Request duration WITHOUT Smart Placement (1% baseline)

Request Duration vs Execution Duration:

  • Request duration: Total time from request arrival to response delivery (includes network latency)
  • Execution duration: Time Worker code actively executing (excludes network waits)

Use request duration to measure Smart Placement impact.

Interpreting Metrics

Metric Comparison Interpretation Action
WITH < WITHOUT Smart Placement helping Keep enabled
WITH ≈ WITHOUT Neutral impact Consider disabling to free resources
WITH > WITHOUT Smart Placement hurting Disable with mode: "off"

Why Smart Placement might hurt performance:

  • Worker primarily serves static assets or cached content
  • Backend services are globally distributed (no single optimal location)
  • Worker has minimal backend communication
  • Using Pages with assets.run_worker_first = true

Typical improvements when Smart Placement helps:

  • 20-50% reduction in request duration for database-heavy Workers
  • 30-60% reduction for Workers making multiple backend API calls
  • Larger improvements when backend is geographically concentrated

Monitoring Commands

# Tail Worker logs
wrangler tail your-worker-name

# Tail with filters
wrangler tail your-worker-name --status error
wrangler tail your-worker-name --header cf-placement

# Check placement status via API
curl -H "Authorization: Bearer $TOKEN" \
  https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/workers/services/$WORKER_NAME \
  | jq .result.placement_status

TypeScript Types

// Placement status returned by API (field may be absent)
type PlacementStatus = 
  | 'SUCCESS'
  | 'INSUFFICIENT_INVOCATIONS'
  | 'UNSUPPORTED_APPLICATION'
  | undefined;

// Placement configuration in wrangler.jsonc
type PlacementMode = 'smart' | 'off';

interface PlacementConfig {
  mode: PlacementMode;
  // Legacy fields (deprecated/removed):
  // hint?: string;  // REMOVED - no longer supported
}

// Explicit placement (separate feature from Smart Placement)
interface ExplicitPlacementConfig {
  region?: string;
  host?: string;
  hostname?: string;
  // Cannot combine with mode field
}

// Worker metadata from API response
interface WorkerMetadata {
  placement?: PlacementConfig | ExplicitPlacementConfig;
  placement_status?: PlacementStatus;
}

// Service Binding for backend Worker
interface Env {
  BACKEND_SERVICE: Fetcher;  // Service Binding to backend Worker
  DATABASE: D1Database;
}

// Example Worker with Service Binding
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    // Forward to backend Worker with Smart Placement enabled
    const response = await env.BACKEND_SERVICE.fetch(request);
    return response;
  }
} satisfies ExportedHandler<Env>;