How to Use Proxies With Cloudflare Workers 2026

Learn how to use proxies with Cloudflare Workers in 2026: why fetch has no proxy option, plus provider APIs, TCP sockets, secrets, caching, and working code.

Author
ProxyHorizon Team
Published
June 26, 2026
13 min read
Expert-Verified

Cloudflare Workers run your code on a global edge network in milliseconds — but the moment you try to route a request through a proxy, you hit a wall. Unlike Node.js, the Workers runtime has no way to attach a proxy agent to fetch, so the usual IP:port approach simply does not work.

That trips up a lot of developers, because Workers are perfect for scraping and data tasks: they are fast, cheap, and run from 300+ locations worldwide. With automated traffic now making up nearly half of all web activity according to Imperva, doing that work from the edge without getting blocked means pairing Workers with proxies the right way.

This guide covers every viable method to use proxies with Cloudflare Workers in 2026 — from the simple provider-API pattern to raw TCP sockets — with working code, a clear comparison, and the pitfalls to avoid. If proxies are new to you, start with our primer on what proxies are.

Why You Cannot Use Proxies in Workers the Normal Way

In Node.js you would pass an http or https agent (or use a library like https-proxy-agent) to send a request through a proxy. The Cloudflare Workers runtime is not Node — its fetch implementation has no agent or proxy option at all.

That means a traditional rotating residential proxy in IP:port form cannot be plugged directly into a Worker. Instead, you work around it by calling a provider that does the proxying for you, or by dropping down to raw TCP sockets. Here is what works and what does not.

ApproachWorks in Workers?Note
fetch with an http(s) proxy agent / IP:portNoWorkers fetch has no agent or proxy option
Provider HTTPS API (Web Unlocker, Scraper API)YesRecommended for most use cases
URL-based scraper API (pass target as a parameter)YesSimplest possible setup
Raw TCP sockets via cloudflare:sockets connect()Yes (advanced)You handle CONNECT, TLS, and HTTP manually
Route through your own proxy relay serverYesGood if you already run proxy infrastructure

The Four Ways to Use Proxies With Cloudflare Workers

Each method trades simplicity for control. For most teams, Method 1 is the answer; the others exist for specific needs.

MethodHow it worksDifficultyBest for
1. Provider HTTP APIfetch a REST endpoint that proxies for youEasyAnti-bot targets, most scraping
2. URL-param scraper APIfetch with the target as a query parameterEasyQuick, lightweight scraping
3. TCP sockets tunnelopen a socket and send CONNECT manuallyHardCustom protocols, full control
4. Self-hosted relayWorker calls your own proxy serverMediumExisting proxy infrastructure

The cleanest pattern is to call a provider’s HTTPS API — a Web Unlocker or scraper API — and let it apply the proxy, rotation, and anti-bot bypass on its side. Your Worker just makes a normal fetch.

First, store your API key as a secret so it never lives in code:

Bash
# Store the key securely (not in wrangler.toml)
npx wrangler secret put PROXY_API_KEY

Then call the provider endpoint from your Worker:

JavaScript
// src/index.js — Cloudflare Worker
export default {
  async fetch(request, env) {
    const target = "https://example.com/products";

    // Call the provider API instead of the target site directly.
    const res = await fetch("https://api.provider.com/unlock", {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${env.PROXY_API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ url: target, country: "us", render: true }),
    });

    const html = await res.text();
    return new Response(html, { headers: { "content-type": "text/html" } });
  },
};

The provider handles the residential or mobile IPs, geo-targeting (via the country field), and JavaScript rendering — your Worker never touches a raw proxy. This is by far the most reliable approach for bot-aware sites.

Method 2: URL-Based Scraper APIs

Many scraper APIs are even simpler: pass the target URL and your key as query parameters and they return the page. This is ideal for quick jobs.

