Cloudflare Workers run JavaScript at the edge — 300+ data centers, sub-millisecond cold starts, and a powerful runtime API.
Workers: Zero Cold Start
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
if (url.pathname === "/api/data") {
const data = await env.DB.prepare("SELECT * FROM products LIMIT 20").all();
return Response.json(data.results);
}
if (url.pathname === "/api/scrape") {
const { targetUrl } = await request.json();
const html = await fetch(targetUrl).then(r => r.text());
return Response.json({ length: html.length, preview: html.slice(0, 500) });
}
return new Response("Not Found", { status: 404 });
},
};
D1: SQLite at the Edge
// wrangler.toml
// [[d1_databases]]
// binding = "DB"
// database_name = "scraping-db"
export default {
async fetch(request, env) {
// Parameterized queries
const products = await env.DB
.prepare("SELECT * FROM products WHERE price < ? ORDER BY scraped_at DESC")
.bind(50)
.all();
// Batch operations
const batch = await env.DB.batch([
env.DB.prepare("INSERT INTO products (title, price) VALUES (?, ?)").bind("Widget", 29.99),
env.DB.prepare("UPDATE stats SET total = total + 1"),
]);
return Response.json(products.results);
},
};
R2: S3-Compatible Object Storage
export default {
async fetch(request, env) {
const url = new URL(request.url);
const key = url.pathname.slice(1);
if (request.method === "PUT") {
await env.BUCKET.put(key, request.body, {
httpMetadata: { contentType: request.headers.get("content-type") },
});
return new Response("Uploaded");
}
if (request.method === "GET") {
const object = await env.BUCKET.get(key);
if (!object) return new Response("Not Found", { status: 404 });
return new Response(object.body, {
headers: { "content-type": object.httpMetadata?.contentType || "application/octet-stream" },
});
}
},
};
KV: Global Key-Value Store
// Read (cached globally)
const value = await env.KV.get("config", "json");
// Write with TTL
await env.KV.put("cache:products", JSON.stringify(data), { expirationTtl: 3600 });
// List keys
const { keys } = await env.KV.list({ prefix: "cache:" });
Durable Objects: Stateful Edge
export class ScrapingSession {
state: DurableObjectState;
constructor(state: DurableObjectState) {
this.state = state;
}
async fetch(request: Request) {
const count = (await this.state.storage.get("count")) || 0;
await this.state.storage.put("count", count + 1);
return Response.json({ scrapeCount: count + 1 });
}
}
Queues: Background Processing
export default {
async fetch(request, env) {
await env.SCRAPE_QUEUE.send({ url: "https://example.com", priority: "high" });
return new Response("Queued");
},
async queue(batch, env) {
for (const message of batch.messages) {
const { url } = message.body;
const result = await scrape(url);
await env.DB.prepare("INSERT INTO results (url, data) VALUES (?, ?)").bind(url, JSON.stringify(result)).run();
message.ack();
}
},
};
Edge-powered scraping? My Apify tools complement Workers for global data collection.
Custom edge solution? Email spinov001@gmail.com
Top comments (0)