CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/golang-github-com-go-co-op-gocron-v2

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.

Overview
Eval results
Files

cron-scheduling.mddocs/examples/by-task/

Cron Scheduling Examples

Schedule jobs using cron expressions for precise time-based scheduling.

Basic Cron Expressions

Every 5 Minutes

j, _ := s.NewJob(
    gocron.CronJob("*/5 * * * *", false),
    gocron.NewTask(doWork),
)

Every Hour at Minute 0

j, _ := s.NewJob(
    gocron.CronJob("0 * * * *", false),
    gocron.NewTask(doHourlyTask),
)

Every Day at 9:30 AM

j, _ := s.NewJob(
    gocron.CronJob("30 9 * * *", false),
    gocron.NewTask(doMorningReport),
)

Day-of-Week Patterns

Every Monday at 10 AM

// 0=Sunday, 1=Monday, 2=Tuesday, etc.
j, _ := s.NewJob(
    gocron.CronJob("0 10 * * 1", false),
    gocron.NewTask(doWeeklyCleanup),
)

Weekdays at 9 AM

// 1-5 = Monday through Friday
j, _ := s.NewJob(
    gocron.CronJob("0 9 * * 1-5", false),
    gocron.NewTask(doWeekdayTask),
)

Weekends at 8 AM

// 0,6 = Sunday and Saturday
j, _ := s.NewJob(
    gocron.CronJob("0 8 * * 0,6", false),
    gocron.NewTask(doWeekendTask),
)

Day-of-Month Patterns

First Day of Month at Midnight

j, _ := s.NewJob(
    gocron.CronJob("0 0 1 * *", false),
    gocron.NewTask(doMonthlyTask),
)

Mid-Month on 15th

j, _ := s.NewJob(
    gocron.CronJob("0 15 15 * *", false),
    gocron.NewTask(doMidMonthReport),
)

Last Day of Month

// 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()
        }
    }),
)

6-Field Cron (With Seconds)

Every 30 Seconds

j, _ := s.NewJob(
    gocron.CronJob("*/30 * * * * *", true), // withSeconds=true
    gocron.NewTask(doQuickCheck),
)

Every 15 Seconds

j, _ := s.NewJob(
    gocron.CronJob("*/15 * * * * *", true),
    gocron.NewTask(func() {
        fmt.Println("High-frequency check")
    }),
)

Precise Timing: 10:30:45 AM

j, _ := s.NewJob(
    gocron.CronJob("45 30 10 * * *", true),
    gocron.NewTask(doPreciseTask),
)

Business Hours Patterns

Every 15 Minutes During Business Hours

// Cron: every 15 minutes, weekdays only, 9 AM - 5 PM
j, _ := s.NewJob(
    gocron.CronJob("*/15 9-17 * * 1-5", false),
    gocron.NewTask(doBusinessHoursTask),
)

Every Hour During Business Hours

// On the hour, 9 AM to 5 PM, weekdays
j, _ := s.NewJob(
    gocron.CronJob("0 9-17 * * 1-5", false),
    gocron.NewTask(doHourlyBusinessTask),
)

Lunch Break Check

// Every day at noon
j, _ := s.NewJob(
    gocron.CronJob("0 12 * * *", false),
    gocron.NewTask(func() {
        fmt.Println("Lunch time check")
    }),
)

Complex Day Patterns

First Monday of Every Month

// 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

Last Friday of Every Month

// 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()
        }
    }),
)

Every Other Day

// 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),
)

Timezone Support

With TZ Prefix

// 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),
)

Multi-Timezone Reporting

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)),
    )
}

Daylight Saving Time Handling

// 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")
    }),
)

Common Cron Patterns

Every Minute

j, _ := s.NewJob(
    gocron.CronJob("* * * * *", false),
    gocron.NewTask(doEveryMinute),
)

Every 10 Minutes

j, _ := s.NewJob(
    gocron.CronJob("*/10 * * * *", false),
    gocron.NewTask(doEvery10Minutes),
)

Every 30 Minutes

j, _ := s.NewJob(
    gocron.CronJob("*/30 * * * *", false),
    gocron.NewTask(doEvery30Minutes),
)

Every 2 Hours

j, _ := s.NewJob(
    gocron.CronJob("0 */2 * * *", false),
    gocron.NewTask(doEvery2Hours),
)

Daily at Midnight

j, _ := s.NewJob(
    gocron.CronJob("0 0 * * *", false),
    gocron.NewTask(doDailyMidnightTask),
)

Daily at Multiple Times

// 9 AM, noon, and 5 PM
j, _ := s.NewJob(
    gocron.CronJob("0 9,12,17 * * *", false),
    gocron.NewTask(doMultipleTimesDaily),
)

Seasonal Schedules

Summer Hours (May-August)

// Runs May through August only
j, _ := s.NewJob(
    gocron.CronJob("0 8 * 5-8 *", false),
    gocron.NewTask(doSummerTask),
)

Quarterly Reports

// 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),
)

Holiday Schedule

// 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()
    }),
)

Multiple Cron Jobs

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 {}
}

Error Handling

Invalid Cron Expression

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)
    }
}

Validating Cron Before Use

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)
}

Complete Cron Example

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...")
}

Cron Expression Quick Reference

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)

Related Documentation

  • API: Job DefinitionsCronJob
  • Guide: Advanced Scheduling
  • Examples: Time-Based Scheduling
  • Examples: Interval Scheduling

Install with Tessl CLI

npx tessl i tessl/golang-github-com-go-co-op-gocron-v2@2.19.1

docs

index.md

tile.json