Functions and Scaling Groups
Define and call remote functions that run on Chalk Compute.
A Chalk Function is a Python callable that you deploy onto a
Scaling Group and register in the
Chalk Catalog. Decorate a function
with @chalkcompute.function and it becomes reachable from anywhere Chalk
runs: local scripts and notebooks, other functions, and (because of the
Catalog registration) the feature engine, including Chalk SQL, resolvers, the
query server, and DataFrames via F.catalog_call(). Arguments and results are
serialized automatically; you write ordinary Python and Chalk handles
scheduling, scaling, and delivery.
On top of what a bare Scaling Group provides, functions add async / streaming invocation, nested calls, automatic retries, concurrency caps, rate limits, and request-queue-driven autoscaling. Reach for a function when you want any of those features, or when you want the callable to be visible to the rest of Chalk.
Functions support three return styles:
yield results incrementally and the caller receives them as
they’re produced. See Streaming results
for an end-to-end example.To define and deploy a function, see Defining a function.
For jobs with multiple steps and separate task environments, see Workflows.
@chalkcompute.function is backed by Chalk Compute’s async execution layer.
At a high level, calling a function goes through three moving parts:
┌──────────┐ ┌──────────────────┐ ┌───────────┐
│ Caller │──call──▸│ Function Queue │──run───▸│ Worker │
│ │◂results─│ │◂results─│ (Python) │
└──────────┘ └──────────────────┘ └───────────┘
Callers and workers are loosely coupled: the caller never opens a connection directly to a worker. Workers can scale up, scale down, or get rescheduled mid-flight and in-flight calls are not lost. This is what enables streaming async generators, nested calls, and policy-enforced dispatch.
The queue enforces the policies declared on each function (rate limit, concurrency, and retries) before dispatching work to the worker.
| Policy | What it caps |
|---|---|
rate_limit | Outbound requests per second / minute / hour, optionally shared across functions via a key. |
concurrency | In-flight invocations at once, optionally shared across functions via a key. Defaults to 1 per function. |
retries | Automatic retry of transient failures (UNAVAILABLE, DEADLINE_EXCEEDED, RESOURCE_EXHAUSTED, ABORTED) with exponential backoff and jitter. Other errors are terminal. |
Concurrency is acquired before dispatching, so a burst of queued calls backpressures on the semaphore rather than spawning unbounded tasks. Rate-limit tokens are consumed per attempt: each retry takes a fresh token.
Retries are safe for failures that happen before the function has started
streaming results: connection errors, DEADLINE_EXCEEDED on the initial
call, etc. If a function has already yielded chunks when it fails, those
chunks are visible to the caller and a retry would produce an ambiguous
stream. Retries therefore apply cleanly only to pre-stream failures today;
making mid-stream retries safe is a known follow-up.