mirror of
https://github.com/K-Dense-AI/claude-scientific-skills.git
synced 2026-03-27 07:09:27 +08:00
3.5 KiB
3.5 KiB
Modal Scheduled Jobs
Overview
Modal supports running functions automatically on a schedule, either using cron syntax or fixed intervals. Deploy scheduled functions with modal deploy and they run unattended in the cloud.
Schedule Types
modal.Cron
Standard cron syntax — stable across deploys:
import modal
app = modal.App("scheduled-tasks")
# Daily at 9 AM UTC
@app.function(schedule=modal.Cron("0 9 * * *"))
def daily_report():
generate_and_send_report()
# Every Monday at midnight
@app.function(schedule=modal.Cron("0 0 * * 1"))
def weekly_cleanup():
cleanup_old_data()
# Every 15 minutes
@app.function(schedule=modal.Cron("*/15 * * * *"))
def frequent_check():
check_system_health()
Cron Syntax Reference
┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12)
│ │ │ │ ┌───────────── day of week (0-6, Sun=0)
│ │ │ │ │
* * * * *
| Pattern | Meaning |
|---|---|
0 9 * * * |
Daily at 9:00 AM UTC |
0 */6 * * * |
Every 6 hours |
*/30 * * * * |
Every 30 minutes |
0 0 * * 1 |
Every Monday at midnight |
0 0 1 * * |
First day of every month |
0 9 * * 1-5 |
Weekdays at 9 AM |
modal.Period
Fixed interval — resets on each deploy:
# Every 5 hours
@app.function(schedule=modal.Period(hours=5))
def periodic_sync():
sync_data()
# Every 30 minutes
@app.function(schedule=modal.Period(minutes=30))
def poll_updates():
check_for_updates()
# Every day
@app.function(schedule=modal.Period(days=1))
def daily_task():
...
modal.Period resets its timer on each deployment. If you need a schedule that doesn't shift with deploys, use modal.Cron.
Deploying Scheduled Functions
Schedules only activate when deployed:
modal deploy script.py
modal run and modal serve do not activate schedules.
Monitoring
- View scheduled runs in the Apps section of the Modal dashboard
- Each run appears with its status, duration, and logs
- Use the "Run Now" button on the dashboard to trigger manually
Management
- Schedules cannot be paused — remove the schedule and redeploy to stop
- To change a schedule, update the
scheduleparameter and redeploy - To stop entirely, either remove the
scheduleparameter or runmodal app stop <name>
Common Patterns
ETL Pipeline
@app.function(
schedule=modal.Cron("0 2 * * *"), # 2 AM UTC daily
secrets=[modal.Secret.from_name("db-creds")],
timeout=7200,
)
def etl_pipeline():
import os
data = extract(os.environ["SOURCE_DB_URL"])
transformed = transform(data)
load(transformed, os.environ["DEST_DB_URL"])
Model Retraining
@app.function(
schedule=modal.Cron("0 0 * * 0"), # Weekly on Sunday
gpu="H100",
volumes={"/data": data_vol, "/models": model_vol},
timeout=86400,
)
def retrain():
model = train_on_latest_data("/data/training/")
torch.save(model.state_dict(), "/models/latest.pt")
Health Checks
@app.function(
schedule=modal.Period(minutes=5),
secrets=[modal.Secret.from_name("slack-webhook")],
)
def health_check():
import os, requests
status = check_all_services()
if not status["healthy"]:
requests.post(os.environ["SLACK_URL"], json={"text": f"Alert: {status}"})