Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Workers and Workers KV  ›  Lesson

The Workers Lifecycle — Respond First, Finish Later

Workers Lifecycle 12 minA Worker invocation ends when it returns a response, so work the response does not need should be registered with ctx.waitUntil to finish in the background.

The Workers Lifecycle — Respond First, Finish Later

Every time someone follows a Hoplink, you want to record the click for the owner's statistics. But the visitor does not care about statistics; they want their redirect now. Making them wait while you send an analytics call wastes their time. Knowing how long a Worker lives, and what you may do after replying, solves this.

The rule

An invocation ends at the response — unless you hand work to waitUntil.

Follow one request through its life:

  1. Wake. A request arrives at an edge location. If no isolate there has your code loaded, the runtime creates one — a matter of milliseconds.
  2. Handle. The runtime calls your fetch(request, env, ctx). You may await other services with fetch; time spent waiting on the network does not count as CPU time, which is the limit that matters most.
  3. Respond. Once you return a Response, the invocation is over. Unfinished promises may be cancelled.
  4. Extend (optional). ctx.waitUntil(promise) tells the runtime: "the response is sent, but keep me alive until this promise settles."
  5. Idle and evict. The isolate may stay warm to serve the next request, or it may be discarded at any moment. Nothing in memory is promised to survive.
export default {
  async fetch(request, env, ctx) {
    const code = new URL(request.url).pathname.slice(1);
    const target = "https://example.com/all-about-cats";

    ctx.waitUntil(
      fetch("https://stats.example/clicks", {
        method: "POST",
        body: JSON.stringify({ code, at: Date.now() }),
      })
    );

    return Response.redirect(target, 302);
  },
};

The redirect goes out immediately; the stats call finishes in the background.

The fetch handler is not the only entry point. A Worker can also export scheduled (run on a cron schedule, such as a nightly cleanup) and queue (receive batches of messages, which you will meet in the last section). Each follows the same wake → handle → finish shape.

The shortcut

Sort every piece of work in a handler into one of two buckets by asking: does the visitor's response depend on this result? Yes means await it before returning. No means wrap it in ctx.waitUntil.

Sorting Hoplink's redirect workStep 1 of 4
  1. Look up the long URL

    The redirect needs it, so await it before responding.

Trap: starting a promise without awaiting it and without waitUntil — a "fire and forget" call. It may be cut off the moment the response is sent, so clicks silently go missing.

Drills

Answer fast — trust the rule.

quick drill

What does ctx.waitUntil(promise) do?

quick drill

A handler calls fetch(statsUrl) without await and without waitUntil, then returns. What is the risk?

quick drill

Which piece of Hoplink work must be awaited before returning the redirect?

quick drill

A Worker must purge expired links every night at 02:00. Which handler fits?

Remember

  • An invocation ends at the response — unless you hand work to waitUntil.
  • Shortcut: does the response depend on it? Await it. Otherwise, waitUntil.
  • Trap: fire-and-forget promises that vanish when the invocation ends.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainAwait it or hand it off?

Hoplink's redirect handler looks up the target URL, records the click with an outside analytics call, and returns a redirect. Explain which step to await, which to pass to ctx.waitUntil, and what goes wrong with a fire-and-forget call.