A Golang job scheduling library that lets you run Go functions at pre-determined intervals using cron expressions, fixed durations, daily, weekly, monthly, or one-time schedules with support for distributed deployments.
How to start, pause, and shut down schedulers.
Start()Starts the scheduler. Non-blocking; jobs are scheduled in the background. Can be called multiple times (idempotent).
s.Start()StopJobs() errorStops scheduling new job runs but keeps the scheduler alive. Running jobs continue. Returns ErrStopJobsTimedOut if jobs don't finish within the configured StopTimeout.
Can be resumed with Start().
err := s.StopJobs()
if errors.Is(err, gocron.ErrStopJobsTimedOut) {
log.Println("Some jobs didn't finish in time")
}Shutdown() errorGracefully shuts down the scheduler. Waits for running jobs to complete up to the configured StopTimeout. Returns ErrStopSchedulerTimedOut if timeout is exceeded.
err := s.Shutdown()
if errors.Is(err, gocron.ErrStopSchedulerTimedOut) {
log.Println("Shutdown timed out")
}JobsWaitingInQueue() intReturns the number of jobs waiting in the execution queue (only relevant when using concurrency limits).
queueSize := s.JobsWaitingInQueue()s, _ := gocron.NewScheduler()
// Add jobs
j, _ := s.NewJob(
gocron.DurationJob(time.Minute),
gocron.NewTask(myFunc),
)
// Start
s.Start()
// Run for a while...
time.Sleep(5 * time.Minute)
// Graceful shutdown
err := s.Shutdown()
if err != nil {
log.Printf("Shutdown error: %v", err)
}s, _ := gocron.NewScheduler(
gocron.WithStopTimeout(30*time.Second),
)
// Add jobs
j, _ := s.NewJob(...)
// Start
s.Start()
// Pause (jobs keep running, no new schedules)
s.StopJobs()
// Resume
s.Start()
// Graceful shutdown
err := s.Shutdown()
if errors.Is(err, gocron.ErrStopSchedulerTimedOut) {
log.Println("Timeout waiting for jobs")
}s, _ := gocron.NewScheduler(
gocron.WithStopTimeout(30*time.Second),
)
j, _ := s.NewJob(
gocron.DurationJob(time.Minute),
gocron.NewTask(func(ctx context.Context) {
select {
case <-ctx.Done():
log.Println("Context cancelled, cleaning up...")
return
case <-time.After(time.Minute):
log.Println("Work complete")
}
}),
)
s.Start()
// Later: shutdown waits up to 30 seconds for running jobs
err := s.Shutdown()
if errors.Is(err, gocron.ErrStopSchedulerTimedOut) {
log.Println("Some jobs didn't finish within timeout")
}s, _ := gocron.NewScheduler(
gocron.WithLimitConcurrentJobs(2, gocron.LimitModeWait),
)
// Add multiple jobs
for i := 0; i < 10; i++ {
s.NewJob(
gocron.DurationJob(time.Second),
gocron.NewTask(func() {
time.Sleep(5 * time.Second)
}),
)
}
s.Start()
// Check queue periodically
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for range ticker.C {
queueSize := s.JobsWaitingInQueue()
fmt.Printf("Jobs in queue: %d\n", queueSize)
}func main() {
s, err := gocron.NewScheduler(
gocron.WithStopTimeout(30*time.Second),
)
if err != nil {
log.Fatal(err)
}
defer s.Shutdown()
j, err := s.NewJob(
gocron.DurationJob(time.Minute),
gocron.NewTask(doWork),
)
if err != nil {
log.Fatal(err)
}
s.Start()
// Block until signal
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
<-sigChan
log.Println("Shutting down...")
// deferred Shutdown() will be called
}The scheduler has the following states:
NewScheduler(), before Start()Start(), jobs are being scheduled and executedStopJobs(), no new job runs but scheduler is aliveShutdown(), scheduler is stopped and cannot be restartedState transitions:
Start()StopJobs()Start()Shutdown()Shutdown()Returned by StopJobs() when jobs don't complete within the configured timeout.
err := s.StopJobs()
if errors.Is(err, gocron.ErrStopJobsTimedOut) {
// Some jobs are still running
log.Println("Timeout waiting for jobs to stop")
}Returned by Shutdown() when the scheduler doesn't stop within the configured timeout.
err := s.Shutdown()
if errors.Is(err, gocron.ErrStopSchedulerTimedOut) {
// Scheduler didn't stop cleanly
log.Println("Timeout waiting for scheduler to shutdown")
}WithStopTimeout() based on longest job durationInstall with Tessl CLI
npx tessl i tessl/golang-github-com-go-co-op-gocron-v2@2.19.1docs
api
examples
guides