How I migrated my Next.js site from Vercel + Supabase to Cloudflare Workers + D1 Database, cutting costs by 75% while eliminating database downtime.
I recently completed a full platform migration for CTK Advisors, moving from Vercel Pro and Supabase to Cloudflare Workers with D1 Database. The migration reduced monthly costs from $20 to $5 while eliminating the database downtime issues I was experiencing with Supabase's free tier.
My setup was costing $20/month for Vercel Pro, plus dealing with Supabase's free tier limitations. The main pain point was database pausing - my contact form would randomly fail when the database went to sleep, creating a poor user experience. I needed a solution that was both more reliable and cost-effective.
Cloudflare's edge platform offered everything I needed:
The total cost? $5/month for the Workers Paid plan, with generous included quotas that cover my usage completely.
The biggest challenge was migrating from PostgreSQL (Supabase) to SQLite (D1). I created a new schema optimized for D1:
CREATE TABLE IF NOT EXISTS contact_submissions (
id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
name TEXT NOT NULL,
email TEXT NOT NULL,
subject TEXT NOT NULL,
project_type TEXT NOT NULL,
budget_range TEXT,
message TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'new',
submitted_at DATETIME DEFAULT CURRENT_TIMESTAMP,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);One of the key improvements was implementing a robust fallback system:
This ensures the contact form never completely fails, even if there are infrastructure issues.
The trickiest part was accessing Cloudflare's environment in Next.js server actions. The solution was using the context symbol:
function getCloudflareEnv(): CloudflareEnv {
const context = (globalThis as any)[Symbol.for("__cloudflare-context__")];
if (context && context.env) {
return context.env;
}
throw new Error("Cloudflare environment not available");
}I replaced external monitoring with a KV-based logging system that automatically rotates logs and provides structured error tracking:
export class CloudflareLogger {
constructor(private logsKV: KVNamespace) {}
async log(
level: "info" | "warn" | "error",
message: string,
context?: Record<string, any>
) {
const entry = {
id: crypto.randomUUID(),
level,
message,
timestamp: new Date().toISOString(),
context,
};
const logKey = `log_${Date.now()}_${entry.id}`;
await this.logsKV.put(logKey, JSON.stringify(entry), {
expirationTtl: 30 * 24 * 60 * 60, // 30 days
});
}
}The migration involved several steps:
The domain switch was seamless - I simply removed the existing DNS records pointing to Vercel and deployed the Worker with custom domain configuration.
The results have been impressive:
Before (Monthly):
After (Monthly):
Annual Savings: $180
I built this migration using Kiro's structured approach: design → requirements → tasks → implement. Instead of jumping straight into code, Kiro forces you through a methodical process that catches issues early.
Design Phase: I described the migration goal - move from Vercel + Supabase to Cloudflare Workers + D1, reduce costs, eliminate database downtime. Kiro analyzed the current architecture and proposed the new structure.
Requirements Gathering: Kiro broke down what needed to happen:
Task Planning: Each requirement became specific implementation tasks with dependencies mapped out. Database migration before environment setup, logging before deployment, etc.
Agentic Implementation: Rather than me writing everything manually, Kiro generated the code, configurations, and deployment scripts. I reviewed and adjusted, but didn't start from scratch.
The structured flow identified problems I would have hit later:
Without the upfront design work, I would have discovered these issues during deployment or worse, in production. The agentic implementation meant I got working code faster, but the real value was the systematic thinking that prevented problems.
Absolutely. The combination of cost savings, improved reliability, and better performance makes this migration a clear win. The initial time investment paid off immediately.
If you're considering a similar migration:
For most small to medium applications, Cloudflare Workers provides better value and reliability than traditional hosting platforms. The edge-first architecture and integrated services create a compelling alternative to the typical Vercel + external database setup.
The migration took about a day of focused work, but the ongoing benefits in cost, performance, and reliability make it one of the best technical decisions I've made for CTK Advisors.