How One Day of Work Reduced Our Server Load by 70% for Free

Introduction

Managing server load is a constant battle in web development. As your application scales and traffic spikes, your servers can buckle under the pressure, leading to slow response times, frustrated users, and ballooning hosting costs. We faced this exact challenge with our API, which was struggling to keep up with demand. We needed a solution that was fast to implement, cost-effective, and powerful enough to make a real difference.

Enter Cloudflare Workers. In just one day, we implemented a caching solution that reduced our server load by an astonishing 70%—and it cost us next to nothing. This article will walk you through how we did it, showcasing my expertise with a detailed step-by-step guide, real-world code examples, and a comparison to traditional caching options like Redis. If you’re looking to optimize your API performance without breaking the bank, keep reading.


Why Cloudflare Workers?

Cloudflare Workers are a lightweight, serverless platform that lets you run JavaScript at the edge—close to your users—across Cloudflare’s global network. This proximity reduces latency, but the real magic lies in their caching capabilities. For APIs, especially GraphQL ones like ours, caching responses at the edge can offload massive amounts of work from your origin servers.

Our GraphQL API was handling complex queries that often hit the database multiple times per request. By caching frequent, stable queries, we could serve responses directly from Cloudflare’s edge, bypassing our servers entirely. This not only cut server load but also sped up response times for users worldwide. Compared to other caching solutions, Cloudflare Workers stood out for their simplicity, cost (free tier included), and zero-maintenance edge infrastructure.


Setting Up Cloudflare Workers: A Step-by-Step Guide

Getting started with Cloudflare Workers is surprisingly easy. Here’s how we set it up for our API endpoint in under a day:

  1. Sign Up for Cloudflare
    If you don’t have an account, head to cloudflare.com and sign up. The free plan includes Workers, making this a no-cost experiment.

  2. Access the Workers Dashboard
    Log in to your Cloudflare dashboard, navigate to the Workers tab on the left, and click Create a Worker. You’ll land in a simple editor where you can write your script.

  3. Write the Worker Script
    This is where you define the caching logic. We’ll dive into the code in the next section, but for now, know that you’ll paste it here. Name your worker something memorable, like api-caching-worker.

  4. Configure the Route
    After saving your script, go to the Triggers tab in the Workers section. Click Add Route and specify the URL pattern you want the worker to handle. For our GraphQL API at https://api.example.com/graphql, we set the route to https://api.example.com/graphql*. The asterisk ensures it catches all subpaths. Save it.

  5. Deploy the Worker
    Back in the editor, hit Save and Deploy. Your worker is now live, intercepting requests to the specified endpoint and applying your caching logic.

That’s it—setup took us less than an hour. The real effort came in tweaking the script, which we’ll cover next.


The Code: Caching GraphQL Responses

Below is the Cloudflare Worker script we used, adapted with generic endpoints for broader applicability. This script caches specific GraphQL queries to slash server load.

addEventListener("fetch", event => {
  event.respondWith(handleRequest(event));
});

async function handleRequest(event) {
  const request = event.request;
  const cache = caches.default;

  if (request.method === "POST") {
    try {
      const clonedRequest = request.clone();
      const body = await clonedRequest.json();

      console.log("📝 Parsed Body:", JSON.stringify(body));

      // Ensure query exists
      if (!body.query || body.query.trim() === "") {
        return new Response("GraphQL operations must contain a non-empty `query`", { status: 400 });
      }

      // Define cacheable queries
      const cacheableQueries = ["GetItems", "GetCategories", "GetDetails"];
      const operationName = body.operationName || "unknown_operation";

      if (cacheableQueries.includes(operationName)) {
        // Generate a unique cache key
        const cacheKey = new URL(request.url);
        cacheKey.searchParams.set("graphql-query", btoa(JSON.stringify(body)));

        // Check for cached response
        let cachedResponse = await cache.match(cacheKey);
        if (cachedResponse) {
          console.log(`✅ Cache Hit: ${operationName}`);
          return cachedResponse;
        }

        console.log(`🚀 Cache Miss: Fetching from Origin`);

        // Fetch from origin if not cached
        let response = await fetch("https://api.example.com/graphql", {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
            "Authorization": request.headers.get("Authorization") || "",
            "Accept": "*/*"
          },
          body: JSON.stringify(body),
        });

        // Cache the response if successful
        if (response.ok) {
          console.log(`🟢 Successfully fetched ${operationName}, caching now...`);
          response = new Response(response.body, response);
          response.headers.append("Cache-Control", "public, max-age=2592000"); // Cache for 30 days

          event.waitUntil(cache.put(cacheKey.toString(), response.clone()));
        }

        return response;
      }
    } catch (error) {
      console.log("❗ Worker Error:", error);
      return new Response("Internal Worker Error", { status: 500 });
    }
  }

  // Pass through non-cached requests
  return fetch(request);
}

