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.
Schedule jobs using cron expressions for precise time-based scheduling.
j, _ := s.NewJob(
gocron.CronJob("*/5 * * * *", false),
gocron.NewTask(doWork),
)j, _ := s.NewJob(
gocron.CronJob("0 * * * *", false),
gocron.NewTask(doHourlyTask),
)j, _ := s.NewJob(
gocron.CronJob("30 9 * * *", false),
gocron.NewTask(doMorningReport),
)// 0=Sunday, 1=Monday, 2=Tuesday, etc.
j, _ := s.NewJob(
gocron.CronJob("0 10 * * 1", false),
gocron.NewTask(doWeeklyCleanup),
)// 1-5 = Monday through Friday
j, _ := s.NewJob(
gocron.CronJob("0 9 * * 1-5", false),
gocron.NewTask(doWeekdayTask),
)// 0,6 = Sunday and Saturday
j, _ := s.NewJob(
gocron.CronJob("0 8 * * 0,6", false),
gocron.NewTask(doWeekendTask),
)j, _ := s.NewJob(
gocron.CronJob("0 0 1 * *", false),
gocron.NewTask(doMonthlyTask),
)j, _ := s.NewJob(
gocron.CronJob("0 15 15 * *", false),
gocron.NewTask(doMidMonthReport),
)// Cron doesn't directly support "last day", use MonthlyJob instead
// Or use days 28-31 with logic to check
j, _ := s.NewJob(
gocron.CronJob("0 0 28-31 * *", false),
gocron.NewTask(func() {
tomorrow := time.Now().AddDate(0, 0, 1)
if tomorrow.Day() == 1 {
// This is the last day of the month
doEndOfMonthTask()
}
}),
)j, _ := s.NewJob(
gocron.CronJob("*/30 * * * * *", true), // withSeconds=true
gocron.NewTask(doQuickCheck),
)j, _ := s.NewJob(
gocron.CronJob("*/15 * * * * *", true),
gocron.NewTask(func() {
fmt.Println("High-frequency check")
}),
)j, _ := s.NewJob(
gocron.CronJob("45 30 10 * * *", true),
gocron.NewTask(doPreciseTask),
)// Cron: every 15 minutes, weekdays only, 9 AM - 5 PM
j, _ := s.NewJob(
gocron.CronJob("*/15 9-17 * * 1-5", false),
gocron.NewTask(doBusinessHoursTask),
)// On the hour, 9 AM to 5 PM, weekdays
j, _ := s.NewJob(
gocron.CronJob("0 9-17 * * 1-5", false),
gocron.NewTask(doHourlyBusinessTask),
)// Every day at noon
j, _ := s.NewJob(
gocron.CronJob("0 12 * * *", false),
gocron.NewTask(func() {
fmt.Println("Lunch time check")
}),
)// Use cron with day-of-month range 1-7 and Monday
j, _ := s.NewJob(
gocron.CronJob("0 9 1-7 * 1", false),
gocron.NewTask(doFirstMondayTask),
)
// Runs on Monday if it falls between 1st-7th// Cron approach: check if last day of month is Friday, or 1-6 days before
j, _ := s.NewJob(
gocron.CronJob("0 9 25-31 * 5", false),
gocron.NewTask(func() {
// Verify it's the last Friday
now := time.Now()
nextWeek := now.AddDate(0, 0, 7)
if now.Month() != nextWeek.Month() {
// This is the last Friday
doLastFridayTask()
}
}),
)// Days 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31
j, _ := s.NewJob(
gocron.CronJob("0 9 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31 * *", false),
gocron.NewTask(doAlternateDayTask),
)// Chicago time using TZ prefix
j, _ := s.NewJob(
gocron.CronJob("TZ=America/Chicago 0 9 * * *", false),
gocron.NewTask(doWork),
)
// Or CRON_TZ prefix
j, _ = s.NewJob(
gocron.CronJob("CRON_TZ=Europe/London 30 14 * * *", false),
gocron.NewTask(doWork),
)timezones := []string{
"America/New_York",
"America/Chicago",
"America/Los_Angeles",
"Europe/London",
"Asia/Tokyo",
}
for _, tz := range timezones {
cronExpr := fmt.Sprintf("TZ=%s 0 9 * * *", tz)
s.NewJob(
gocron.CronJob(cronExpr, false),
gocron.NewTask(func(timezone string) {
fmt.Printf("Morning report for %s\n", timezone)
doRegionalReport(timezone)
}, tz),
gocron.WithName(fmt.Sprintf("report-%s", tz)),
)
}// Jobs automatically adjust for DST with timezone
j, _ := s.NewJob(
gocron.CronJob("TZ=America/New_York 0 9 * * *", false),
gocron.NewTask(func() {
fmt.Println("Always runs at 9 AM Eastern, DST-aware")
}),
)j, _ := s.NewJob(
gocron.CronJob("* * * * *", false),
gocron.NewTask(doEveryMinute),
)j, _ := s.NewJob(
gocron.CronJob("*/10 * * * *", false),
gocron.NewTask(doEvery10Minutes),
)j, _ := s.NewJob(
gocron.CronJob("*/30 * * * *", false),
gocron.NewTask(doEvery30Minutes),
)j, _ := s.NewJob(
gocron.CronJob("0 */2 * * *", false),
gocron.NewTask(doEvery2Hours),
)j, _ := s.NewJob(
gocron.CronJob("0 0 * * *", false),
gocron.NewTask(doDailyMidnightTask),
)// 9 AM, noon, and 5 PM
j, _ := s.NewJob(
gocron.CronJob("0 9,12,17 * * *", false),
gocron.NewTask(doMultipleTimesDaily),
)// Runs May through August only
j, _ := s.NewJob(
gocron.CronJob("0 8 * 5-8 *", false),
gocron.NewTask(doSummerTask),
)// First day of Jan, Apr, Jul, Oct at midnight
j, _ := s.NewJob(
gocron.CronJob("0 0 1 1,4,7,10 *", false),
gocron.NewTask(doQuarterlyReport),
)// Run every day except specific dates (needs additional logic)
j, _ := s.NewJob(
gocron.CronJob("0 9 * * *", false),
gocron.NewTask(func() {
if isHoliday(time.Now()) {
return // Skip holidays
}
doRegularTask()
}),
)package main
import (
"fmt"
"time"
"github.com/go-co-op/gocron/v2"
)
func main() {
s, _ := gocron.NewScheduler()
defer s.Shutdown()
// Every 5 minutes
s.NewJob(
gocron.CronJob("*/5 * * * *", false),
gocron.NewTask(func() {
fmt.Println("Every 5 minutes")
}),
gocron.WithName("frequent"),
)
// Every hour
s.NewJob(
gocron.CronJob("0 * * * *", false),
gocron.NewTask(func() {
fmt.Println("Every hour")
}),
gocron.WithName("hourly"),
)
// Every day at 9 AM
s.NewJob(
gocron.CronJob("0 9 * * *", false),
gocron.NewTask(func() {
fmt.Println("Daily at 9 AM")
}),
gocron.WithName("daily"),
)
// Every Monday at 10 AM
s.NewJob(
gocron.CronJob("0 10 * * 1", false),
gocron.NewTask(func() {
fmt.Println("Weekly on Monday")
}),
gocron.WithName("weekly"),
)
// First of month at midnight
s.NewJob(
gocron.CronJob("0 0 1 * *", false),
gocron.NewTask(func() {
fmt.Println("Monthly on 1st")
}),
gocron.WithName("monthly"),
)
s.Start()
select {}
}import "errors"
j, err := s.NewJob(
gocron.CronJob("invalid cron", false),
gocron.NewTask(myFunc),
)
if err != nil {
if errors.Is(err, gocron.ErrCronJobParse) {
fmt.Println("Invalid cron expression")
} else {
fmt.Println("Failed to create job:", err)
}
}cronExpr := "0 9 * * *" // From config or user input
_, err := s.NewJob(
gocron.CronJob(cronExpr, false),
gocron.NewTask(myFunc),
)
if err != nil {
log.Fatalf("Invalid cron expression: %v", err)
}package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
"github.com/go-co-op/gocron/v2"
)
func main() {
// Create scheduler with timezone
loc, _ := time.LoadLocation("America/New_York")
s, err := gocron.NewScheduler(gocron.WithLocation(loc))
if err != nil {
panic(err)
}
defer s.Shutdown()
// Every 5 minutes
s.NewJob(
gocron.CronJob("*/5 * * * *", false),
gocron.NewTask(func() {
fmt.Println("Every 5 minutes")
}),
gocron.WithName("frequent-check"),
)
// Every hour at minute 0
s.NewJob(
gocron.CronJob("0 * * * *", false),
gocron.NewTask(func() {
fmt.Println("Hourly task")
}),
gocron.WithName("hourly-sync"),
)
// Weekdays at 9 AM
s.NewJob(
gocron.CronJob("0 9 * * 1-5", false),
gocron.NewTask(func() {
fmt.Println("Weekday morning task")
}),
gocron.WithName("weekday-morning"),
)
// Every 15 minutes during business hours
s.NewJob(
gocron.CronJob("*/15 9-17 * * 1-5", false),
gocron.NewTask(func() {
fmt.Println("Business hours check")
}),
gocron.WithName("business-hours-check"),
)
// First of month at midnight
s.NewJob(
gocron.CronJob("0 0 1 * *", false),
gocron.NewTask(func() {
fmt.Println("Monthly report")
}),
gocron.WithName("monthly-report"),
)
// Start scheduler
s.Start()
fmt.Println("Scheduler started with cron jobs")
// Print schedule
for _, j := range s.Jobs() {
nextRun, _ := j.NextRun()
fmt.Printf("%s: next run at %v\n", j.Name(), nextRun)
}
// Wait for interrupt
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
<-sigCh
fmt.Println("Shutting down...")
}Field Allowed Values
----- --------------
second 0-59 (6-field only, when withSeconds=true)
minute 0-59
hour 0-23
day-of-month 1-31
month 1-12
day-of-week 0-6 (0=Sunday)
Special Characters:
* any value
, value list (1,3,5)
- range (1-5)
/ step (*/15 = every 15)Install with Tessl CLI
npx tessl i tessl/golang-github-com-go-co-op-gocron-v2docs
api
examples
guides