JavaScript
export default {
  async fetch(request, env) {
    const endpoint = new URL("https://api.provider.com/v1");
    endpoint.searchParams.set("api_key", env.PROXY_API_KEY);
    endpoint.searchParams.set("url", "https://example.com");
    endpoint.searchParams.set("country", "de");
    endpoint.searchParams.set("render", "true");

    const res = await fetch(endpoint.toString());
    return new Response(await res.text());
  },
};

Because it is a single GET request, this pattern works beautifully with Workers and is trivial to cache. The trade-off is less control over headers and request shaping than the POST API in Method 1.

Method 3: Raw TCP Sockets With connect() (Advanced)

If you genuinely need a traditional IP:port proxy — say a SOCKS or HTTP CONNECT proxy — Workers expose a low-level TCP socket API via cloudflare:sockets. You open a socket to the proxy and send the CONNECT handshake yourself.

JavaScript
import { connect } from "cloudflare:sockets";

export default {
  async fetch(request, env) {
    // Open a raw TCP socket to an HTTP proxy.
    const socket = connect({ hostname: "proxy.example.com", port: 8080 });
    const writer = socket.writable.getWriter();
    const encoder = new TextEncoder();

    // Send an HTTP CONNECT tunnel request with proxy auth.
    const auth = btoa(`${env.PROXY_USER}:${env.PROXY_PASS}`);
    const connectReq =
      `CONNECT example.com:443 HTTP/1.1\r\n` +
      `Host: example.com:443\r\n` +
      `Proxy-Authorization: Basic ${auth}\r\n\r\n`;
    await writer.write(encoder.encode(connectReq));

    // After a 200 Connection Established, you must call socket.startTls()
    // and then speak HTTPS over the tunnel manually. This is non-trivial,
    // which is why most teams choose Method 1 instead.
    return new Response("Tunnel opened — see notes on completing TLS.");
  },
};

This is powerful but genuinely advanced: you are reimplementing the TLS and HTTP layers that fetch normally gives you for free. Reach for it only when a provider API cannot meet your needs.

Method 4: Route Through Your Own Proxy Relay

If you already run proxy infrastructure, the pragmatic path is to put a small relay server in front of it. Your Worker sends the target URL to your relay over HTTPS; the relay applies the IP:port proxy with a normal Node agent and returns the result.

This keeps the messy proxy logic where it works natively (Node) while still letting the edge Worker handle routing, caching, and request distribution. It adds one hop of latency but is simple to reason about, and it pairs well with a rotating proxy script running on your own server.

Handling Secrets and Wrangler Config

Never hard-code credentials. Use Wrangler secrets for keys and the config file only for non-sensitive vars.

TOML
# wrangler.toml
name = "proxy-worker"
main = "src/index.js"
compatibility_date = "2024-09-01"

[vars]
DEFAULT_COUNTRY = "us"   # non-secret config only
Bash
# Secrets are encrypted and injected as env.* at runtime
npx wrangler secret put PROXY_API_KEY
npx wrangler secret put PROXY_USER
npx wrangler secret put PROXY_PASS

At runtime these arrive on the env object, so your code stays clean and your keys never enter version control.

Caching and Retries at the Edge

Proxy and scraper API calls cost money per request, so cache aggressively. Workers give you the Cache API for free, and a small retry helper keeps transient failures from breaking your flow.

JavaScript
export default {
  async fetch(request, env, ctx) {
    const cache = caches.default;
    let res = await cache.match(request);
    if (res) return res;                       // serve from edge cache

    res = await fetchWithRetry(buildEndpoint(env), {}, 3);
    res = new Response(res.body, res);
    res.headers.set("Cache-Control", "s-maxage=3600");
    ctx.waitUntil(cache.put(request, res.clone()));
    return res;
  },
};

async function fetchWithRetry(url, opts, attempts) {
  for (let i = 0; i < attempts; i++) {
    try {
      const res = await fetch(url, opts);
      if (res.ok) return res;
    } catch (e) {
      // transient network error — fall through and retry
    }
  }
  throw new Error("All proxy attempts failed");
}