How It Works

  • Event Listener: The fetch event triggers handleRequest for every incoming request.
  • POST Handling: Since GraphQL APIs typically use POST, we focus on those requests.
  • Body Parsing: We clone and parse the request body to extract the GraphQL query and operation name.
  • Cacheable Queries: We list operations like GetItems that are safe to cache (stable, read-only data).
  • Cache Key: A unique key is created using the URL and encoded query body, ensuring different queries don’t collide.
  • Cache Check: If a cached response exists, it’s returned instantly—bam, no server hit!
  • Origin Fetch: On a cache miss, we fetch from https://api.example.com/graphql, cache the response if successful (with a 30-day TTL), and return it.
  • Error Handling: Any hiccups trigger a 500 response with logging for debugging.

This script targets high-traffic, stable queries, slashing server requests dramatically.


The Results: 70% Server Load Reduction

Deploying this worker was a game-changer. Within hours, our server load plummeted by 70%. Here’s why:

  • Fewer Origin Hits: Cached responses served from Cloudflare’s edge meant most requests never reached our servers.
  • Faster Responses: Edge delivery cut latency, delighting users with near-instant replies.
  • Cost Savings: Reduced server strain let us scale back resources, all while staying within Cloudflare’s free tier.

The one-day investment—mostly spent refining the script and testing—paid off instantly. Our API went from gasping to thriving, all for free.


Cloudflare Workers vs. Traditional Caching (Like Redis)

We already use Redis for some caching, and it’s fantastic—fast, reliable, and flexible. But it’s not perfect for every scenario, especially compared to Cloudflare Workers. Here’s how they stack up:

Cost

  • Redis: Requires dedicated servers or cloud instances (e.g., AWS ElastiCache), costing $20–$100+/month depending on scale. Add in setup and licensing fees, and it’s a hefty investment.
  • Cloudflare Workers: Free tier covers 100,000 requests/day. Even paid plans are usage-based and cheap—pennies compared to Redis.

Setup Time

  • Redis: Hours to days. You need to provision servers, install Redis, configure replication, and test failover. We spent a week getting ours production-ready.
  • Cloudflare Workers: Minutes. Sign up, write a script, deploy—done in a day, as we proved.

Maintenance

  • Redis: Ongoing. Monitor memory usage, handle scaling, patch updates—it’s a job. Our ops team spends hours monthly on it.
  • Cloudflare Workers: None. Cloudflare manages the infrastructure. We just write the code and forget it.

Performance

  • Redis: Blazing fast, but caches on the server side. Requests still travel to your data center, adding latency.
  • Cloudflare Workers: Edge caching serves responses from 300+ global locations, cutting latency to near zero.

For our API, where edge delivery and cost were key, Workers won. Redis still shines for dynamic, server-side caching, but it couldn’t match this use case’s simplicity and savings.


Need Help with Setup?

Reach me on LinkedIn: https://www.linkedin.com/in/radek-fabisiak/.

Conclusion

In just one day, Cloudflare Workers transformed our API performance, slashing server load by 70% for virtually no cost. This wasn’t a fluke—it’s a testament to smart, edge-based caching and my team’s ability to execute fast. The step-by-step guide and code above give you everything you need to replicate this win.

If your servers are groaning under API traffic, don’t overcomplicate it with expensive setups like Redis (great as they are). Try Cloudflare Workers. Tweak the script for your endpoints, deploy it, and watch the load melt away. One day’s work could save you months of headaches—and a chunk of your budget.