2. modulWorkers mélyebben: runtime, limitek, lokális fejlesztés
Cloudflare for Devs · 2. modul

Workers mélyebben: runtime, limitek, lokális fejlesztés

Az 1. modulban megértetted, mi a Worker. Most azt nézzük meg, hogyan dolgozol vele nap mint nap: mit tud a runtime, hol vannak a határai, mennyi Node-kódod működik változtatás nélkül, és milyen a lokális fejlesztési élmény.

2.1A runtime közelről: handlerek az Express-app helyett

Egy Express-appban van egy hosszú életű processz, ami app.listen(3000)-rel portot nyit, és middleware-láncokon át kezel mindent. A Workernél nincs „listen": a runtime (a nyílt forráskódú workerd) eseményekkel hívja meg a kódodat. Amilyen típusú eseményre exportálsz handlert, olyanra reagál a Workered:

src/index.ts
export default {
  // HTTP kérés — az Express route-ok helyett
  async fetch(request, env, ctx) { return new Response("hello"); },

  // ütemezett futás — a cron/EventBridge helyett (7. modul)
  async scheduled(event, env, ctx) { /* napi riport, cleanup… */ },

  // üzenetsor-fogyasztás — az SQS consumer helyett (7. modul)
  async queue(batch, env, ctx) { /* batch.messages feldolgozása */ },
};

Vagyis ami az AWS-en három külön deploy-egység lenne (web app + cron Lambda + SQS consumer Lambda), az itt lehet egyetlen Worker három handlerrel — közös kóddal, közös bindingokkal.

A harmadik paraméter, a ctx (ExecutionContext) a Worker-életciklus kulcsa. Alapszabály: amint a fetch visszaadja a Response-t, a runtime lezárhatja a munkát. Ha a válasz után még dolgozni akarsz — log kiírása, analitika, cache-frissítés —, azt a ctx.waitUntil()-lal kell „életben tartanod":

async fetch(request, env, ctx) {
  const data = await handleRequest(request, env);

  // a választ NEM késlelteti, de a runtime megvárja a hátteret:
  ctx.waitUntil(logToAnalytics(env, request, data));

  return Response.json(data);
}
Node-reflexből fakadó hiba: Expressben a res.send() után nyugodtan futhat tovább kód a processzben. Workersben egy „elfelejtett" (nem await-elt, nem waitUntil-ozott) promise csendben megszakadhat a válasz után. Ha háttérmunka kell: ctx.waitUntil() — vagy ha komolyabb, Queues (7. modul).

2.2Compatibility date: a runtime „verziószáma"

Beanstalkon te döntöd el, mikor lépsz Node 20-ról 22-re — platform-frissítéskor minden viselkedésváltozást egyszerre kapsz meg. A Workers ehelyett compatibility date-tel dolgozik: a konfigban rögzített dátum azt mondja meg, hogy a runtime melyik napi viselkedését kéred. A Cloudflare folyamatosan frissíti a platformot, de a változtatásokat dátumhoz (vagy explicit compatibility flaghez) köti — a te Workered viselkedése soha nem változik meg alattad, amíg a dátumot nem emeled. Ez a „soha nem törünk el élő appot" garancia platform-szinten.

2.3Mennyi Node-kódom működik? — a nodejs_compat réteg

Ez a te szempontodból az egyik legfontosabb kérdés, hiszen évek npm-függősége jön veled. A helyzet 2026-ban sokkal jobb, mint a Workers hírneve alapján gondolnád. A nodejs_compat flag bekapcsolásával a Node API-k nagy része natívan, a runtime-ban implementálva elérhető, a maradékot pedig a Wrangler polyfillekkel (unenv) hidalja át bundle-öléskor.

