Skip to main content

Cloudflare Workers: Serverless Functions on the Edge

Cloudflare · 19.04.2026 · 4 min read
Illustration for “Cloudflare Workers: Serverless Functions on the Edge”

Cloudflare Workers is a serverless platform for running JavaScript/TypeScript code on Cloudflare's Edge servers worldwide. Code runs in the data center closest to the user, with no cold start.

Free Workers Plan

LimitFreePaid ($5/mo)
Requests/day100,00010M included
CPU time10 ms30 ms (default)
Workers30Unlimited

Your First Worker

// Simple Worker — responds to all requests
export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    
    // Redirect old → new
    if (url.pathname === '/old-page') {
      return Response.redirect('https://example.com/new-page', 301);
    }
    
    // Add security headers
    const response = await fetch(request);
    const newResponse = new Response(response.body, response);
    newResponse.headers.set('X-Frame-Options', 'DENY');
    newResponse.headers.set('X-Content-Type-Options', 'nosniff');
    return newResponse;
  }
};

Deploying via Wrangler CLI

# Install Wrangler
npm install -g wrangler

# Log in
wrangler login

# Create the project
wrangler init my-worker

# Deploy
wrangler deploy

Useful Worker Examples

  • Geo-redirect — redirect users to the localized version of a site by country
  • A/B testing — randomly split traffic between versions
  • Response transformation — modify HTML on the fly without a deploy
  • Security headers — add CSP and HSTS to every response
  • API rate limiting — throttle requests with logic in the Worker
✅ Workers KV is a key-value store for Workers. You can store configuration, feature flags, and cache without a database.

Workers compared to a traditional backend

CriterionCloudflare WorkersRegular server/VPS
Cold startPractically noneNot applicable (the process is already running)
Where the code runsThe data center closest to the userA single region
Filesystem accessNoneFull
Long background jobsLimited by CPU timeNo platform limit
State between requestsNeeds Workers KV/Durable ObjectsProcess memory, files, a database

Breaking down Workers errors

Error 1101: Worker threw exception

An unhandled exception in the Worker's code — most often accessing an undefined variable, a Promise rejected without a .catch(), or an invalid attempt to read the request body (for example, reading request.body twice, when it can only be read once). Check logs with wrangler tail in real time or in Dashboard → Workers → Logs.

Error 1102: Worker exceeded resource limits

The Worker went over the CPU-time limit on the free plan, or got stuck in an infinite loop. Unlike a classic server timeout, this counts active CPU execution time, not time spent waiting for a response from an external API — a long fetch to a slow backend does not by itself eat into this limit.

Verifying the Worker works

# Watch the Worker's live logs
wrangler tail my-worker

# Check that the Worker actually handles the route
curl -I https://example.com/old-page
# Expected: HTTP/2 301 and a location header coming from the Worker's code

When Workers do not fit

  • You need persistent filesystem access or to run OS-level binary dependencies — a Worker runs in an isolated V8 sandbox with no filesystem and without the full Node.js API.
  • You need long background computations (minutes, not milliseconds) — a regular server or a job queue with a worker on a VPS fits better.
  • You need to store and serve large files from the Worker itself — for that, a Worker reaches out to R2 through bindings instead of storing data inside itself.

A Worker gets access to environment variables and secrets through the env object passed into the fetch function. Secrets (API keys, tokens) are set with wrangler secret put NAME and never end up in plain text in the code or the repository — unlike ordinary variables defined in wrangler.toml.

Local debugging before deploying is done with wrangler dev — it spins up the Worker on your local machine with an emulated Cloudflare environment, including Workers KV and R2 bindings, so you do not have to deploy every change to production just to test it.

The "script startup exceeded CPU time limit" error differs from Error 1102 in that it is not about handling a request but about the module's own startup — it is usually caused by heavy top-level initialization in the file (for example, synchronously parsing a large JSON blob at startup), which should be moved inside the request handler or cached between calls.

Several Workers can be linked together through Service Bindings — one Worker calls another directly, without an HTTP request over the internet, with minimal latency, which is handy for splitting a large project into modules without extra cost.

Was this article helpful?
← Back to Knowledge Base Ask Support