Caching identical requests for an hour can slash your proxy bill, and the retry loop turns the occasional failed call into a non-event.

Best Proxy Providers for Cloudflare Workers

Since Workers rely on the provider-API pattern, pick a provider with a solid HTTPS scraping or unlocker API — our roundup of the best proxy APIs for developers is a good starting point. These are the ones we rate most highly.

1BrightData

Pool:72M+
Uptime:99.99%
Latency:0.5s
Countries:195+
Extensive 72M+ global residential IPs
Industry-leading scraping APIs (Web Unlocker, SERP, Scraping Browser)
Advanced proxy manager and precise geo-targeting
Pay-as-you-go options available
Fully compliant and ethically sourced

BrightData’s Web Unlocker API is purpose-built for exactly this pattern — one HTTPS call returns an unblocked page, with proxies, retries, and anti-bot handling done server-side. It slots into a Worker with a single fetch.

Its enormous residential network and geo precision make it the go-to for the hardest targets, though it is priced for serious operations.

2Oxylabs

Pool:102M+
Uptime:99.99%
Latency:0.6s
Countries:195+
Massive 102M+ IP Pool
Ethically Sourced & Compliant
AI-Powered Web Unblocker
Dedicated Account Manager
Advanced ASN & City Targeting

Oxylabs offers Web Unlocker and dedicated Scraper APIs (SERP, e-commerce) that return structured data from a simple endpoint — ideal for Workers that need clean JSON rather than raw HTML.

It is an enterprise-grade choice with excellent reliability and support for high-volume edge scraping.

3Decodo

Pool:115M+
Uptime:99.99%
Latency:0.6s
Countries:195+
Huge 97M+ residential IP pool
Beginner-friendly dashboard and documentation
Flexible pay-as-you-go pricing
High success rates on tough targets
Fast 24/7 live chat support
Free trial and money-back guarantee

Decodo provides a Site Unblocker and API access on top of a large residential pool, with friendly pricing and a clean dashboard that make it a great default for Workers projects.

Its balance of cost, ease of use, and reliability suits teams that want a capable API without enterprise commitments.

4Webshare

Pool:10M+
Uptime:99.97%
Latency:1.0s
Countries:50+
Extremely cheap entry pricing
Free 10-proxy plan available
Highly customizable proxy lists
Fast self-serve dashboard and API
Unlimited bandwidth on datacenter plans

Webshare is the budget-friendly pick, with affordable proxies, a clean API, and a free tier perfect for prototyping your Worker before you scale.

For lenient targets where you mainly need IP rotation rather than full anti-bot bypass, it offers unbeatable value.

How to Choose Your Approach

The right method comes down to a few questions.

1Is the target protected by anti-bot systems?

If yes, use a provider Web Unlocker API (Method 1) — it handles CAPTCHAs and fingerprinting you cannot replicate in a Worker. For lenient sites, a simple URL-based scraper API or basic rotation is enough.

2Do you need raw protocol control?

Only then should you consider the TCP sockets approach (Method 3). For 95% of projects the extra complexity is not worth it over a managed API.

3Do you already run proxy infrastructure?

If you have your own rotating proxies, a relay server (Method 4) lets you reuse them while keeping the edge Worker thin. Otherwise, a provider API is faster to ship.

Common Mistakes to Avoid

A few errors trip up almost everyone the first time.

1Trying to set a proxy agent on fetch

The Workers runtime has no agent option, so passing one silently does nothing. Accept this early and use a provider API or sockets instead of fighting the runtime.

2Hard-coding credentials

API keys and proxy passwords belong in Wrangler secrets, never in your source or wrangler.toml. Leaked keys in a public repo get abused within hours.

3Not caching repeated requests

Every uncached proxy call costs money. Use the Workers Cache API for identical requests, and you can cut your bill dramatically with one extra block of code.

4Ignoring CPU and subrequest limits

