Moving a legacy commerce platform to Cloudflare Workers
Static front-end on Pages, API on Workers, D1 for reads and R2 for files. p95 latency from 190ms to 68ms and the server contract ended.
- Role
- IT consultant — architecture, migration, handover
- Year
- 2026
- Client
- Retail client, Kathmandu
The situation
A small internal tool on a Singapore VPS. Read-mostly, forty thousand rows, no heavy writes. Paying for a server around the clock to serve traffic that peaked during a two-hour window each morning.
Why not just optimise the server
Honestly, they could have. The server was not wrong. But three things tipped it:
The split
Read-mostly and file-heavy, which is exactly where edge execution wins:
- Static assets → Pages, cached at the edge
- Read API → Workers + D1, served from the nearest PoP
- Files → R2, never through the database
- Writes → a single Worker with D1’s transaction model respected, not worked around
import { z } from 'astro:schema';
const OrderQuery = z.object({
customerId: z.string().uuid(),
since: z.coerce.date().optional(),
});
export async function GET({ request, env }: ExportedHandler<Env>) {
const url = new URL(request.url);
const parsed = OrderQuery.safeParse(Object.fromEntries(url.searchParams));
if (!parsed.success) return Response.json({ error: 'bad_request' }, { status: 400 });
const { customerId, since } = parsed.data;
return Response.json(
await env.DB.prepare(
'SELECT id, placed_at, total FROM orders WHERE customer_id = ?1 AND placed_at >= ?2 ORDER BY placed_at DESC',
)
.bind(customerId, since ?? new Date(0))
.all(),
);
}
Result
68ms
p95 after
3
Servers removed
£0
Fixed monthly
14 days
Elapsed
What I’d raise with a different client
More work
Building internal AI tooling on a budget
An interactive workshop for engineers at Nepali companies. Hands-on, tool-agnostic, and deliberately sceptical of autonomous pipelines.
Delivered to 4 cohorts · 90 participants
- Claude Code
- MCP
- Python
- GitHub Actions
Invoice document extraction pipeline
Confidential client · IT consultant — design and build
R2 → rasterise → structured extraction → arithmetic validation → confidence-gated review queue. Running in production for a services business since early 2026.
1,500 invoices/month · ~92% auto-cleared · ~$40/month model spend
- Claude
- R2
- Python
- D1
- +1
Runbook templates that actually get followed
The four-part structure, the confirm-before-acting rule, and the quarterly cold-reader test. Used on every engagement since 2024.
Median time-to-resolve 38min → 17min
- Bash
- Markdown
- systemd
- Prometheus
Published by Sudeep Dhakal, IT Consultant.