NJIT Logo YWCC Capstone Sponsors
Diagram of three program websites all running on Cloudflare services for $15 per month
Program News

How We Use Cloudflare to Run Three Websites for $15/Month

By Jay Singh

One platform, seven Cloudflare services

If you strip away the CMS and the frontend framework, everything in the YWCC Capstone and RWC platform runs on Cloudflare. Not because we wanted to be locked in, but because the free and near-free tiers align perfectly with a low-budget academic project that needs to scale to real traffic.

This article is a tour of every Cloudflare service we use, what role each one plays, and the specific constraints that led us to pick it.

Cloudflare Pages — static hosting for the public site

Every public page on all three sites is statically generated by Astro at build time and served by Cloudflare Pages. Pages gives us:

  • Free static hosting with unlimited bandwidth
  • Native preview deployments from every branch and pull request
  • Automatic HTTPS and a global edge network
  • Git integration so every push to main rebuilds and deploys automatically

Each of the three program sites (Capstone, RWC US, RWC International) has its own independent Cloudflare account with its own Pages project pointing at the shared GitHub repository. Environment variables parameterize the build for each site.

Cloudflare Workers Paid — SSR for the Sponsor Portal

The public pages are static, but the Sponsor Portal needs authentication, database access, and real-time data. Astro's hybrid output lets us opt specific routes into server-side rendering by adding export const prerender = false, and those routes run as Cloudflare Workers.

Cloudflare Workers Paid ($5/month) gives us:

  • 10 million requests per month included
  • 50ms CPU per request (far more than we need — portal routes average 3–6ms)
  • 5 minute max invocation time for long-running operations
  • Access to bindings for D1, KV, Durable Objects, Workers AI, and Queues

The $5/month is the only recurring cost per site. Three sites = $15/month total for all infrastructure.

Cloudflare D1 — SQLite at the edge for portal auth

The Sponsor Portal uses Better Auth for Google OAuth, GitHub OAuth, and Magic Link sign-in. Better Auth needs a database for session storage and user records, and Cloudflare D1 (edge SQLite) is the natural fit:

  • 5 million row reads per day on the free tier
  • 100,000 row writes per day on the free tier
  • Serverless — no provisioning or scaling
  • Managed via Drizzle ORM for type-safe queries

Because D1 is SQLite, the schema is versioned in migration files in the repo. Running migrations during deploy keeps every environment in sync without any DBA work.

Cloudflare KV — session cache and fast lookups

For data that doesn't need SQL's relational guarantees — session tokens, rate limit counters, cached API responses — we use Cloudflare KV. KV is eventually-consistent key-value storage with 100,000 reads per day on the free tier, which is plenty for a portal that serves a few hundred sponsors.

Cloudflare Durable Objects — rate limiting that actually works

Sliding-window rate limiting is surprisingly hard without persistent per-client state. We use a Cloudflare Durable Object (a single-instance stateful Worker) as a dedicated rate-limiter deployed as a separate worker (rate-limiter-worker/). The portal middleware forwards the client IP to this worker and gets back an allow/deny response.

The rate-limiter enforces 100 requests per 60 seconds per IP on portal routes. Because Durable Objects guarantee single-instance state, we get consistent counts without race conditions even under bursty traffic.

Cloudflare AI Search + @cloudflare/ai-search-snippet — zero-cost chatbot

The AI chatbot visible on public pages is powered by Cloudflare AI Search (previously called NLWeb Worker) and the @cloudflare/ai-search-snippet web component. Here's what that means in practice:

  • The NLWeb Worker indexes our site content autonomously — no custom RAG pipeline, no vector database to manage, no embeddings to generate
  • The chat bubble widget is a web component (@cloudflare/ai-search-snippet) that renders in a shadow DOM and hits the NLWeb endpoint directly
  • Editors control visibility via a siteSettings.aiSearch toggle in Sanity Studio — we can enable or disable the chatbot per site without a code deploy
  • Zero incremental cost on top of the existing Workers Paid plan

This replaces what would otherwise be a custom pipeline with OpenAI embeddings, Pinecone, and a custom chat API. Instead we get AI-grounded answers about our program with literally zero code to maintain.

Cloudflare Turnstile — invisible CAPTCHA for forms

The sponsor inquiry form and contact form are protected by Cloudflare Turnstile, an invisible CAPTCHA that replaces reCAPTCHA. Turnstile:

  • Runs entirely in the browser with no user interaction in most cases
  • Is free and unlimited
  • Integrates cleanly with Astro Actions on the backend
  • Produces a token that we verify server-side before accepting the submission

Form submissions also trigger a Discord webhook notification so the team is alerted to new sponsor inquiries in real time.

Cloudflare Queues — the event bus (for Team B's API)

The Aggregated Platform API (delivered by Team B as part of Scope Document 2) uses Cloudflare Queues as an asynchronous event bus. When a form is submitted, or a content change webhook fires, or a scheduled task runs, events are pushed onto a Queue and consumed by downstream workers. This keeps the request/response path fast while still supporting complex async workflows.

Cost breakdown

ServiceCostNotes
Cloudflare Pages (3 projects)$0Free tier, unlimited bandwidth
Cloudflare Workers Paid (3 accounts)$15/month$5/month per site × 3
Cloudflare D1$0Free tier (5M reads/day)
Cloudflare KV$0Free tier (100k reads/day)
Cloudflare Durable Objects$0Included in Workers Paid
Cloudflare AI Search + NLWeb$0Included in Workers Paid
Cloudflare Turnstile$0Free and unlimited
Cloudflare Queues$0Included in Workers Paid
Total$15/monthFor 3 production sites

Why Cloudflare?

We picked Cloudflare over AWS, Vercel, and Netlify for one overriding reason: the free tiers and unit economics match a student project budget. AWS free tier expires after 12 months. Vercel's free tier has bandwidth limits that make it unsafe for a public-facing site. Netlify's paid tier starts at $19/month per site.

Cloudflare's model — free static hosting + a fixed $5/month per Workers-enabled site — gives us predictable costs with real headroom. And the fact that everything (D1, KV, Workers AI, AI Search, Turnstile, Queues) lives behind the same wrangler CLI and the same bindings model means there's one mental model to learn instead of seven different AWS service SDKs.

In the next article, we'll go deeper into the multi-site architecture and how we use the same codebase to deploy to three independent Cloudflare accounts without cross-contamination.

Video thumbnail: Video

Stay updated

Subscribe for new articles delivered to your inbox.

Related Articles

← Back to Articles