Cloudflare Workers can connect to external services, but they don’t directly make outgoing HTTP requests like a traditional server. Instead, they use a specific API to request that Cloudflare’s edge infrastructure make the request on their behalf.

Let’s see this in action. Imagine you have a Worker that needs to fetch data from an external API.

// Example Worker script (worker.js)
export default {
  async fetch(request, env, ctx) {
    // This is the key: `fetch` on the global scope is provided by Workers
    // and tells Cloudflare's edge to make the outgoing request.
    const response = await fetch('https://api.example.com/data');

    if (!response.ok) {
      throw new Error(`External API error: ${response.status}`);
    }

    const data = await response.json();
    return new Response(JSON.stringify(data), {
      headers: { 'content-type': 'application/json' },
    });
  },
};

When this worker.js script is deployed to Cloudflare Workers, the fetch function isn’t the one running in your browser or on a Node.js server. It’s a special fetch provided by the Workers runtime environment. This runtime intercepts the call to fetch, takes the URL, headers, and body, and dispatches an actual HTTP request from one of Cloudflare’s edge data centers to https://api.example.com/data. The response from api.example.com is then returned to the Worker script, which can process it and return its own response back to the original client that invoked the Worker.

The core problem Workers solve here is enabling serverless logic to interact with the outside world without requiring you to provision or manage any servers. The "edge" aspect means these outgoing requests originate from a location geographically close to your users, reducing latency. You control what data is fetched and how it’s processed, but Cloudflare manages the network infrastructure for making the actual connection.

The fetch API in Workers is designed to be familiar to developers who have used it in browsers or Node.js. You can make GET, POST, PUT, DELETE, and other HTTP methods. You can set custom headers, send JSON payloads, and handle response streams. The env object in the fetch handler can be used to bind external services, like KV namespaces or Durable Objects, but for simple HTTP requests, the global fetch is the primary mechanism.

One significant difference from traditional server-side HTTP clients is that Workers have strict outbound connection limits. By default, a Worker can only initiate one outbound request per incoming request. If your Worker needs to fetch data from multiple external services, you’ll need to chain them sequentially within the Worker script, or use a more advanced pattern like fetching from one service and then using a Response.redirect() or a Worker-to-Worker communication pattern if the services are also hosted on Cloudflare.

The most surprising thing about Workers’ fetch is how it abstracts away the network stack. You’re not dealing with sockets, TCP handshakes, or DNS resolution directly. You provide a URL and Cloudflare’s edge handles the rest, including TLS termination, load balancing, and routing to the appropriate origin. This allows Workers to be incredibly fast and efficient because they don’t incur the overhead of a traditional server’s network stack.

The next frontier is understanding how to manage more complex inter-service communication patterns, like asynchronous background tasks or coordinating multiple outgoing requests in parallel without hitting the single-request limit.

Want structured learning?

Take the full Neon course →