Cloudflare Workers run JavaScript at the edge in 300+ locations — with 100K free requests per day and 0ms cold starts.
Basic Worker
export default {
async fetch(request, env) {
const url = new URL(request.url)
if (url.pathname === '/api/hello') {
return Response.json({ message: 'Hello from the edge!' })
}
if (url.pathname === '/api/geo') {
return Response.json({
country: request.cf.country,
city: request.cf.city,
timezone: request.cf.timezone
})
}
return new Response('Not Found', { status: 404 })
}
}
KV — Global Key-Value Store
export default {
async fetch(request, env) {
// Write
await env.MY_KV.put('user:123', JSON.stringify({ name: 'John' }), {
expirationTtl: 3600 // 1 hour
})
// Read (cached globally, <10ms)
const user = await env.MY_KV.get('user:123', 'json')
// List keys
const list = await env.MY_KV.list({ prefix: 'user:' })
return Response.json(user)
}
}
D1 — SQLite at the Edge
export default {
async fetch(request, env) {
// Query
const { results } = await env.DB.prepare(
'SELECT * FROM users WHERE active = ?'
).bind(true).all()
// Insert
await env.DB.prepare(
'INSERT INTO users (name, email) VALUES (?, ?)'
).bind('John', 'john@test.com').run()
// Batch
await env.DB.batch([
env.DB.prepare('INSERT INTO logs (msg) VALUES (?)').bind('Event 1'),
env.DB.prepare('INSERT INTO logs (msg) VALUES (?)').bind('Event 2')
])
return Response.json(results)
}
}
R2 — S3-Compatible Storage
export default {
async fetch(request, env) {
if (request.method === 'PUT') {
const body = await request.arrayBuffer()
await env.MY_BUCKET.put('uploads/file.pdf', body, {
httpMetadata: { contentType: 'application/pdf' }
})
return Response.json({ uploaded: true })
}
if (request.method === 'GET') {
const object = await env.MY_BUCKET.get('uploads/file.pdf')
if (!object) return new Response('Not Found', { status: 404 })
return new Response(object.body, {
headers: { 'Content-Type': object.httpMetadata.contentType }
})
}
}
}
Durable Objects — Stateful Edge
export class ChatRoom {
constructor(state, env) {
this.state = state
this.sessions = []
}
async fetch(request) {
const [client, server] = Object.values(new WebSocketPair())
this.sessions.push(server)
server.accept()
server.addEventListener('message', (msg) => {
for (const session of this.sessions) {
if (session !== server) session.send(msg.data)
}
})
return new Response(null, { status: 101, webSocket: client })
}
}
Real-World Use Case
An API company needed to add geolocation-based routing with <10ms latency globally. Traditional approach: servers in 5 regions, DNS-based routing, $500/month. Cloudflare Workers: code runs in 300+ locations automatically, request.cf gives location data, KV caches responses globally. Cost: $0 (free tier) to $5/month. Latency: <5ms everywhere.
Cloudflare Workers made the edge accessible to everyone.
Build Smarter Data Pipelines
Need to scrape websites, extract APIs, or automate data collection? Check out my ready-to-use scrapers on Apify — no coding required.
Custom scraping solution? Email me at spinov001@gmail.com — fast turnaround, fair prices.
Top comments (0)