Functions can automatically retry on failure. Pass a simple integer for max-attempts with default exponential backoff, or use RetryPolicy for full control:

import chalkcompute
from chalkcompute import RetryPolicy

# Simple: retry up to 3 times with exponential backoff
@chalkcompute.function(retries=3)
def flaky_api(query: str) -> str:
    ...

# Exponential backoff with custom parameters
@chalkcompute.function(
    retries=RetryPolicy.exponential(
        attempts=5,
        initial=0.5,
        max_wait=30.0,
    ),
)
def resilient_call(payload: str) -> str:
    ...

# Fixed delay, only retry on specific exceptions
@chalkcompute.function(
    retries=RetryPolicy.linear(
        attempts=3,
        delay=2.0,
        retry_on=(TimeoutError, ConnectionError),
    ),
)
def network_call(url: str) -> str:
    ...

​
RetryPolicy.exponential()

Wait times grow geometrically: initial, initial * multiplier, initial * multiplier², …, capped at max_wait:

ParameterTypeDefaultDescription
attemptsint3Max retry attempts
initialfloat1.0Base wait time in seconds
multiplierfloat2.0Backoff multiplier
max_waitfloat60.0Upper bound on wait time
jitterboolTrueAdd random jitter
retry_ontuple[type, ...](Exception,)Exception types that trigger retry

​
RetryPolicy.linear()

Fixed delay between retries:

ParameterTypeDefaultDescription
attemptsint3Max retry attempts
delayfloat1.0Fixed wait in seconds
jitterboolFalseAdd random jitter
retry_ontuple[type, ...](Exception,)Exception types that trigger retry

​
Exception filtering

By default, all Exception subclasses trigger a retry. Pass a tuple of exception classes to retry_on to restrict which failures are retried:

RetryPolicy.exponential(
    attempts=4,
    retry_on=(ConnectionError, TimeoutError, OSError),
)

Non-matching exceptions propagate immediately without consuming retry budget.