Edge Computing: Deploying Code Closer to Users with Cloudflare Workers | SoniNow Blog

Limited TimeLearn More

edge computingcloudflare workersserverlesscdnperformance

Edge Computing: Deploying Code Closer to Users with Cloudflare Workers

Published

2026-06-23

Read Time

5 mins

Edge Computing: Deploying Code Closer to Users with Cloudflare Workers

Edge computing moves application logic from centralized data centers to points of presence distributed around the world. Cloudflare Workers executes code at over 330 locations globally, putting your logic within 10–50ms of nearly every internet user. The result: sub-millisecond response times for dynamic content that traditionally required a round trip to a single region.

Hello, Cloudflare Workers

A Worker is a JavaScript function that runs on every request at the edge. The runtime supports a subset of Web API standards—Fetch, Request, Response, Cache, Crypto, and TextEncoder—familiar to any JavaScript developer:

// wrangler.jsonc project config
{
  "$schema": "node_modules/wrangler/config-schema.json",
  "name": "edge-api",
  "main": "src/index.js",
  "compatibility_date": "2026-06-01",
  "routes": [
    { "pattern": "api.example.com/*", "zone_id": "abc123" }
  ]
}
// src/index.js
export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);

    if (url.pathname === '/api/hello') {
      const userCountry = request.cf?.country || 'Unknown';
      const userCity = request.cf?.city || 'Unknown';

      return new Response(
        JSON.stringify({
          message: `Hello from ${userCity}, ${userCountry}!`,
          servedBy: request.cf?.colo || 'edge',
          timestamp: Date.now(),
        }),
        {
          headers: {
            'Content-Type': 'application/json',
            'CF-Cache-Status': 'MISS',
          },
        }
      );
    }

    return new Response('Not found', { status: 404 });
  },
};

Deploy with npx wrangler deploy and your function is live at 330+ locations in seconds. The request.cf object provides geolocation data (country, city, continent, longitude/latitude, timezone, AS number) from each edge location—no external geolocation service needed.

Workers KV: Global Key-Value Storage

KV is a low-latency, eventually consistent key-value store designed for high-read workloads. Reads complete in under 10ms at the edge; writes propagate globally within seconds:

// src/index.js
export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);
    const slug = url.pathname.split('/').pop();

    if (request.method === 'GET') {
      // Read from KV - cached at the edge
      const page = await env.CONTENT_KV.get(`page:${slug}`, {
        type: 'json',
        cacheTtl: 300, // Edge cache for 5 minutes
      });

      if (!page) {
        return new Response('Not found', { status: 404 });
      }

      return new Response(JSON.stringify(page), {
        headers: { 'Content-Type': 'application/json' },
      });
    }

    if (request.method === 'PUT') {
      const body = await request.json();
      await env.CONTENT_KV.put(`page:${slug}`, JSON.stringify(body));
      return new Response('Stored', { status: 201 });
    }
  },
};

KV is ideal for: configuration data (feature flags, A/B test assignments), content pages and markdown, user sessions (with short TTLs), and redirect rules. It's not suitable for write-heavy workloads or use cases requiring strong consistency. For those, use Durable Objects.

Durable Objects: Strongly Consistent State at the Edge

Durable Objects (DO) provide strongly consistent, persistent storage with a single-writer pattern. Each DO instance lives in exactly one location, but all Workers can interact with it via global routing:

// src/durable_objects/chatroom.js
export class Chatroom {
  constructor(state, env) {
    this.state = state;
    this.messages = [];
  }

  async fetch(request) {
    if (request.method === 'POST') {
      const { user, message } = await request.json();
      this.messages.push({ user, message, timestamp: Date.now() });

      // Persist to storage
      await this.state.storage.put('messages', this.messages);

      return new Response('OK', { status: 200 });
    }

    return new Response(JSON.stringify(this.messages.slice(-50)), {
      headers: { 'Content-Type': 'application/json' },
    });
  }
}
// wrangler.jsonc - Durable Object binding
{
  "durable_objects": {
    "bindings": [
      { "name": "CHATROOM", "class_name": "Chatroom" }
    ]
  }
}

DO enables use cases that require coordination: multiplayer game state, collaborative document editing (like a CRDT-based approach), real-time counters and leaderboards, and transactional workflows across regions. The trade-off: the DO's single location means operations targeting it incur a network hop if the user is far from that location.

Requests for HTML Rewriting and A/B Testing

Cloudflare's HTMLRewriter is a streaming HTML parser that lets you modify responses without buffering the entire payload:

class LinkRewriter {
  element(element) {
    if (element.getAttribute('href')?.startsWith('/')) {
      element.setAttribute('href', `https://cdn.example.com${element.getAttribute('href')}`);
    }
  }
}

export default {
  async fetch(request, env, ctx) {
    const response = await fetch('https://origin.example.com');

    // A/B test: inject different banner
    const abTest = Math.random() > 0.5 ? 'A' : 'B';
    const bannerHtml = abTest === 'A'
      ? '<div class="banner">New feature is live!</div>'
      : '<div class="banner">Try our new feature</div>';

    return new HTMLRewriter()
      .on('a[href]', new LinkRewriter())
      .on('#banner-slot', {
        element(element) {
          element.replace(bannerHtml, { html: true });
        },
      })
      .transform(response);
  },
};

The HTMLRewriter operates on the response stream as it passes through the edge. There's no buffering overhead, and the transformed response starts arriving at the client with minimal additional latency.

Worker-to-Worker Communication and Service Bindings

Service bindings allow one Worker to call another without going through the public internet:

// wrangler.jsonc
{
  "services": {
    "bindings": [
      {
        "name": "AUTH_SERVICE",
        "service": "edge-auth",
        "environment": "production"
      }
    ]
  }
}
// Inside a Worker
export default {
  async fetch(request, env) {
    // Call auth service via service binding (no network call)
    const authResponse = await env.AUTH_SERVICE.fetch(
      new Request('https://internal/auth', {
        method: 'POST',
        headers: request.headers,
      })
    );

    if (authResponse.status !== 200) {
      return new Response('Unauthorized', { status: 401 });
    }

    return env.ASSETS.fetch(request);
  },
};

Service bindings route through Cloudflare's internal network—there's no public DNS resolution, no TLS termination overhead, and latency is measured in microseconds rather than milliseconds.

Edge Caching Integration

Combine Workers with Cloudflare's cache for maximum performance:

export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);
    const cacheKey = new Request(
      url.toString(),
      request
    );
    const cache = caches.default;

    // Try edge cache first
    let response = await cache.match(cacheKey);
    if (response) {
      response.headers.set('X-Cache', 'HIT');
      return response;
    }

    // Generate response
    response = await generateResponse(request);
    response.headers.set('X-Cache', 'MISS');

    // Store in edge cache
    ctx.waitUntil(cache.put(cacheKey, response.clone()));
    return response;
  },
};

The Cache API gives programmatic control over what gets cached and for how long. Use ctx.waitUntil to perform cache writes asynchronously without blocking the response.

Deploy at the Edge with SoniNow

Edge computing with Cloudflare Workers brings application logic closer to users than ever before, slashing latency for dynamic content. Our team at SoniNow builds edge-native applications that leverage Workers, KV, and Durable Objects for global performance.