CronLib is a lightweight, thread-safe, and high-performance cron scheduling library for Go. It is designed to handle thousands of concurrent jobs with sub-millisecond precision, mirroring node-cron functionality but optimized for the Go ecosystem.
- 🚀 High Performance: Bitmask-based parser for O(1) matching of cron fields.
- 🕒 Sub-millisecond Precision: Uses
time.Timerfor event-driven scheduling (no polling tickers). - 🔒 Thread-Safe: Safe for concurrent job management (adding, removing, stopping).
- ⚙️ Overlap Policies: Control job execution overlap with
Allow,Forbid, orReplacepolicies. - 💾 Persistence: Native SQLite support to track last run times and execution history.
- 🌐 Distributed Locks: Redis integration for cluster-wide job synchronization.
- 🖥️ Web Dashboard: Built-in UI to monitor job status and execution logs in real-time.
- 🕒 Timezone Support: Full support for job-specific execution locations.
This project follows Semantic Versioning 2.0.0.
We use GoReleaser to automate our release process. Every time a new version tag (e.g., v0.1.0) is pushed, a corresponding GitHub Release is created with an automatically generated changelog.
- Go: 1.24 or higher.
- Targeting: Built for high-performance and modern Go concurrency patterns.
To install the latest version:
go get github.com/raythurman2386/cronlibTo install a specific version:
go get github.com/raythurman2386/cronlib@v0.1.2package main
import (
"fmt"
"time"
"github.com/raythurman2386/cronlib"
)
func main() {
c := cronlib.NewCron()
// Add a job: runs every 5 seconds
c.AddJob("*/5 * * * * *", func() {
fmt.Println("Tick:", time.Now().Format("15:04:05"))
})
c.Start()
select {} // Keep running
}CronLib supports standard 6-field cron syntax (sec, min, hour, dom, month, dow) and convenient macros:
@yearly,@annually: Run once a year.@monthly: Run once a month.@weekly: Run once a week.@daily,@midnight: Run once a day.@hourly: Run once an hour.
For simple fixed-interval schedules, use @every:
// Runs every 1 hour and 30 minutes
c.AddJob("@every 1h30m", func() {
fmt.Println("Tick")
})CronLib provides fine-grained control over how jobs behave when a new execution is scheduled while a previous instance is still running.
| Policy | Description |
|---|---|
OverlapAllow |
(Default) Allows multiple instances to run concurrently. |
OverlapForbid |
Skips the execution if the previous instance is still running. |
OverlapReplace |
Cancels the running instance and starts the new one immediately. |
c.AddJobWithOptions("*/10 * * * * *", myTask, cronlib.JobOptions{
Overlap: cronlib.OverlapReplace,
})You can extend job behavior using composable wrappers. CronLib applies Recover, Lock (if configured), and Log (if configured) by default, but you can add custom logic.
Standard Wrappers:
Recover(): Catches panics and prevents the scheduler from crashing.DelayIfStillRunning(): Queues execution if the previous run hasn't finished (ensures sequential execution).SkipIfStillRunning(): Skips execution if busy (alternative toOverlapForbid).
c.AddJobWithOptions("@every 1s", myTask, cronlib.JobOptions{
Wrappers: []cronlib.JobWrapper{
cronlib.DelayIfStillRunning(),
MyCustomMetricsWrapper(),
},
})Track job history and recover schedules across restarts.
import "github.com/raythurman2386/cronlib/pkg/store/sqlite"
store, _ := sqlite.New("cron.db")
c.SetJobStore(store)Ensure a job runs only once across a cluster.
import "github.com/raythurman2386/cronlib/pkg/lock/redis"
lock := redis.New("localhost:6379")
c.SetDistLock(lock)Embedded UI accessible at http://localhost:8080.
import "github.com/raythurman2386/cronlib/pkg/dashboard"
http.Handle("/", dashboard.NewHandler(c))
http.ListenAndServe(":8080", nil)The Web Dashboard provides a live view of:
- Job ID & Expression
- Next Scheduled Run
- Last Execution Time
- Real-time Status (Running/Idle)
Explore more realistic implementation patterns in the examples/ directory:
- 🚀 IoT Ingestion: High-frequency polling with sub-millisecond precision monitoring.
- 🔒 Distributed Singleton: Cluster-wide job synchronization using Redis locks.
- 💾 Persistent Recovery: Resuming schedules and tracking history using SQLite.
- ⚙️ Overlap Control: Demonstrating
ForbidandReplacepolicies for slow tasks. - 🌐 Full Stack: A complete implementation featuring the dashboard, persistence, and locking.
You can run any example using:
go run examples/iot/main.goMIT