Node APIÁllapot WorkersbenMegjegyzés
node:buffer, node:path, node:events, node:stream, node:util, node:zlib✔ natíva leggyakoribb npm-függőségi igények
node:crypto, node:tls✔ natívteljes crypto API — JWT, aláírás, titkosítás megy
node:net, node:dns, node:timers✔ natívkimenő TCP-socket is — ezen áll a Postgres-driver (4. modul)
AsyncLocalStorage (node:async_hooks)✔ natívrequest-kontextus, logger-korreláció — ahogy megszoktad
node:fs◐ virtuáliskérésenkénti, izolált, nem perzisztens fájlrendszer — configolvasásra jó, tárolásra nem (arra R2)
process.env, process.nextTick◐ részlegesa process.env-et a bindings/vars táplálják
net.Server, http.Server — portnyitás✘ sohanincs „listen": a platform hívja a handleredet, nem fordítva
child_process, natív addonok (.node)✘ nemnincs OS-processz az isolate-ben — ha kell: Containers
wrangler.jsonc
{
  "compatibility_date": "2026-08-02",
  "compatibility_flags": ["nodejs_compat"]   // ennyi — a többit a Wrangler intézi
}
Gyakorlati ökölszabály npm-csomagokhoz: ami „tiszta JS" logika (validálás, dátum, lodash-féle utilok, SDK-k fetch-alapon), az működik. Ami hálózatot használ standard módon (Postgres-driver, Redis-kliens TCP-n), az ma már jellemzően működik. Ami portot nyit, processzt forkol vagy natív binárist tölt be, az nem fog — és nem is hibaüzenet nélkül: a polyfill réteg [unenv] ... is not implemented yet! hibát dob futáskor, ezért mindig próbáld ki lokálisan az új függőséget.

2.4Limitek: CPU-idő vs. fali idő — az új gondolkodás

A legfontosabb fogalompár, amit meg kell szokni: a Workers nem azt méri (és számlázza), meddig él a kérésed, hanem hogy mennyit dolgozik közben a CPU. Amíg a Worker adatbázisra, fetch-re vagy R2-re várakozik, az nem számít CPU-időnek — és nem is kerül pénzbe.

Egy tipikus API-kérés idővonala (össz. fali idő: 240 ms) parse + auth várakozás: Postgres-lekérdezés (80 ms) map várakozás: külső API fetch (140 ms) render CPU-idő: ~9 ms — ezt méri a limit, ez alapján fizetsz Várakozás (I/O): ~231 ms — nem számít bele a CPU-limitbe, nem kerül pénzbe
2. ábra — Egy átlagos, adatbázisra és külső API-ra váró kérés CPU-ideje töredéke a teljes futásidőnek.

A fontosabb határok (Paid plan, ami éles rendszerhez reális):

LimitFreePaidMit jelent neked
CPU-idő / kérés10 ms30 s alap, konfigurálhatóan 5 percigAPI-knak bőven elég; nehéz számításnak (képfeldolgozás, nagy JSON-ok) tervezés kell
Memória / isolate128 MBnem tölthetsz be gigabájtos adatot — streamelj (lásd lent)
Worker mérete (gzip)3 MB10 MBa bundle számít — a monorepo-szintű függőséghalmot karcsúsítani kell
Subrequest / kérés5010 000 (10 M-ig emelhető)minden fetch, KV/D1/R2 hívás egy subrequest
Egyidejű kimenő kapcsolat6a Promise.all(50 fetch) sorban áll — batchelj okosan
Indulási idő1 sa top-level (import-időben futó) kódod legyen könnyű

A limiteket lefelé is állíthatod védelemként (elszabadult kód vagy költség ellen), felfelé pedig a konfigban:

wrangler.jsonc
{
  "limits": {
    "cpu_ms": 300000,      // 5 perc — pl. nehéz feldolgozáshoz
    "subrequests": 50000   // ha sok szolgáltatáshívásod van
  }
}

Ha egy Worker túllépi a CPU-limitet, a kliens 1102-es hibát kap (exceededCpu a metrikákban). A megoldási sorrend: profilozd (DevTools CPU-profil), optimalizálj, vagy szervezd ki a nehéz munkát — Queues-ba, Workflows-ba, Durable Objectbe (7. modul), végső esetben Containersbe. A 128 MB memóriára pedig a streaming a válasz: a Response body lehet stream, tehát egy nagy R2-fájlt úgy szolgálsz ki, hogy soha nincs egyben a memóriában.

2.5Lokális fejlesztés: wrangler dev, Vite plugin, Miniflare

