The APAC Latency Problem That Edge Compute Solves
APAC engineering teams deploying applications to a single APAC region face a latency distribution problem: Singapore-hosted applications serve Singapore users at 10-30ms but serve Japanese users at 70-100ms, Korean users at 60-90ms, and Australian users at 150-200ms. For APAC applications where latency is directly felt by users — login flows, search, API responses visible in the UI — this APAC inter-region latency degrades the product experience for users outside the primary APAC deployment region.
Edge compute addresses this by running application logic at Points of Presence (PoPs) distributed across APAC — so APAC requests are processed where users are, not where servers were conveniently deployed.
Three tools serve the APAC edge compute and serverless deployment spectrum:
Cloudflare Workers — JavaScript/TypeScript isolates at Cloudflare's 300+ global PoPs, including 10+ APAC cities. Sub-millisecond cold starts. Suitable for APAC edge logic, routing, auth.
Deno Deploy — TypeScript-native serverless runtime at APAC edge regions. git-push deploy. No build steps. Suitable for APAC TypeScript API handlers and Deno Fresh applications.
Fly.io — Docker containers as Firecracker microVMs at APAC regional datacenters. Full OS, persistent volumes, any language. Suitable for APAC full-stack applications and stateful workloads.
The three fill different parts of the APAC compute spectrum: Workers at the extreme-lightweight isolate edge, Fly.io at the full-container end, Deno Deploy in between.
Cloudflare Workers: APAC Edge Logic Without Origin Round-Trips
The APAC Workers deployment model
# Install Wrangler and deploy to APAC Workers global network
npm install -g wrangler
wrangler login
# Initialize APAC Workers project
wrangler init apac-edge-auth-worker --type javascript
# Deploy to all APAC PoPs simultaneously (SIN, NRT, ICN, SYD, BOM, HKG included)
wrangler deploy
# Deployed at https://apac-edge-auth-worker.username.workers.dev
# Coverage: 300+ PoPs globally including 10+ APAC locations
Workers for APAC JWT edge authentication
// apac-auth-worker/src/index.ts
// Runs at APAC PoP nearest to user — validates JWT without origin round-trip
import { jwtVerify, importX509 } from 'jose';
interface Env {
APAC_JWT_SECRET: string; // Workers secret binding
APAC_UPSTREAM: string; // Origin URL (Workers environment variable)
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
// Public APAC routes bypass auth
if (url.pathname.startsWith('/public/') || url.pathname === '/health') {
return fetch(env.APAC_UPSTREAM + url.pathname, request);
}
// Validate APAC JWT at edge (no origin round-trip)
const authHeader = request.headers.get('Authorization');
if (!authHeader?.startsWith('Bearer ')) {
return new Response('Unauthorized', { status: 401 });
}
const token = authHeader.slice(7);
try {
const secret = new TextEncoder().encode(env.APAC_JWT_SECRET);
const { payload } = await jwtVerify(token, secret);
// Inject APAC user context into upstream request
const upstreamRequest = new Request(env.APAC_UPSTREAM + url.pathname, {
method: request.method,
headers: {
...Object.fromEntries(request.headers),
'X-APAC-User-ID': payload.sub as string,
'X-APAC-Region': request.cf?.country as string || 'SG',
'X-APAC-Verified': 'true',
},
body: request.body,
});
return fetch(upstreamRequest);
} catch {
return new Response('Invalid token', { status: 401 });
}
},
};
Workers KV for APAC geo-based feature flags
// APAC edge feature flag evaluation using Workers KV
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const country = request.cf?.country || 'SG';
const flagKey = `apac-feature-flags:${country}`;
// KV read: served from nearest APAC Workers PoP (<1ms latency)
const flagsJson = await env.APAC_FLAGS_KV.get(flagKey);
const flags = flagsJson ? JSON.parse(flagsJson) : {};
// Inject APAC feature flag context into upstream request
const modifiedRequest = new Request(request, {
headers: {
...Object.fromEntries(request.headers),
'X-APAC-Flags': JSON.stringify(flags),
'X-APAC-Country': country,
},
});
return fetch(env.APAC_UPSTREAM, modifiedRequest);
},
};
# wrangler.toml: APAC Workers configuration
name = "apac-edge-worker"
main = "src/index.ts"
compatibility_date = "2026-01-01"
# KV namespace binding for APAC feature flags
[[kv_namespaces]]
binding = "APAC_FLAGS_KV"
id = "a1b2c3d4e5f6..."
# APAC R2 bucket for static asset serving
[[r2_buckets]]
binding = "APAC_ASSETS"
bucket_name = "apac-static-assets"
Deno Deploy: TypeScript-Native APAC Serverless
Why Deno Deploy for APAC TypeScript teams
APAC TypeScript Deployment Comparison:
Node.js + Lambda (APAC):
1. Write TypeScript
2. Configure tsconfig.json
3. Run tsc or esbuild
4. Bundle with webpack/esbuild (handle APAC tree-shaking)
5. Package as Lambda ZIP or Docker
6. Deploy via SAM/CDK/Serverless Framework
Time to deploy: 5-15 minutes; build complexity: high
Deno Deploy (APAC):
1. Write TypeScript
2. git push
Time to deploy: 30 seconds; build complexity: zero
Deno Deploy API handler for APAC
// main.ts: Deno Deploy APAC API handler (TypeScript, no compilation required)
import { serve } from "https://deno.land/[email protected]/http/server.ts";
const kv = await Deno.openKv(); // Deno KV: globally replicated APAC storage
serve(async (req: Request) => {
const url = new URL(req.url);
if (url.pathname === "/apac/rate-limit" && req.method === "POST") {
const body = await req.json() as { ip: string; window: string };
const key = ["apac-rate-limit", body.ip, body.window];
// Atomic increment with Deno KV (replicated across APAC regions)
const result = await kv.atomic()
.mutate({ type: "sum", key, value: new Deno.KvU64(1n) })
.commit();
const current = await kv.get<Deno.KvU64>(key);
const count = Number(current.value?.value ?? 0n);
return Response.json({
ip: body.ip,
count,
allowed: count <= 100, // APAC rate limit: 100 requests per window
region: Deno.env.get("DENO_REGION") || "unknown",
});
}
return new Response("APAC Deno Deploy API", { status: 200 });
});
Deno Deploy project configuration
// deno.json: Deno Deploy APAC project configuration
{
"tasks": {
"dev": "deno run --watch --allow-net --allow-read --allow-env main.ts",
"deploy": "deployctl deploy --project=apac-api-handler main.ts"
},
"imports": {
"std/": "https://deno.land/[email protected]/"
}
}
Fly.io: Docker Containers at APAC Regional Datacenters
Fly.io APAC regional deployment
# fly.toml: APAC multi-region Docker deployment
app = "apac-payments-api"
primary_region = "sin" # Singapore primary
[build]
image = "registry.apac-company.internal/payments-api:latest"
[env]
APAC_REGION = "SEA"
LOG_LEVEL = "info"
[[services]]
internal_port = 8080
protocol = "tcp"
[[services.ports]]
port = 443
handlers = ["tls", "http"]
[services.concurrency]
hard_limit = 200
soft_limit = 150
# APAC regional scaling: run instances close to users
[[vm]]
size = "shared-cpu-2x" # 2 shared vCPU, 512MB RAM
# Deploy APAC application to Fly.io
flyctl deploy --local-only # Build locally, push to Fly.io registry
# Add APAC regional instances (run close to users)
flyctl regions add nrt # Tokyo
flyctl regions add syd # Sydney
flyctl regions add hkg # Hong Kong
# Scale APAC instances per region
flyctl scale count 2 --region sin # 2 instances in Singapore
flyctl scale count 1 --region nrt # 1 instance in Tokyo
flyctl scale count 1 --region syd # 1 instance in Sydney
# Create APAC persistent volume (stateful apps)
flyctl volumes create apac_postgres_data \
--region sin \
--size 20 # 20GB in Singapore
Fly.io for APAC PostgreSQL deployment
# Fly-managed PostgreSQL in Singapore (APAC primary)
flyctl postgres create \
--name apac-postgres \
--region sin \
--initial-cluster-size 2 \
--vm-size shared-cpu-2x \
--volume-size 20
# Attach to APAC application (sets DATABASE_URL environment variable)
flyctl postgres attach apac-postgres --app apac-payments-api
# Enable APAC read replica in Tokyo for read-heavy APAC regional traffic
flyctl postgres add-replica-region apac-postgres nrt
APAC Edge and Serverless Tool Selection
APAC Compute Need → Platform → Why
APAC edge authentication/routing → CF Workers Runs at APAC PoP nearest user;
(JWT validation, geo-routing) → no origin round-trip for APAC auth
APAC static asset serving globally → CF Workers + R2 R2 serves from APAC PoP edge;
with APAC custom logic → no APAC egress fees
APAC TypeScript API without build → Deno Deploy Native TypeScript; git-push
toolchain complexity → deploy; no webpack/esbuild
APAC full-stack app (Next.js, → Fly.io Docker container; persistent
Rust, Go) with persistent data → volumes; any APAC language
APAC WebSocket server or TCP → Fly.io Full VM; persistent TCP;
long-running APAC connections → Workers isolates terminate at req
APAC database (Postgres, SQLite) → Fly.io Fly Postgres + volumes;
close to APAC users → no external APAC DB service
APAC small team, JS/TS-only stack, → CF Workers Lower APAC operational overhead;
already on Cloudflare CDN → single APAC vendor for CDN+compute
Related APAC Platform Engineering Resources
For the container orchestration that Fly.io replaces for APAC teams not ready for Kubernetes, see the APAC Kubernetes platform engineering essentials guide covering vCluster, External Secrets, and ExternalDNS.
For the API gateway tools that sit in front of APAC Workers and Fly.io deployments, see the APAC API gateway guide covering Tyk, Traefik, and KrakenD.
For the supply chain security scanning applied to APAC Workers and Fly.io deployment pipelines, see the APAC supply chain security guide covering Checkov, Gitleaks, and TruffleHog.
Beyond this insight
Cross-reference our practice depth.
If this article matches your stage of thinking, the underlying capabilities ship across all six pillars, ten verticals, and nine Asian markets.