DEV Community

Shrijith Venkatramana
Shrijith Venkatramana

Posted on

3 3 3 3 3

Golang: Implementing Cron-Like Tasks / Executing Tasks at a Specific Time

Scheduling tasks in Golang is a common requirement for automation, background jobs, and periodic tasks. This article explores different approaches, from simple time-based execution to robust scheduling libraries and cloud-native solutions.

Am I A Joke To You?

1. Raw Implementation Using time Package

For simple task scheduling, you can use the time package in Go.

1.1 Using time.AfterFunc (One-time Delayed Execution)

package main

import (
    "fmt"
    "time"
)

func main() {
    time.AfterFunc(3*time.Second, func() {
        fmt.Println("Executed after 3 seconds")
    })

    // Prevent the program from exiting immediately
    time.Sleep(5 * time.Second)
}
Enter fullscreen mode Exit fullscreen mode

Output:

Executed after 3 seconds
Enter fullscreen mode Exit fullscreen mode

1.2 Using time.Ticker (Periodic Execution)

package main

import (
    "fmt"
    "time"
)

func main() {
    ticker := time.NewTicker(2 * time.Second)
    defer ticker.Stop()

    for i := 0; i < 3; i++ {
        <-ticker.C
        fmt.Println("Task executed at:", time.Now())
    }
}
Enter fullscreen mode Exit fullscreen mode

Output:

Task executed at: 2025-02-07 12:00:00 +0000 UTC
Task executed at: 2025-02-07 12:00:02 +0000 UTC
Task executed at: 2025-02-07 12:00:04 +0000 UTC
Enter fullscreen mode Exit fullscreen mode

Pros:

  • Lightweight, built into Go
  • No external dependencies

Cons:

  • Requires manual handling of concurrency and persistence
  • Limited to running inside the same process

2. Using cron-like Libraries in Go

For more complex scheduling needs, use existing cron libraries that offer better flexibility and reliability.

2.1 Using robfig/cron (Crontab Syntax Support)

Install the library:

go get github.com/robfig/cron/v3
Enter fullscreen mode Exit fullscreen mode

Example:

package main

import (
    "fmt"
    "time"

    "github.com/robfig/cron/v3"
)

func main() {
    c := cron.New()

    // Schedule a job every 5 seconds
    c.AddFunc("*/5 * * * * *", func() {
        fmt.Println("Cron job executed at:", time.Now())
    })

    c.Start()

    // Keep the main function running
    select {}
}
Enter fullscreen mode Exit fullscreen mode

2.2 Using gocron (Simpler API for Recurring Jobs)

Install:

go get github.com/go-co-op/gocron
Enter fullscreen mode Exit fullscreen mode

Example:

package main

import (
    "fmt"
    "time"

    "github.com/go-co-op/gocron"
)

func main() {
    s := gocron.NewScheduler(time.UTC)

    s.Every(10).Seconds().Do(func() {
        fmt.Println("Scheduled task executed at:", time.Now())
    })

    s.StartAsync()

    // Prevent exit
    select {}
}
Enter fullscreen mode Exit fullscreen mode

Pros:

  • More robust than time.Ticker
  • Supports standard cron expressions

Cons:

  • Runs within the Go process (needs process monitoring)

3. Using System cron (Best for CLI Execution)

Instead of running a Go process indefinitely, you can execute a Go script using Linux's cron daemon.

Example crontab Entry (Runs Every Minute)

* * * * * /path/to/your-go-program
Enter fullscreen mode Exit fullscreen mode

To set this up:

  1. Build the Go program:
   go build -o mytask mytask.go
Enter fullscreen mode Exit fullscreen mode
  1. Add it to crontab -e:
   * * * * * /path/to/mytask
Enter fullscreen mode Exit fullscreen mode

Pros:

  • More stable, managed by the OS
  • Easy to monitor and log

Cons:

  • Requires additional setup
  • Limited to CLI tasks

4. Cloud-Native Approaches

If you're deploying to the cloud, managed solutions may be better.

4.1 Google Cloud Run Jobs

  • Deploy a container that runs on a schedule.
  • Use Google Cloud Scheduler to trigger the job.
gcloud scheduler jobs create http my-job \
  --schedule="*/10 * * * *" \
  --uri="https://your-cloud-run-service-url"
Enter fullscreen mode Exit fullscreen mode

4.2 AWS Lambda with EventBridge

Create an AWS Lambda function and trigger it using EventBridge (formerly CloudWatch Events).

Example EventBridge rule (runs every 5 minutes):

{
  "ScheduleExpression": "rate(5 minutes)"
}
Enter fullscreen mode Exit fullscreen mode

4.3 Kubernetes CronJobs

Example cronjob.yaml (Runs Every Hour):

apiVersion: batch/v1
kind: CronJob
metadata:
  name: my-cronjob
spec:
  schedule: "0 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: my-job
            image: my-go-image
          restartPolicy: OnFailure
Enter fullscreen mode Exit fullscreen mode

Pros:

  • Fully managed, scalable
  • Works well in containerized environments

Cons:

  • Requires cloud setup and configuration

5. Comparing the Options: What Should You Use?

Approach Best For Pros Cons
time.Ticker Simple recurring jobs No dependencies, lightweight Needs manual persistence & recovery
robfig/cron Flexible job scheduling Crontab syntax, well-tested Runs inside app, process-dependent
System cron CLI-based scheduled tasks OS-managed, stable Limited logging, debugging overhead
Cloud Run Jobs Serverless scheduled tasks Fully managed, scalable Cloud-dependent, cold starts
Kubernetes CronJobs Containerized jobs Scalable, cloud-native Requires Kubernetes setup

Conclusion

  • If you need simple, in-process scheduling, use time.Ticker.
  • If you want crontab-like flexibility, use robfig/cron.
  • If your task is system-wide, use system cron.
  • For cloud-native workloads, use Cloud Run, Lambda, or Kubernetes CronJobs.

By choosing the right approach, you can ensure that your scheduled tasks run efficiently and reliably.

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

Top comments (0)