Beanstalk-világban a „lokális fejlesztés" gyakran azt jelenti: fut a Node lokálisan, de az SQS-t, S3-at mockolod, vagy dev-AWS-fiókra csatlakozol. A Workers-nél a helyzet jobb, mert maga a runtime fut a gépeden: a wrangler dev ugyanazt a workerd motort indítja el lokálisan (ezt a becsomagolást hívják Miniflare-nek), a bindingokkal együtt:

# lokális dev szerver: http://localhost:8787
npx wrangler dev

# a KV, D1, R2, Queues bindingok LOKÁLIS szimulációval mennek,
# perzisztens állapotuk a .wrangler/state mappába kerül

# ha éles erőforrások ellen akarsz fejleszteni:
npx wrangler dev --remote
Ez nagyobb ugrás, mint amilyennek hangzik: AWS-en a „lokálisan működött, élesben nem" a mindennapok része, mert a lokális Node ≠ Lambda-környezet. Itt a lokális és az éles runtime ugyanaz a kódbázis (workerd nyílt forráskódú) — az eltérési felület radikálisan kisebb.

2.6Napi munka: mi változik a Beanstalk-rutinhoz képest?

Szokásod eddigÚj megfelelője
npm run dev (Node lokálisan)wrangler dev / Vite plugin (workerd lokálisan)
.env fájl.dev.vars lokálisan + vars/secrets a konfigban
eb deploy (percek)wrangler deploy (másodpercek, globális)
Node-verzió upgradecompatibility date emelése (kontrollált, dátumhoz kötött)
console.log → CloudWatchconsole.logwrangler tail / Workers Logs (9. modul)
háttérmunka a response utánctx.waitUntil() vagy Queues
„bírja-e a gép?" (CPU/RAM-grafikonok)„belefér-e a CPU-ms-be?" (per-kérés gondolkodás)

2.7Ellenőrizd magad

  1. Miért nem számít bele az adatbázis-lekérdezésre várás a CPU-időbe, és miért jó ez neked pénzügyileg?
    Válasz

    A CPU-idő csak a ténylegesen futó kódot méri; I/O-várakozás alatt az isolate nem foglal CPU-t, így azt a Cloudflare nem is számlázza. Egy tipikus, I/O-ra váró API-nál a fali idő 95%-a „ingyen" van — EC2-n ugyanezt az időt instance-óraként fizetted.

  2. Egy npm-csomag [unenv] ... is not implemented yet! hibát dob futáskor. Mi történt, és mik a lehetőségeid?
    Válasz

    A csomag olyan Node API-t hív, amit a runtime natívan nem támogat — a Wrangler polyfillje engedte importálni, de a metódushívás hibát dob. Lehetőségek: alternatív (fetch-alapú vagy edge-kompatibilis) csomag keresése, a funkció kiváltása webes API-val, vagy ha tényleg kell a natív Node-környezet: Containers.

  3. Mire való a ctx.waitUntil(), és mi történik nélküle a válasz után indított promise-szal?
    Válasz

    A válasz visszaadása utáni háttérmunka életben tartására. Nélküle a runtime a response után bármikor leállíthatja az isolate munkáját, így a promise csendben megszakadhat.

  4. Miben más a compatibility date, mint egy Node-verzió a Beanstalkon?
    Válasz

    A runtime folyamatosan frissül mindenkinél, de a viselkedésváltozások dátumhoz kötöttek: a Worker a konfigban rögzített dátum szerinti viselkedést kapja örökre, amíg te nem emeled. Nincs kényszerített platform-upgrade, és nincs „minden változás egyszerre" ugrás.

  5. 500 MB-os fájlt kell kiszolgálnod R2-ből 128 MB memóriájú Workerrel. Hogyan?
    Válasz

    Streameléssel: az R2-objektum body-ja stream, amit közvetlenül a Response-ba adsz — a fájl sosincs egyben a memóriában, csak átfolyik a Workeren (vagy még jobb: a 6. modulban látott módon közvetlen/cache-elt kiszolgálással).

Előző1. modul — A Cloudflare platform mentális modellje Következő 3. modul — Full-stack és frontend: Nuxt a Workers-en