Skip to main content
Cron jobs run shell commands on a schedule inside your service’s container image. Declare them in floo.app.toml and they are synced on every deploy.

Declare in config

Add [cron.<name>] sections to floo.app.toml:
[app]
name = "my-app"

[cron.daily-report]
schedule = "0 9 * * *"                  # 9am UTC daily
command = "python scripts/daily_report.py"
service = "web"                          # which service's image to run in

[cron.cleanup]
schedule = "*/5 * * * *"                 # every 5 minutes
command = "node scripts/cleanup.js"
service = "worker"
timeout = 600                            # max seconds (default 300)

[services.web]
type = "web"
path = "."
port = 3000
ingress = "public"

[services.worker]
type = "worker"
path = "./worker"
ingress = "internal"

Fields

FieldRequiredDescription
scheduleyesStandard cron expression (e.g. "0 9 * * *" for 9am daily, "*/5 * * * *" for every 5 minutes)
commandyesShell command to execute inside the container
serviceyesName of the service whose image to run the command in — must match a [services.*] entry
timeoutnoMax execution time in seconds (default: 300)

Deploy and verify

Push to GitHub or run floo redeploy. Cron jobs are synced on every deploy — new jobs are created, changed jobs are updated, removed jobs are deleted.
git push origin main && floo deploys watch --app my-app
After deploy, verify your jobs:
floo cron list --app my-app

Manually trigger a job

Test a job without waiting for its schedule:
floo cron run daily-report --app my-app

Common schedule expressions

ExpressionMeaning
* * * * *Every minute
*/5 * * * *Every 5 minutes
0 * * * *Every hour
0 9 * * *Daily at 9am UTC
0 9 * * 1-5Weekdays at 9am UTC
0 0 * * 0Weekly on Sunday at midnight UTC
0 0 1 * *Monthly on the 1st at midnight UTC

How it works

  1. You declare [cron.<name>] in floo.app.toml
  2. The CLI sends cron definitions to the API during deploy
  3. The API’s _sync_cron_jobs() creates, updates, or deletes CronJob records
  4. Jobs run inside the specified service’s container image with the same environment variables
Cron jobs have access to the same DATABASE_URL, REDIS_URL, and other env vars as the service they run in.

Agent workflow

# List cron jobs (JSON for parsing)
floo cron list --app my-app --json 2>/dev/null | jq '.data.cron_jobs'

# Trigger a job manually
floo cron run daily-report --app my-app --json 2>/dev/null