Cronitor checks every run against its schedule and history. It distinguishes a failed run from a missing or unusually slow one, then alerts the right person.
Cronitor captures stdout and stderr as the job runs and keeps them with that execution — no SSH, grep, or timestamp matching. It also records success rate, duration, and custom metrics, so you can investigate today or compare trends months later.
The Cronitor CLI reads your crontab — or Windows Task Scheduler — and walks through each job with you. Choose what to monitor and the CLI creates the monitor and wraps the command. Status, duration, and output start reporting without changes to the job itself.
Prefer to add monitoring in code? Use an open-source SDK for tools such as Java, Airflow, and GitHub Actions, or send events directly to the telemetry API.
Start for free# Install CronitorCLI on the box that runs your jobs $ curl https://cronitor.io/install-linux?sudo=1 -H "API-KEY: <API-KEY>" | sh # Walk the crontab and add monitoring to the jobs you choose $ cronitor sync ----► Scanning for cron jobs... |--► Found 15 jobs in user "ec2-user" crontab |--► Send Daily Reports │ ✔ Monitor this job ----► Sync complete ✔ # Your crontab comes back instrumented. Status, duration and output # are reported for you — the job itself never changes. 0 9 * * * cronitor exec send-invoices "/usr/local/bin/send-invoices.sh"
# Add the Cronitor Helm chart $ helm repo add cronitor https://cronitorio.github.io/cronitor-kubernetes/ # Add your Cronitor API key as a Secret $ kubectl create secret generic cronitor-secret -n <namespace> \ --from-literal=CRONITOR_API_KEY=<API-KEY> # Deploy with Helm 2 or Helm 3 — every CronJob on the cluster syncs $ helm upgrade --install <release-name> cronitor/cronitor-kubernetes \ --namespace <namespace> \ --set credentials.secretName=cronitor-secret \ --set credentials.secretKey=CRONITOR_API_KEY
# Run PowerShell as Administrator to install CronitorCLI Invoke-WebRequest -Uri "https://cronitor.io/dl/windows_amd64.zip" ` -OutFile "$env:TEMP\cronitor.zip" Expand-Archive -Path "$env:TEMP\cronitor.zip" ` -DestinationPath "$env:ProgramFiles\Cronitor" -Force Remove-Item "$env:TEMP\cronitor.zip" [Environment]::SetEnvironmentVariable("Path", ` "$env:Path;$env:ProgramFiles\Cronitor", "Machine") # Open a new terminal so the PATH takes effect, then configure cronitor configure --api-key '<API-KEY>' --api-version '2025-11-28' # Walk Task Scheduler and monitor the tasks you choose cronitor sync
# Install the CLI into the image that runs the job FROM python:3.12-slim RUN curl -sOL https://cronitor.io/dl/linux_amd64.tar.gz \ && tar xf linux_amd64.tar.gz -C /usr/bin/ # Wrap the container command — exit status, duration and output ship home ENTRYPOINT cronitor exec -k $CRONITOR_API_KEY nightly-export \ "python /app/export.py" # Pass the key in at run time, never bake it into the image # docker run -e CRONITOR_API_KEY=<API-KEY> nightly-export
# Add Cronitor to your project $ pip install cronitor # Configure once, at startup import cronitor cronitor.api_key = '<API-KEY>' # Decorate anything scheduled — start, finish, duration # and unhandled exceptions are all reported @cronitor.job('send-invoices') def send_invoices(): Invoices.objects.send_all()
# Celery support ships inside the Python SDK $ pip install cronitor # Configure, then register your Celery app once import cronitor.celery cronitor.api_key = '<API-KEY>' cronitor.celery.initialize(app) # Every task is now monitored. To watch only the beat schedule: cronitor.celery.initialize(app, celerybeat_only=True)
// Add Cronitor to your project $ npm install cronitor // Configure with your API key const cronitor = require('cronitor')('<API-KEY>'); // Wrap any function with telemetry events cronitor.wrap('send-invoices', function () { console.log('running background job with monitoring!'); }); // Or embed telemetry events directly in your code const monitor = new cronitor.Monitor('send-invoices'); monitor.ping({state: 'run'});
# Add Cronitor to your project $ gem install cronitor # Import and configure require 'cronitor' Cronitor.api_key = '<API-KEY>' # Wrap any block with telemetry events Cronitor.job 'daily-metrics' do DailyMetricsJob.new(Date.today).run end
# The Sidekiq middleware is its own gem $ gem install sidekiq-cronitor # Configure Cronitor and register the server middleware require 'cronitor' Cronitor.api_key = '<API-KEY>' Sidekiq.configure_server do |config| config.server_middleware do |chain| chain.add Sidekiq::Cronitor::ServerMiddleware end end # Periodic jobs: Sidekiq::Cronitor::PeriodicJobs.sync_schedule!
// Add Cronitor to your project $ composer require cronitor/cronitor-php // Import and configure $cronitor = new Cronitor\Client('<API-KEY>'); // Wrap any invokable class or function $cronitor->job('weekly-report-job', new WeeklyReport); $cronitor->job('weekly-report-job', function() { (new WeeklyReport)->send(); });
# Install the Laravel SDK $ composer require cronitor/laravel # Add your API key to your .env file CRONITOR_API_KEY='<API-KEY>' # Sync monitors during deploy $ php artisan cronitor:sync # All set — your scheduled tasks and queue jobs are monitored # automatically from here on.
# Tell Cronitor a job started, finished, or failed $ curl https://cronitor.link/p/<API-KEY>/send-invoices?state=run $ curl https://cronitor.link/p/<API-KEY>/send-invoices?state=complete $ curl https://cronitor.link/p/<API-KEY>/send-invoices?state=fail # A key that doesn't exist yet is created on its first ping # Attach metrics and a message to any ping $ curl "https://cronitor.link/p/<API-KEY>/send-invoices?state=complete\ &metric=count:1204&metric=duration:41.2&message=Import+complete" # Metrics: count, error_count, duration, latency, length, tokens, actions, cost
Cron jobs rarely fail loudly. They may exit 0 with an empty result, start ten minutes late, or quietly stop running. Cronitor records what each job did, compares it with the schedule, and alerts whoever is on call when the two do not match.
Register cron, Kubernetes CronJobs, Sidekiq, Celery, Windows Task Scheduler — or anything that can make an HTTP request. One place that knows what runs, where it runs, and when it is next due.
Cronitor captures stdout and stderr as the job emits them and stores the output against that execution. No SSH, no tailing files, no matching timestamps by hand.
Cronitor holds your schedule and expects each run. Miss the window and it alerts — absence is a failure here, not silence. This is the failure mode you cannot catch from inside the job.
Every duration is compared with that job's own history. Use the automatic slow-job alert, or set your own threshold and watch p95 instead of averages.
Grace periods, failure tolerance and schedule tolerance, set per job. Page on the third consecutive miss instead of the first flake, and send it to Slack or PagerDuty.
Success rate, duration percentiles and custom metrics, retained a full year on dashboards that load fast enough to actually use during an incident.
Jobs tell you whether scheduled work happened. Checks watch endpoints. Heartbeats watch long-running processes. Analytics shows what real visitors experienced, and status pages keep customers informed. They all share one dashboard and alert pipeline, so a late job and a down endpoint reach the same on-call team.
Cron job monitoring verifies that your scheduled jobs start on time, finish successfully, and complete within a normal duration. Cronitor records every execution with its status, duration, metrics, and captured output, and alerts you the moment a job fails or an expected run never starts.
Each job reports its lifecycle to Cronitor, typically by wrapping the scheduled command with cronitor exec or by sending simple telemetry pings from your code. If a run reports a failure, exits with a non-zero code, or the expected run never arrives, Cronitor triggers an alert to email, Slack, PagerDuty, or any other channel you configure.
No code changes are required. Wrapping the command in your crontab with cronitor exec is a one-line change per job and captures start, completion, exit status, and output automatically. If you prefer, you can instrument jobs directly with an HTTP ping or one of Cronitor's SDKs instead.
Create a Job monitor with the agent tag, then wrap the scheduled command with cronitor exec MONITOR_KEY -- COMMAND. Cronitor records when Codex, Claude Code, or another agent starts, completes, or fails and alerts you when the cron-driven run is missing.
Every invocation has a run, complete, or fail outcome plus its duration and captured output. Direct telemetry can also attach tokens, actions, and cost metrics to show how much useful work the agent performed and make unusual usage visible.