LockFlare

Worker models

Every project picks a worker model, and the choice has real consequences. Get it wrong and a scheduled job can run once per core instead of once.

If your application runs crons, schedulers or anything that must happen exactly once, read this before your first push. The default is correct for most applications and wrong for that one.

Standard recommended

One real worker process per licensed core, all serving in parallel. This is real multi-core — four licensed cores means four workers handling requests simultaneously.

It works for ordinary applications and for fork-and-serve cluster code alike. If your application calls cluster.fork(), that call is skipped, because the engine has already forked real workers for you.

WORKER_NUMBER and cluster.worker.id are the real worker number under Standard. A guard like if (cluster.worker.id === 1) runs your cron exactly once, on one worker — which is the pattern you want.

Self-coordinating cluster single core

Your entire application — its master and the workers it forks — runs emulated inside one process on one core. There is no parallelism.

Choose it only when your master does coordination the engine cannot replace: aggregating messages from workers over IPC, distributing jobs, holding state the workers ask it for.

If your master only forks and respawns, use Standard instead. That is the common case, and Standard gives you the cores you are paying for.

Single instance single core

One copy, one core. For applications that must never run twice and cannot be adapted — in-memory sessions or caches with no shared store, or a scheduler with no worker guard.

It is the safe answer when you are unsure and cannot change the code. It is also the slowest, so treat it as a stopgap rather than a destination.

Choosing

Your applicationModel
An ordinary web app or APIStandard
Uses cluster.fork() just to spread loadStandard — your fork is skipped, the engine already did it
Runs a cron guarded by a worker checkStandard — the guard works as written
Runs a cron with no guardSingle instance, or add a guard and use Standard
Keeps sessions or a cache in process memorySingle instance, or move state to Redis and use Standard
Master aggregates worker messages over IPCSelf-coordinating cluster

The failure to avoid

An unguarded setInterval or cron under Standard runs in every worker. Four cores means four invoices emailed, four cleanup jobs, four webhook retries. Nothing errors — it just happens four times, which is worse.

The fix is one line, and it is the same line you would want on any clustered Node deployment:

run the scheduler on one worker only
const cluster = require('cluster')

if (cluster.worker.id === 1) { startScheduler() }

Changing it later

The worker model is on the project’s General pane and can be changed at any time. It takes effect on the next push or reload.