Introduction
gocron is a Go job scheduling library that lets developers define recurring tasks using a fluent API or standard cron expressions. It handles timing, concurrency control, and job lifecycle management so applications can schedule background work without deploying a separate scheduler service like cron or Celery.
What gocron Does
- Schedules jobs at fixed intervals, cron expressions, or specific times
- Provides a fluent builder API for readable schedule definitions
- Supports distributed locking to prevent duplicate execution across instances
- Handles job concurrency limits, singleton mode, and error recovery
- Offers event listeners for job start, completion, and failure hooks
Architecture Overview
gocron v2 uses a scheduler that maintains a priority queue of jobs sorted by next execution time. A goroutine loop sleeps until the next job is due, then dispatches it to a worker pool. Each job wraps a Go function and its arguments. The scheduler supports pluggable distributed lockers (Redis, PostgreSQL, MongoDB) for multi-instance deployments, ensuring only one instance runs a given job.
Self-Hosting & Configuration
- Create a scheduler with gocron.NewScheduler() and optional configuration
- Define jobs with DurationJob, CronJob, DailyJob, WeeklyJob, or MonthlyJob
- Set timezone with gocron.WithLocation for locale-aware scheduling
- Use gocron.WithDistributedLocker to prevent duplicate execution in clusters
- Call s.StopJobs() for graceful shutdown that waits for running jobs to complete
Key Features
- Multiple schedule types: duration, cron, daily, weekly, monthly, and one-time jobs
- Distributed locking: pluggable lockers for Redis, PostgreSQL, and MongoDB
- Singleton mode: ensures only one instance of a job runs at a time
- Event listeners: hooks for before/after job execution and error handling
- Elector mode: elect a single scheduler instance to run jobs in a cluster
Comparison with Similar Tools
- robfig/cron — the original Go cron library; gocron adds fluent API, distributed locking, and v2 improvements
- Asynq — Redis-based task queue with retry and scheduling; heavier but better for distributed job processing
- Temporal — full workflow orchestration platform; overkill for simple recurring tasks that gocron handles
- APScheduler (Python) — similar feature set in Python; gocron is the Go equivalent with native goroutine integration
FAQ
Q: Can I use cron expressions? A: Yes. Use gocron.CronJob("*/5 * * * *", false) for standard 5-field cron or pass true for 6-field (with seconds) expressions.
Q: How does distributed locking work? A: Configure a locker (e.g., Redis-based) via gocron.WithDistributedLocker. Before each job runs, the scheduler acquires a lock. Only the instance that gets the lock executes the job.
Q: What happens if a job takes longer than its interval? A: By default, a new instance starts on schedule. Use SingletonMode to skip the next run if the previous one is still executing.
Q: Can I dynamically add or remove jobs? A: Yes. Call s.NewJob() to add jobs and s.RemoveJob(id) to remove them while the scheduler is running.