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 at specific times using DailyJob, WeeklyJob, and MonthlyJob.
j, _ := s.NewJob(
gocron.DailyJob(
1,
gocron.NewAtTimes(gocron.NewAtTime(9, 0, 0)),
),
gocron.NewTask(doMorningTask),
)// Every day at 9 AM and 5 PM
j, _ := s.NewJob(
gocron.DailyJob(
1,
gocron.NewAtTimes(
gocron.NewAtTime(9, 0, 0),
gocron.NewAtTime(17, 0, 0),
),
),
gocron.NewTask(doReport),
)j, _ := s.NewJob(
gocron.DailyJob(2, gocron.NewAtTimes(gocron.NewAtTime(12, 0, 0))),
gocron.NewTask(doBiDailyTask),
)j, _ := s.NewJob(
gocron.DailyJob(1, gocron.NewAtTimes(gocron.NewAtTime(0, 0, 0))),
gocron.NewTask(doMidnightRollover),
)// 9:30:15 AM
j, _ := s.NewJob(
gocron.DailyJob(1, gocron.NewAtTimes(gocron.NewAtTime(9, 30, 15))),
gocron.NewTask(doPreciseTask),
)// If created before 9 AM, runs today at 9 AM
// If created after 9 AM, runs tomorrow at 9 AM
j, _ := s.NewJob(
gocron.DailyJob(1, gocron.NewAtTimes(gocron.NewAtTime(9, 0, 0))),
gocron.NewTask(doMorningTask),
gocron.WithStartAt(gocron.WithStartImmediately()),
)// 8 AM and 8 PM daily
j, _ := s.NewJob(
gocron.DailyJob(
1,
gocron.NewAtTimes(
gocron.NewAtTime(8, 0, 0),
gocron.NewAtTime(20, 0, 0),
),
),
gocron.NewTask(func() {
hour := time.Now().Hour()
if hour < 12 {
fmt.Println("Morning report")
} else {
fmt.Println("Evening report")
}
generateReport()
}),
gocron.WithName("daily-reports"),
)j, _ := s.NewJob(
gocron.WeeklyJob(
1,
gocron.NewWeekdays(time.Monday),
gocron.NewAtTimes(gocron.NewAtTime(9, 0, 0)),
),
gocron.NewTask(doMondayTask),
)// Monday and Wednesday at 9 AM
j, _ := s.NewJob(
gocron.WeeklyJob(
1,
gocron.NewWeekdays(time.Monday, time.Wednesday),
gocron.NewAtTimes(gocron.NewAtTime(9, 0, 0)),
),
gocron.NewTask(doWeekdayTask),
)// Monday and Friday at 9 AM and 5 PM
j, _ := s.NewJob(
gocron.WeeklyJob(
1,
gocron.NewWeekdays(time.Monday, time.Friday),
gocron.NewAtTimes(
gocron.NewAtTime(9, 0, 0),
gocron.NewAtTime(17, 0, 0),
),
),
gocron.NewTask(doTask),
)
// Runs 4 times per weekj, _ := s.NewJob(
gocron.WeeklyJob(
2,
gocron.NewWeekdays(time.Friday),
gocron.NewAtTimes(gocron.NewAtTime(17, 0, 0)),
),
gocron.NewTask(doBiWeeklyTask),
)j, _ := s.NewJob(
gocron.WeeklyJob(
1,
gocron.NewWeekdays(
time.Monday,
time.Tuesday,
time.Wednesday,
time.Thursday,
time.Friday,
),
gocron.NewAtTimes(gocron.NewAtTime(9, 30, 0)),
),
gocron.NewTask(sendStandupReminder),
)j, _ := s.NewJob(
gocron.WeeklyJob(
1,
gocron.NewWeekdays(time.Saturday, time.Sunday),
gocron.NewAtTimes(gocron.NewAtTime(10, 0, 0)),
),
gocron.NewTask(doWeekendMaintenance),
)// Align to last Monday
lastMonday := time.Now()
for lastMonday.Weekday() != time.Monday {
lastMonday = lastMonday.AddDate(0, 0, -1)
}
j, _ := s.NewJob(
gocron.WeeklyJob(
1,
gocron.NewWeekdays(time.Monday),
gocron.NewAtTimes(gocron.NewAtTime(9, 0, 0)),
),
gocron.NewTask(doWeeklyReport),
gocron.WithStartAt(gocron.WithStartDateTimePast(lastMonday)),
)// Monday standup, Wednesday sync, Friday retrospective
j, _ := s.NewJob(
gocron.WeeklyJob(
1,
gocron.NewWeekdays(time.Monday, time.Wednesday, time.Friday),
gocron.NewAtTimes(gocron.NewAtTime(10, 0, 0)),
),
gocron.NewTask(func() {
day := time.Now().Weekday()
switch day {
case time.Monday:
sendMeetingReminder("standup")
case time.Wednesday:
sendMeetingReminder("sync")
case time.Friday:
sendMeetingReminder("retrospective")
}
}),
gocron.WithName("team-meetings"),
)j, _ := s.NewJob(
gocron.MonthlyJob(
1,
gocron.NewDaysOfTheMonth(1),
gocron.NewAtTimes(gocron.NewAtTime(12, 0, 0)),
),
gocron.NewTask(doMonthlyTask),
)// 1st and 15th at noon
j, _ := s.NewJob(
gocron.MonthlyJob(
1,
gocron.NewDaysOfTheMonth(1, 15),
gocron.NewAtTimes(gocron.NewAtTime(12, 0, 0)),
),
gocron.NewTask(doTwiceMonthly),
)// -1 = last day (adjusts for month length)
j, _ := s.NewJob(
gocron.MonthlyJob(
1,
gocron.NewDaysOfTheMonth(-1),
gocron.NewAtTimes(gocron.NewAtTime(0, 0, 0)),
),
gocron.NewTask(doEndOfMonth),
)
// Runs: Jan 31, Feb 28/29, Mar 31, Apr 30, May 31, etc.// 5 days before end of month
j, _ := s.NewJob(
gocron.MonthlyJob(
1,
gocron.NewDaysOfTheMonth(-5),
gocron.NewAtTimes(gocron.NewAtTime(10, 0, 0)),
),
gocron.NewTask(sendReminder),
)
// Runs: Jan 27, Feb 24/25, Mar 27, Apr 26, etc.// Every 3 months on the 1st at midnight
j, _ := s.NewJob(
gocron.MonthlyJob(
3,
gocron.NewDaysOfTheMonth(1),
gocron.NewAtTimes(gocron.NewAtTime(0, 0, 0)),
),
gocron.NewTask(doQuarterlyTask),
)// Last day of Mar, Jun, Sep, Dec
startDate := time.Date(time.Now().Year(), 3, 31, 23, 59, 0, 0, time.Local)
j, _ := s.NewJob(
gocron.MonthlyJob(
3,
gocron.NewDaysOfTheMonth(-1),
gocron.NewAtTimes(gocron.NewAtTime(23, 59, 0)),
),
gocron.NewTask(doQuarterEndReport),
gocron.WithStartAt(gocron.WithStartDateTime(startDate)),
)// 15th of every month at 3 PM
j, _ := s.NewJob(
gocron.MonthlyJob(
1,
gocron.NewDaysOfTheMonth(15),
gocron.NewAtTimes(gocron.NewAtTime(15, 0, 0)),
),
gocron.NewTask(doMidMonthReport),
)// 25th and last day of month at 6 AM
j, _ := s.NewJob(
gocron.MonthlyJob(
1,
gocron.NewDaysOfTheMonth(25, -1),
gocron.NewAtTimes(gocron.NewAtTime(6, 0, 0)),
),
gocron.NewTask(processPayroll),
)// 31st of every month (skips Feb, Apr, Jun, Sep, Nov)
j, _ := s.NewJob(
gocron.MonthlyJob(
1,
gocron.NewDaysOfTheMonth(31),
gocron.NewAtTimes(gocron.NewAtTime(0, 0, 0)),
),
gocron.NewTask(doTask),
)
// Only runs in Jan, Mar, May, Jul, Aug, Oct, Dec// First day of month for billing
j, _ := s.NewJob(
gocron.MonthlyJob(
1,
gocron.NewDaysOfTheMonth(1),
gocron.NewAtTimes(gocron.NewAtTime(2, 0, 0)),
),
gocron.NewTask(func() {
fmt.Println("Processing monthly billing")
processBilling()
sendInvoices()
}),
gocron.WithName("monthly-billing"),
)// Weekdays 9 AM to 5 PM every hour
for hour := 9; hour <= 17; hour++ {
h := hour // capture for closure
s.NewJob(
gocron.WeeklyJob(
1,
gocron.NewWeekdays(
time.Monday, time.Tuesday, time.Wednesday,
time.Thursday, time.Friday,
),
gocron.NewAtTimes(gocron.NewAtTime(uint(h), 0, 0)),
),
gocron.NewTask(func() {
fmt.Printf("Business hours check at %d:00\n", h)
}),
)
}// Summer hours (May-Aug): daily at 8 AM
summerStart := time.Date(time.Now().Year(), 5, 1, 8, 0, 0, 0, time.Local)
summerEnd := time.Date(time.Now().Year(), 9, 1, 0, 0, 0, 0, time.Local)
j, _ := s.NewJob(
gocron.DailyJob(1, gocron.NewAtTimes(gocron.NewAtTime(8, 0, 0))),
gocron.NewTask(doSummerTask),
gocron.WithStartAt(gocron.WithStartDateTime(summerStart)),
gocron.WithStopAt(gocron.WithStopDateTime(summerEnd)),
)
// Winter hours (Nov-Feb): daily at 9 AM
winterStart := time.Date(time.Now().Year(), 11, 1, 9, 0, 0, 0, time.Local)
winterEnd := time.Date(time.Now().Year()+1, 3, 1, 0, 0, 0, 0, time.Local)
j, _ = s.NewJob(
gocron.DailyJob(1, gocron.NewAtTimes(gocron.NewAtTime(9, 0, 0))),
gocron.NewTask(doWinterTask),
gocron.WithStartAt(gocron.WithStartDateTime(winterStart)),
gocron.WithStopAt(gocron.WithStopDateTime(winterEnd)),
)// Incremental: every 6 hours
j, _ := s.NewJob(
gocron.DurationJob(6*time.Hour),
gocron.NewTask(doIncrementalBackup),
gocron.WithName("incremental-backup"),
gocron.WithTags("backup"),
)
// Daily full backup at 2 AM
j, _ = s.NewJob(
gocron.DailyJob(1, gocron.NewAtTimes(gocron.NewAtTime(2, 0, 0))),
gocron.NewTask(doFullBackup),
gocron.WithName("daily-backup"),
gocron.WithTags("backup"),
)
// Weekly verification on Sunday at 3 AM
j, _ = s.NewJob(
gocron.WeeklyJob(
1,
gocron.NewWeekdays(time.Sunday),
gocron.NewAtTimes(gocron.NewAtTime(3, 0, 0)),
),
gocron.NewTask(verifyBackups),
gocron.WithName("backup-verification"),
gocron.WithTags("backup"),
)// All jobs use New York time
loc, _ := time.LoadLocation("America/New_York")
s, _ := gocron.NewScheduler(gocron.WithLocation(loc))
j, _ := s.NewJob(
gocron.DailyJob(1, gocron.NewAtTimes(gocron.NewAtTime(9, 0, 0))),
gocron.NewTask(doTask),
)
// Runs at 9 AM New York time// Create regional schedulers
regions := map[string]string{
"us-east": "America/New_York",
"us-west": "America/Los_Angeles",
"eu-central": "Europe/Berlin",
"asia-east": "Asia/Tokyo",
}
for region, tz := range regions {
loc, _ := time.LoadLocation(tz)
s, _ := gocron.NewScheduler(gocron.WithLocation(loc))
s.NewJob(
gocron.DailyJob(1, gocron.NewAtTimes(gocron.NewAtTime(9, 0, 0))),
gocron.NewTask(func(r string) {
fmt.Printf("Morning task for %s\n", r)
doRegionalTask(r)
}, region),
gocron.WithName(fmt.Sprintf("morning-%s", region)),
)
s.Start()
}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()
// Daily morning report at 9 AM
s.NewJob(
gocron.DailyJob(1, gocron.NewAtTimes(gocron.NewAtTime(9, 0, 0))),
gocron.NewTask(func() {
fmt.Println("Morning report at 9 AM")
}),
gocron.WithName("morning-report"),
)
// Weekly team meeting: Monday at 10 AM
s.NewJob(
gocron.WeeklyJob(
1,
gocron.NewWeekdays(time.Monday),
gocron.NewAtTimes(gocron.NewAtTime(10, 0, 0)),
),
gocron.NewTask(func() {
fmt.Println("Weekly team meeting")
}),
gocron.WithName("team-meeting"),
)
// Monthly billing: 1st of month at midnight
s.NewJob(
gocron.MonthlyJob(
1,
gocron.NewDaysOfTheMonth(1),
gocron.NewAtTimes(gocron.NewAtTime(0, 0, 0)),
),
gocron.NewTask(func() {
fmt.Println("Processing monthly billing")
}),
gocron.WithName("monthly-billing"),
)
// End of month cleanup: last day at 11 PM
s.NewJob(
gocron.MonthlyJob(
1,
gocron.NewDaysOfTheMonth(-1),
gocron.NewAtTimes(gocron.NewAtTime(23, 0, 0)),
),
gocron.NewTask(func() {
fmt.Println("End of month cleanup")
}),
gocron.WithName("month-end-cleanup"),
)
// Weekday morning standup: Mon-Fri at 9:30 AM
s.NewJob(
gocron.WeeklyJob(
1,
gocron.NewWeekdays(
time.Monday, time.Tuesday, time.Wednesday,
time.Thursday, time.Friday,
),
gocron.NewAtTimes(gocron.NewAtTime(9, 30, 0)),
),
gocron.NewTask(func() {
fmt.Println("Standup reminder")
}),
gocron.WithName("standup"),
)
// Start scheduler
s.Start()
fmt.Println("Scheduler started")
// 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...")
}DailyJob, WeeklyJob, MonthlyJobInstall with Tessl CLI
npx tessl i tessl/golang-github-com-go-co-op-gocron-v2@2.19.1docs
api
examples
guides