Workers cap CPU time and the number of subrequests per invocation. Heavy parsing or many sequential proxy calls can hit those limits, so keep each Worker focused and offload heavy work.

5Using datacenter IPs on strict targets

Pointing a basic proxy at a bot-aware site fails fast. Match the proxy type to the target — see our guide on the types of proxies — and use residential or unlocker APIs where needed.

Best Practices

  • Default to a provider API — it is the only pattern that handles anti-bot reliably from a Worker.
  • Store every credential as a Wrangler secret, never in code or config.
  • Cache aggressively with the Workers Cache API to cut proxy costs.
  • Add retries with sensible limits so a single failed call does not break the response.
  • Match the proxy type to the target and compare options in our proxy directory.

Frequently Asked Questions

Yes, but not the traditional way. The Workers runtime cannot attach an IP:port proxy to fetch the way Node.js can. Instead you call a proxy provider’s HTTPS API, which does the proxying for you, or you drop down to the low-level cloudflare:sockets API to open a tunnel manually. The provider-API approach is by far the most common.
Because the Workers runtime is not Node.js. Its fetch implementation has no agent or proxy option, so there is nowhere to specify an upstream proxy. This is a deliberate design choice of the V8-based edge runtime, which is why you route through a provider API or the raw sockets API instead.
Call a proxy provider’s HTTPS API — a Web Unlocker or Scraper API — from your Worker’s fetch. You send the target URL and your API key, and the provider applies the proxy, rotation, and anti-bot bypass on its side. Your Worker only makes a normal HTTPS request, so there is no proxy configuration at all.
Yes, through a provider API. You cannot plug a raw residential IP:port into a Worker, but providers expose their residential pools via HTTPS endpoints that you call from fetch. The provider routes your request through a residential IP and returns the page, which gives you residential stealth without managing IPs in the Worker.
Not through fetch. There is no built-in SOCKS support. In theory you could implement a SOCKS or HTTP CONNECT handshake over the cloudflare:sockets TCP API, but that means writing the protocol and TLS layers yourself. For nearly all projects, a provider HTTPS API is the practical choice.
It is a low-level API that lets a Worker open a raw TCP socket to a host and port. With it you can speak protocols fetch does not support, including sending an HTTP CONNECT request to a proxy. It is powerful but advanced — you handle the handshake, TLS via startTls, and HTTP framing manually.
Use Wrangler secrets. Run npx wrangler secret put PROXY_API_KEY and the value is encrypted and injected onto the env object at runtime. Keep only non-sensitive variables in wrangler.toml. Never hard-code API keys or proxy passwords in your source, because leaked credentials in a repo are abused quickly.
Yes. Workers are often used as reverse proxies that forward requests to an origin, rewrite headers, or add caching. That is different from routing a Worker’s outbound traffic through a third-party proxy, which is the focus here. Both are valid, and you can even combine them — a Worker that proxies clients while calling an upstream proxy API.
For lenient sites, sometimes not — Workers already run from many edge locations. But Cloudflare’s own egress IPs are well known and frequently blocked, so for anything bot-aware you will need proxies or an unlocker API to avoid being flagged as automated traffic.
Use a provider Web Unlocker API for tough targets, cache repeated requests, pace your calls, and rotate residential or mobile IPs through the provider. Match the proxy type to the target, set realistic headers, and avoid hammering a site — the same etiquette that keeps any scraper unblocked applies at the edge too.

The Bottom Line

Cloudflare Workers cannot use proxies the traditional way, but that is rarely a problem once you know the patterns. For the vast majority of projects, calling a provider’s Web Unlocker or Scraper API from fetch is the cleanest, most reliable approach — it hands the proxying, rotation, and anti-bot work to infrastructure built for it.

Reach for raw TCP sockets only when you truly need protocol-level control, and a relay server when you already run your own proxies. Whichever route you take, store secrets properly, cache aggressively, and match the proxy type to your target. When you are ready to choose a network, compare every option in our proxy provider directory and pair the edge with a proxy built to keep it unblocked.