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.
Guide to advanced scheduling patterns and techniques.
Beyond basic intervals and cron expressions, gocron supports sophisticated scheduling patterns for complex use cases.
Schedule jobs at specific times of day, week, or month.
// Run at 9 AM and 5 PM every day
j, _ := s.NewJob(
gocron.DailyJob(
1,
gocron.NewAtTimes(
gocron.NewAtTime(9, 0, 0),
gocron.NewAtTime(17, 0, 0),
),
),
gocron.NewTask(dailyReport),
)// Run every Monday at 9 AM
j, _ := s.NewJob(
gocron.WeeklyJob(
1,
gocron.NewWeekdays(time.Monday),
gocron.NewAtTimes(gocron.NewAtTime(9, 0, 0)),
),
gocron.NewTask(weeklyReport),
)// Run on 1st and 15th of month at midnight
j, _ := s.NewJob(
gocron.MonthlyJob(
1,
gocron.NewDaysOfTheMonth(1, 15),
gocron.NewAtTimes(gocron.NewAtTime(0, 0, 0)),
),
gocron.NewTask(monthlyReport),
)Detailed guide: Time-Based Scheduling
Add jitter to prevent thundering herd:
// Random interval between 1-5 minutes
j, _ := s.NewJob(
gocron.DurationRandomJob(
time.Minute,
5*time.Minute,
),
gocron.NewTask(healthCheck),
)Limit job execution window:
// Run only during business hours
j, _ := s.NewJob(
gocron.DurationJob(time.Minute),
gocron.NewTask(businessTask),
gocron.WithStartAt(
gocron.WithStartDateTime(
time.Date(2024, 1, 1, 9, 0, 0, 0, time.Local),
),
),
gocron.WithLimitRunsTo(480), // 8 hours * 60 minutes
)loc, _ := time.LoadLocation("America/Chicago")
s, _ := gocron.NewScheduler(
gocron.WithLocation(loc),
)j, _ := s.NewJob(
gocron.CronJob("TZ=America/New_York 0 9 * * *", false),
gocron.NewTask(doWork),
)Skip execution based on runtime conditions:
j, _ := s.NewJob(
gocron.DurationJob(time.Minute),
gocron.NewTask(func() {
if shouldSkip() {
return
}
doWork()
}),
)Execute job once immediately, then on schedule:
j, _ := s.NewJob(
gocron.DurationJob(time.Hour),
gocron.NewTask(initialize),
gocron.WithStartAt(
gocron.WithStartImmediately(),
),
)Ensure fixed rest period between executions:
j, _ := s.NewJob(
gocron.DurationJob(5*time.Minute),
gocron.NewTask(rateLimitedAPI),
gocron.WithIntervalFromCompletion(), // 5min rest after completion
)Execute once at specific time:
j, _ := s.NewJob(
gocron.OneTimeJob(
gocron.OneTimeJobStartDateTime(
time.Now().Add(time.Hour),
),
),
gocron.NewTask(initializeSystem),
)Execute jobs in sequence:
// Job 1
j1, _ := s.NewJob(
gocron.DurationJob(time.Hour),
gocron.NewTask(step1),
gocron.WithEventListeners(
gocron.AfterJobRuns(func(jobID uuid.UUID, jobName string) {
// Trigger job 2
j2.RunNow()
}),
),
)
// Job 2
j2, _ := s.NewJob(
gocron.DurationJob(24*time.Hour), // Normally runs daily
gocron.NewTask(step2),
)Update jobs at runtime:
// Create initial job
j, _ := s.NewJob(
gocron.DurationJob(time.Minute),
gocron.NewTask(myFunc),
)
// Later, update interval
newJob, err := s.Update(
j.ID(),
gocron.DurationJob(5*time.Minute), // New interval
gocron.NewTask(myFunc),
)Create multiple instances of same job:
for i := 0; i < 5; i++ {
workerID := i
s.NewJob(
gocron.DurationJob(time.Minute),
gocron.NewTask(func() {
processQueue(workerID)
}),
gocron.WithName(fmt.Sprintf("worker-%d", workerID)),
gocron.WithTags("worker", "queue"),
)
}Implement complex scheduling with cron:
// Run every weekday at 9 AM
j, _ := s.NewJob(
gocron.CronJob("0 9 * * 1-5", false),
gocron.NewTask(weekdayTask),
)
// Run last day of month
j, _ = s.NewJob(
gocron.CronJob("0 0 L * *", false), // Last day
gocron.NewTask(monthEndTask),
)// Limit total runs
j, _ := s.NewJob(
gocron.DurationJob(time.Minute),
gocron.NewTask(myFunc),
gocron.WithLimitRunsTo(100),
)// Prevent overlapping runs
j, _ := s.NewJob(
gocron.DurationJob(30*time.Second),
gocron.NewTask(slowOperation),
gocron.WithSingletonMode(gocron.LimitModeReschedule),
)Best practices for production deployments.
Detailed guide: Production Patterns
Install with Tessl CLI
npx tessl i tessl/golang-github-com-go-co-op-gocron-v2@2.19.1docs
api
examples
guides