# How CasaOS Uses the Periodic Task Scheduler (cron) for Background Jobs

> Discover how CasaOS utilizes the periodic task scheduler cron for background jobs like hardware status broadcasting and file maintenance. Learn about its precise execution and lifecycle management.

- Repository: [IceWhale/CasaOS](https://github.com/IceWhaleTech/CasaOS)
- Tags: internals
- Published: 2026-06-27

---

**CasaOS leverages the `robfig/cron` library with second-level precision to execute recurring background tasks such as hardware status broadcasting and file maintenance, initializing schedulers in [`main/main.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/main/main.go) and managing them through graceful lifecycle hooks.**

CasaOS, the open-source home cloud system developed by IceWhaleTech, implements a **periodic task scheduler** using the `robfig/cron` library to manage background jobs efficiently. This architecture allows the system to execute recurring tasks—such as real-time hardware monitoring and file maintenance—without blocking the main application thread, ensuring responsive performance while handling critical housekeeping operations.

## Scheduler Architecture and Initialization

The system adopts a decentralized approach where both the main application and individual packages can instantiate their own cron schedulers. In [`main/main.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/main/main.go), the core entry point creates a global scheduler instance that persists for the application's lifetime.

### Global Instance with Second-Level Precision

Lines 121-127 of [`main/main.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/main/main.go) establish the primary scheduler using `cron.New(cron.WithSeconds())`, enabling second-level granularity critical for real-time monitoring. This configuration distinguishes CasaOS's implementation from standard minute-level cron systems.

```go
crontab := cron.New(cron.WithSeconds())

```

The scheduler is started after task registration and includes a deferred shutdown hook: `defer crontab.Stop()`. This ensures that when the main process exits, all background goroutines terminate cleanly without resource leaks.

## Registering Background Jobs

Jobs are registered using either the `@every` duration syntax or standard cron expressions, with callbacks defined as standard Go functions. CasaOS uses both patterns depending on the required granularity.

### Hardware Status Broadcasting

The primary periodic job runs every 5 seconds to push system telemetry to the frontend. In [`main/main.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/main/main.go), this is registered as:

```go
if _, err := crontab.AddFunc("@every 5s", route.SendAllHardwareStatusBySocket); err != nil {
    logger.Error("add crontab error", zap.Error(err))
}

```

The callback function `SendAllHardwareStatusBySocket` resides in [`route/periodical.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/periodical.go) (lines 25-74). This function gathers CPU, memory, network, and temperature data from the system service, constructs a payload, and broadcasts it via the notification bus using the channel `casaos:system:utilization`.

### File Maintenance Tasks

In [`route/v1/file.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/v1/file.go) (lines 988-1000), a separate scheduler instance handles file-related cleanup operations. This implementation uses a quartz-style cron expression to execute every 30 seconds:

```go
crontab := cron.New(cron.WithSeconds())
spec := "*/30 * * * * ?" // every 30 seconds
crontab.AddFunc(spec, task)
crontab.Start()

```

This pattern demonstrates how individual packages can manage their own lifecycle without interfering with the global scheduler.

## Lifecycle Management and Graceful Shutdown

Proper resource management is critical for long-running daemons. CasaOS handles this by:

1. **Initializing** the scheduler with `cron.New(cron.WithSeconds())`
2. **Registering** jobs immediately after creation
3. **Starting** the scheduler with `crontab.Start()`
4. **Deferring** shutdown with `defer crontab.Stop()` to guarantee cleanup on process exit

This pattern prevents orphan goroutines and ensures that all pending jobs complete or receive termination signals before the application closes.

## Practical Code Examples

### Initializing a Custom Scheduler

The following pattern mirrors CasaOS's approach for creating a second-precision scheduler with error handling:

```go
package main

import (
    "github.com/robfig/cron/v3"
    "log"
)

func main() {
    // Create a second-precision scheduler
    scheduler := cron.New(cron.WithSeconds())

    // Register a job that runs every 10 seconds
    _, err := scheduler.AddFunc("@every 10s", func() {
        log.Println("Running periodic cleanup")
        // …insert cleanup logic here…
    })
    if err != nil {
        log.Fatalf("failed to add cron job: %v", err)
    }

    // Start the scheduler
    scheduler.Start()
    defer scheduler.Stop()

    // Block forever (or replace with your server’s run loop)
    select {}
}

```

### Hardware Status Function Implementation

The actual task implementation from [`route/periodical.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/periodical.go) shows how to integrate system monitoring with the notification system:

```go
func SendAllHardwareStatusBySocket() {
    netList := service.MyService.System().GetNetInfo()
    // …collect network, CPU, memory, temperature…
    body := map[string]interface{}{
        "sys_mem": memInfo,
        "sys_cpu": cpuData,
        "sys_net": newNet,
    }
    // Push to front-end via notification bus
    service.MyService.Notify().SendNotify("casaos:system:utilization", body)
}

```

## Summary

- CasaOS uses the `robfig/cron/v3` library with second-level precision for all background job scheduling
- The global scheduler is initialized in [`main/main.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/main/main.go) using `cron.New(cron.WithSeconds())` to enable sub-minute intervals
- Hardware status updates run every 5 seconds via `SendAllHardwareStatusBySocket` in [`route/periodical.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/periodical.go)
- File cleanup tasks use quartz expressions like `*/30 * * * * ?` in [`route/v1/file.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/v1/file.go) with independent scheduler instances
- Graceful shutdown is guaranteed via `defer crontab.Stop()` to prevent resource leaks

## Frequently Asked Questions

### What cron library does CasaOS use?

CasaOS uses the `github.com/robfig/cron/v3` library, which provides standard cron expression parsing along with extended features like second-level precision and the `@every` duration syntax. This dependency is declared in the project's `go.mod` file.

### How frequently does CasaOS broadcast hardware status updates?

According to the source code in [`main/main.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/main/main.go), the system broadcasts hardware status every 5 seconds using the `@every 5s` descriptor. This triggers the `SendAllHardwareStatusBySocket` function defined in [`route/periodical.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/periodical.go), which collects CPU, memory, network, and temperature metrics.

### How does CasaOS prevent resource leaks from background goroutines?

The application ensures clean shutdown by calling `defer crontab.Stop()` immediately after starting the scheduler. This deferred function signals all running cron jobs to terminate gracefully when the main process exits, preventing goroutine leaks and ensuring proper cleanup of system resources.

### Can cron jobs run at sub-minute intervals in CasaOS?

Yes, by initializing the scheduler with `cron.WithSeconds()`, CasaOS supports sub-minute intervals that would be impossible with standard minute-level cron implementations. This allows expressions like `@every 5s` for hardware monitoring or `*/30 * * * * ?` for file cleanup tasks running every 30 seconds.