FastAPI-Cronsv2.4.0

CronConfig

Every setting is read from the environment when CronConfig() is constructed, and can be overridden in code afterwards.

python
from fastapi_crons import Crons, CronConfig

config = CronConfig()
config.sqlite_db_path = "var/cron_state.db"
config.enable_distributed_locking = True

crons = Crons(app, config=config)

Construct the config before the scheduler

Crons() reads the config once, at construction, to build the default state backend and lock manager. Mutating it afterwards will not retroactively change those.

Environment variables

The full set of variables, with their defaults.

General

VariableDefaultDescription
CRON_INSTANCE_IDrandom 8 charsIdentifies this scheduler instance in state and locks.
CRON_SQLITE_DB_PATHcron_state.dbPath to the SQLite state database.
CRON_LOG_LEVELINFOLogger level.
CRON_ENABLE_JOB_LOGGINGtrueLog each job start and finish.

Redis

VariableDefaultDescription
CRON_REDIS_URLunsetFull connection URL. Takes precedence over the host and port settings.
CRON_REDIS_HOSTlocalhostRedis host.
CRON_REDIS_PORT6379Redis port.
CRON_REDIS_DB0Redis database number.
CRON_REDIS_PASSWORDunsetRedis password.

Locking

VariableDefaultDescription
CRON_ENABLE_DISTRIBUTED_LOCKINGfalseTurn on distributed locking. Accepts true, 1 or yes.
CRON_LOCK_TTL300Seconds before an abandoned lock expires.

Retries and timeouts

VariableDefaultDescription
CRON_DEFAULT_MAX_RETRIES0Retry attempts for jobs that do not set their own.
CRON_DEFAULT_RETRY_DELAY1.0Initial delay in seconds.
CRON_RETRY_BACKOFF_MULTIPLIER2.0Exponential backoff factor.
CRON_MAX_RETRY_DELAY300.0Ceiling on any single backoff delay.
CRON_DEFAULT_JOB_TIMEOUTunsetDefault job timeout in seconds. No timeout when unset.

Set CRON_INSTANCE_ID in production

It defaults to a random value generated at startup, so a restarted replica gets a new identity. Pin it to something stable — the pod or hostname — to keep lock ownership and state attribution readable.

Inspecting the active config

bash
python -m fastapi_crons.cli config-show

OpenTelemetry

Install the otel extra, then register the tracing hooks. Each run becomes a span carrying the job name, tags and outcome.

python
from fastapi_crons import OpenTelemetryHooks, is_otel_available

if is_otel_available():
    otel = OpenTelemetryHooks(service_name="my-app-crons")
    crons.add_before_run_hook(otel.before_run)
    crons.add_after_run_hook(otel.after_run)
    crons.add_on_error_hook(otel.on_error)

is_otel_available() returns False when the extra is not installed, so the block above is safe to leave in code that ships without it.

Thread safety

Sync jobs run in a thread pool while async jobs share the event loop. The scheduler itself is safe to use from both, but your job bodies are not automatically protected — guard any shared mutable state you touch, and use a connection pool rather than a single shared database connection.

Esc
IntroductionGetting StartedInstallationGetting StartedQuick StartGetting StartedCron ExpressionsCore ConceptsDefining JobsCore ConceptsHooksCore ConceptsConfigurationCore ConceptsState BackendsBackendsDistributed LockingBackendsDashboardOperationsHTTP EndpointsOperationsCLIOperations