node-cron Monitoring — Catch Silent Failures in Node.js Scheduled Jobs | Pakyas

Start monitoring your node-cron jobs free — up to 10 checks, no card required.

The problem

node-cron schedules jobs inside your Node.js process, which is exactly why its failures are so easy to miss. If the process crashes, gets OOM-killed, is redeployed, or never restarts, cron.schedule() simply never fires — and there is no log line, no exception, and no signal that anything is wrong. Even when the process is alive, an unhandled rejection inside the task callback can swallow the error so the job appears to have run when it never did. A try/catch that logs to a file nobody watches is not monitoring. The result is the classic silent failure: a nightly backup or sync that quietly stops running for days, with a green-looking app the whole time. Silence is not success, and a job that never fired is Missing — not failed — but without an external observer you cannot tell the difference.

How Pakyas helps

Pakyas uses execution-signal monitoring: instead of polling your server, it waits for your node-cron task to prove it ran by sending a signal at the start and end of each run. Pakyas compares those signals against the job's expected schedule and tells you precisely what happened — On Schedule, Late (the signal arrived but later than expected), Missing (the signal never arrived, so the process likely died or was redeployed), Overrunning (the job started but never reported completion in time), or Error (the job ran and explicitly reported a failure). Because the signal comes from inside your task callback, a crashed process or a redeploy that stops the scheduler shows up as Missing — the exact case a log line can never catch. You get one clear alert that means action, not a dashboard you have to remember to check.

Set it up

  1. Create a check and copy its ping URL

    # In Pakyas, create a check for your scheduled job and copy its ping URL.
    # It has the form (public_id is the check's UUID):
    #   https://ping.pakyas.com/{public_id}
    # Start signal:   https://ping.pakyas.com/{public_id}/start
    # Failure signal: https://ping.pakyas.com/{public_id}/fail

    Set the expected schedule on the check to match your node-cron cron expression (e.g. daily at 02:00). Pakyas uses it to detect Late and Missing runs.

  2. Add the ping URL to your environment

    # .env
    PAKYAS_PING_URL=https://ping.pakyas.com/your-check-public-id

    Keep the public_id out of source control. Node 18+ has fetch built in, so no extra dependency is needed.

  3. Signal start, success, and failure from inside the task

    const cron = require('node-cron');
    
    const PING = process.env.PAKYAS_PING_URL;
    
    // Daily at 02:00 server time
    cron.schedule('0 2 * * *', async () => {
      // Signal that the job started (enables Overrunning detection)
      await fetch(`${PING}/start`).catch(() => {});
    
      try {
        await runBackup(); // your actual job
        // Success signal (default endpoint, no modifier)
        await fetch(PING).catch(() => {});
      } catch (err) {
        // Explicit failure signal
        await fetch(`${PING}/fail`).catch(() => {});
        throw err;
      }
    });

    The .catch(() => {}) keeps a transient ping network error from crashing your job. The cron expression here must match the schedule you set on the Pakyas check.

A worked example

Suppose you run a nightly database backup with node-cron at 02:00. Schedule the work with cron.schedule('0 2 * * *', ...). The moment the callback fires, call fetch(`${PING}/start`) so Pakyas knows the run began and can flag it Overrunning if it stalls. Run pg_dump and upload the dump to S3. On success, call fetch(PING) to report completion; in the catch block, call fetch(`${PING}/fail`) to report an explicit error. Now the three outcomes are distinct: a clean backup is On Schedule, a pg_dump that throws is Error, and a process that was redeployed or crashed before 02:00 — so /start never arrives — is Missing. You learn about the dead scheduler the next morning from one alert instead of discovering an empty backup bucket weeks later.

Pricing

Pakyas has four tiers: Free ($0), Developer ($9/mo), Pro ($29/mo), and Business ($99/mo). The Free tier monitors up to 10 checks, which is enough to cover the scheduled jobs in a typical Node.js app at no cost.

See the full breakdown on the pricing page.

New to the terminology? See the cron monitoring glossary for plain-language definitions of every job state, or explore everything Pakyas tracks on the features page.

Start monitoring your node-cron jobs free — up to 10 checks, no card required.

Execution-signal precision: know when a job is Missing, Late, Overrunning, or reports an Error — not just up or down.

Start monitoring free