#
Background Jobs
This page covers the internal implementation of the worker system. For adding custom jobs, see Adding Jobs.
#
Job Storage
Jobs are stored in the workerJobs table with these key fields:
#
Worker Process
Each worker runs as a forked child process with its own ServerApp instance. The start-worker.ts entry point handles:
- Creating a
ServerAppwithout theWorkerManager(to avoid recursive spawning) - Connecting to the database with a smaller connection pool
- Starting the job polling loop
- Graceful shutdown on SIGTERM
Workers poll the database every second for jobs where due <= now and started IS NULL. They use FOR UPDATE SKIP LOCKED to claim jobs without blocking other workers.
#
IPC Communication
Workers communicate with the main server through Node.js IPC. Message types are defined in ipc-types.ts:
WorkerStarted— Worker process initializedWorkerShutdown— Worker shutting downWorkerError— Unhandled error in workerHeartbeat— Keep-alive signalSendToUser— Route WebSocket message to specific userBroadcast— Send WebSocket message to all connected clients
When a job needs to send a real-time notification, it uses serverApp.createNotification() which saves to the database and sends an IPC message. The main server receives this and routes it through the SocketManager.
#
Cron Scheduling
Jobs with a cronSchedule field automatically reschedule after completion. The schedule uses standard cron syntax:
┌───────────── second (0-59)
│ ┌───────────── minute (0-59)
│ │ ┌───────────── hour (0-23)
│ │ │ ┌───────────── day of month (1-31)
│ │ │ │ ┌───────────── month (1-12)
│ │ │ │ │ ┌───────────── day of week (0-6)
│ │ │ │ │ │
* * * * * *
The removeOldWorkerJobs job runs hourly. The watchChain job runs every few seconds when Web3 is enabled.
#
Error Handling
When a job throws an error:
- The
finishedtimestamp andsuccess = falseare recorded - If
autoRescheduleOnFailureis true, a new job is scheduled after the configured delay - The error is logged with the job context
Jobs don't retry infinitely—the rescheduled job is a new record. The original failed job remains for debugging until the cleanup job removes it.
#
Monitoring
Job execution is logged with structured data including job ID, type, duration, and result. Enable debug logging with WORKER_LOG_LEVEL=debug for detailed execution traces.
The workerJobs table serves as both queue and audit log. Query it to check pending jobs, recent failures, or execution patterns.