Worker's Global Variables

hello community! i read closely the documentation about workers mechanism of storing data (https://developers.cloudflare.com/workers/archive/writing-workers/storing-data/), but i still am not sure if i got it right. so here goes my questions:

  1. in the doc, it states that “Worker script is not launched for each individual request”, does that mean memory is shared among requests? if User-A sends a request to the worker, and the worker sets a global variable varAlpha = 1, then User-B sends a request and worker sets varAlpha = 2. if i look into the memory now, will it be varAlpha = 1 or 2? will varAlpha = 1 be a possible response to User-B?

  2. i have following code:

    let alpha = 0
    addEventListener(‘fetch’, event => {
    event.respondWith(handleRequest(event.request))
    })
    async function handleRequest(request) {
    let url = new URL(request.url);
    alpha += 1
    return new Response(alpha, {status: 200})
    }

it returns 1 for the first run, but 3, 5, 7, 9 for the consequent requests. shouldn’t it be 1, 2, 3, 4, 5? why it acts like that?
but when i run this code in the cloudflare web editor, it returns 1, 2, 3, 4, 5

1 Like

In general, yes, but it’s not guaranteed to share the same memory, ie. cross-data center requests will have fresh globals and sometimes even within the same DC depending on if all requests go to different Workers runners.

I also experienced the same think you’re experiencing when I threw that code on https://121123.judge.workers.dev/

But differing behavior from my curl (curl within WSL, so I think keep-alive sessions weren’t working)

So… I wouldn’t write code that bets on the global variable having anything in it. If you will use workers on a site with very heavy traffic, the global variable could be used as an extremely fast cache, ie

let expensiveNumber;

async function handleRequest(request) {
    if(expensiveNumber > 1) {
        return new Response(expensiveNumber, {status: 200})
    }
    expensiveNumber = Math.pow(3, 4);
    return new Response(expensiveNumber, {status: 200})
}

if expensiveNumber was a fetch event or otherwise took long to process, very frequent requests would be slightly faster than the first one.

1 Like

Sometime the client on a GET also requests OPTIONS and other http methods, also favicon.ico generating more requests. What client are you using?

1 Like

You’re right, Chrome makes a favicon.ico request:

image

1 Like

@Judge @adaptive Thanks a lot! problems solved!

1 Like

Only use case for globals that I’ve found so far is a half-arsed rate-limiter :wink:

Anyone got any other fun ideas?

Top level await when? seems to have a good use :stuck_out_tongue:

But the only good use cases I’m aware of are as a soft cache and as a way to store secret keys (eg let apikey = 'ccaabbdd')

1 Like

“cache” KV, reducing KV cost, logging worker lifespan data.

1 Like

I thought Cloudflare recommended to use the KV for secret keys, at least until the secret vault?

Caching the KV is a really good idea, especially for non-dynamic values!

Logging worker lifespan, sounds interesting, tell me more :wink:

I guess, but storing it is a top-level constant is much cheaper :stuck_out_tongue:

2 Likes

This post was flagged by the community and is temporarily hidden.