Cloudflare's Free Tier Is Absurdly Generous
Most developers don't realise how much Cloudflare gives away for free. Here's the complete picture:
| Service | Free Allowance | Equivalent Paid Service |
|---|---|---|
| Pages | Unlimited requests, unlimited bandwidth | Vercel Pro ($20/mo) |
| Workers | 100,000 requests/day | AWS Lambda ($0.20/million) |
| R2 Storage | 10GB storage, 10M reads/month | AWS S3 (~$1/month for same) |
| D1 Database | 5GB, 5M reads/day | PlanetScale Free tier |
| KV Storage | 100,000 reads/day, 1,000 writes/day | Redis Cloud Free |
| DNS | Unlimited | Route53 ($0.50/zone/month) |
| SSL | Unlimited | Certbot (free but self-managed) |
| Analytics | Basic analytics | Google Analytics (free) |
| DDoS Protection | Full | Cloudflare Magic Transit ($) |
| CDN | Global 300+ PoPs | Fastly, Akamai ($$$) |
The cost to host 10 small projects on Cloudflare: $0/month.

Project 1: Static Site or Blog (Pages)
# Deploy any static site or Next.js app
wrangler pages deploy ./out --project-name my-blog
Or connect via GitHub:
- Push code to GitHub
- Cloudflare Pages dashboard → Create Project → Connect to Git
- Set build command and output directory
- Deploy
Supports: Next.js, Astro, Hugo, Gatsby, SvelteKit, plain HTML/CSS.
Project 2: API Server (Workers)
// worker.js
export default {
async fetch(request) {
const url = new URL(request.url)
if (url.pathname === '/api/ping') {
return Response.json({ pong: true, time: Date.now() })
}
return new Response('Not found', { status: 404 })
}
},
wrangler deploy
# Live at: https://my-worker.your-username.workers.dev
Project 3: File Storage (R2)
R2 is S3-compatible object storage. Use it to store user uploads, generated files, or media.
# Create a bucket
wrangler r2 bucket create my-uploads
# wrangler.toml
[[r2_buckets]]
binding = "UPLOADS"
bucket_name = "my-uploads"
// Upload a file
export default {
async fetch(request, env) {
if (request.method === 'PUT') {
const key = new URL(request.url).pathname.slice(1)
const body = await request.arrayBuffer()
await env.UPLOADS.put(key, body)
return Response.json({ key, url: `https://files.yourdomain.com/${key}` })
}
if (request.method === 'GET') {
const key = new URL(request.url).pathname.slice(1)
const object = await env.UPLOADS.get(key)
if (!object) return new Response('Not found', { status: 404 })
return new Response(object.body, { headers: { 'Content-Type': object.httpMetadata.contentType } })
}
}
},
Project 4: Scheduled Background Jobs (Workers Cron)
# wrangler.toml
[triggers]
crons = ["0 9 * * 1"] # Every Monday at 9am UTC
export default {
async scheduled(event, env, ctx) {
// This runs automatically on the cron schedule
console.log('Weekly job running:', new Date().toISOString())
// Example: update exchange rates, send digest emails, clean old data
const rates = await fetch('https://api.exchangerate-api.com/v4/latest/USD').then(r => r.json())
await env.KV.put('exchange-rates', JSON.stringify(rates), { expirationTtl: 86400 })
console.log('Exchange rates updated')
}
},
Managing Multiple Projects
Naming Convention
my-name-project1-api ← Worker: API for project 1
my-name-project1-site ← Pages: Frontend for project 1
my-name-project1-files ← R2: Storage for project 1
my-name-project1-db ← D1: Database for project 1
my-name-project2-api
my-name-project2-site
...
Custom Domains (Free SSL Included)
For every project:
- Add your domain to Cloudflare (free DNS management)
- In Pages: Settings → Custom Domains → Add
- In Workers: Triggers → Add Custom Domain
SSL certificates are issued automatically and renewed forever for free.
Monitoring With Free Tools
| Tool | What It Monitors | Cost |
|---|---|---|
| Cloudflare Analytics | Requests, errors, latency | Free (built-in) |
| UptimeRobot | Uptime, downtime alerts | Free (50 monitors) |
| Sentry Free | Error tracking | Free (5k errors/month) |
| Better Stack | Logs + uptime | Free tier available |
When to Leave the Free Tier
| Trigger | Upgrade To | Cost |
|---|---|---|
| Workers > 100k req/day | Workers Paid | $5/month |
| R2 > 10GB | R2 Paid | $0.015/GB/month |
| Need Worker > 10ms CPU | Workers Paid | $5/month |
| Pages build minutes exhausted | Pages Pro | $20/month |
Most indie projects never leave the free tier. The 100,000 requests/day limit on Workers is roughly 3 requests per second sustained — enough for thousands of daily users.

