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.
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.
| Approach | Works in Workers? | Note |
|---|---|---|
| fetch with an http(s) proxy agent / IP:port | No | Workers fetch has no agent or proxy option |
| Provider HTTPS API (Web Unlocker, Scraper API) | Yes | Recommended for most use cases |
| URL-based scraper API (pass target as a parameter) | Yes | Simplest possible setup |
| Raw TCP sockets via cloudflare:sockets connect() | Yes (advanced) | You handle CONNECT, TLS, and HTTP manually |
| Route through your own proxy relay server | Yes | Good 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.
| Method | How it works | Difficulty | Best for |
|---|---|---|---|
| 1. Provider HTTP API | fetch a REST endpoint that proxies for you | Easy | Anti-bot targets, most scraping |
| 2. URL-param scraper API | fetch with the target as a query parameter | Easy | Quick, lightweight scraping |
| 3. TCP sockets tunnel | open a socket and send CONNECT manually | Hard | Custom protocols, full control |
| 4. Self-hosted relay | Worker calls your own proxy server | Medium | Existing proxy infrastructure |
Method 1: Call a Proxy Provider's HTTP API (Recommended)
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:
# Store the key securely (not in wrangler.toml)
npx wrangler secret put PROXY_API_KEYThen call the provider endpoint from your Worker:
// 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.
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.
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.
# wrangler.toml
name = "proxy-worker"
main = "src/index.js"
compatibility_date = "2024-09-01"
[vars]
DEFAULT_COUNTRY = "us" # non-secret config only# 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_PASSAt 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.
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
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
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
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
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
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.
Keep Reading
More articles you might enjoy



