Functions and Scaling Groups
Run a Chalk Function on a recurring schedule with a crontab expression or a duration string.
Some jobs run on a clock instead of in response to a request: refreshing a
table of exchange rates, recomputing a daily rollup, warming a cache,
syncing an external source.
A scheduled function is a Function that Chalk invokes for you on a recurring
schedule: declare a schedule in the decorator, and Chalk runs it at the
cadence you specify, with the image, resources, secrets, and retry behavior
you configured. There is no separate cron server to operate.
import chalkcompute
@chalkcompute.function(
schedule="0 * * * *", # every hour, on the hour
secrets=[chalkcompute.Secret.from_chalk_env("EXCHANGE_API_KEY")],
cpu="1",
memory="2Gi",
retries=3,
)
def refresh_exchange_rates() -> None:
import os
import requests
resp = requests.get(
"https://api.example.com/v1/rates",
params={"base": "USD"},
headers={"Authorization": f"Bearer {os.environ['EXCHANGE_API_KEY']}"},
)
rates = resp.json()["rates"]
# write the latest rates to your store
...
schedule and retries govern how and when the platform invokes the
function; everything else configures the Scaling Group that hosts it, exactly
as it would for an on-demand function. Scheduled jobs often do heavier work,
such as nightly batch inference or periodic re-scoring of a dataset, and can
request a GPU the same way:
@chalkcompute.function(
schedule="0 3 * * *", # daily at 03:00 UTC
gpu="nvidia-l4",
cpu="4",
memory="16Gi",
)
def nightly_batch_inference() -> None:
...
schedule accepts either a crontab expression or a Chalk duration string. Use
whichever reads more clearly for your cadence. All schedules are evaluated
in UTC.
Crontab: five space-separated fields (minute hour day-of-month month day-of-week). Standard syntax is supported: *, lists (1,15), ranges
(1-5), and steps (*/10).
| Expression | Runs |
|---|---|
"*/10 * * * *" | every 10 minutes |
"0 * * * *" | every hour, on the hour |
"0 2 * * *" | every day at 02:00 UTC |
"0 0 * * 0" | every Sunday at 00:00 UTC |
Duration shorthand: a single interval, for simple cadences. Supported units are minutes (≤ 60), hours (≤ 24), and days (= 1), written as one value:
| Shorthand | Runs | Equivalent crontab |
|---|---|---|
"10m" | every 10 minutes | */10 * * * * |
"6h" | every 6 hours | 0 */6 * * * |
"1d" | every day | 0 0 * * * |
Shorthand intervals are aligned to clock boundaries, not to your deployment
time: "6h" runs at 00:00, 06:00, 12:00, and 18:00 UTC. Anything longer or
compound ("90m", "1h30m", "2d") must be written as a crontab expression.
@chalkcompute.function(schedule="0 2 * * *") # nightly at 02:00 UTC
def nightly_rollup() -> None:
...
@chalkcompute.function(schedule="15m") # every 15 minutes
def warm_cache() -> None:
...
Because a scheduled function is invoked by the platform rather than a caller, two constraints apply and are enforced when the function is defined:
yield. Return None (or a value)
instead.Everything else about a Compute Function still applies: custom images, resource requests, secrets, and retries all work exactly as they do for on-demand functions.
Each invocation appears in the Chalk dashboard with its status, logs, and resource usage, just like a manually invoked function. Emit logs from the body to make each run observable:
from chalk import chalk_logger
@chalkcompute.function(schedule="1h")
def refresh_exchange_rates() -> None:
chalk_logger.info("refresh started")
rates = ... # fetch the latest rates and write them to your store
chalk_logger.info("refreshed %s rates", len(rates))