Cron jobs run commands on a schedule and exit when the work is complete. Use them for reports, periodic cleanup, and other bounded tasks. They expose no HTTP endpoint. Use a background worker for a continuous consumer or a process that should remain running.
Deploy a scheduled command
The repository's cron demo prints a message every five minutes:
services:
- name: cron-demo
type: cron
runtime: docker
repo: https://github.com/bex-co/bex
rootDir: examples/cron-demo
branch: main
schedule: "*/5 * * * *"
plan: free
envVars:
- key: MESSAGE
value: "hello from the Bex cron job"Follow the Blueprint guide to authenticate, validate, and
deploy the file. Docker cron jobs run the image's default command; for a
Dockerfile build, dockerCommand can override it. Native-runtime jobs need
build and start commands appropriate to the selected runtime.
Use a standard five-field cron expression: minute, hour, day of month, month, and day of week. Bex currently passes the expression to Kubernetes without setting a per-job timezone. The Kubernetes controller's timezone determines wall-clock scheduling; confirm it with your instance operator before relying on a particular local hour. The every-five-minutes example avoids that ambiguity.
Inspect runs separately from deployments
A deployment prepares the executable and schedule. A run executes the command.
An App phase of Running means the cron schedule is configured, not that the
last execution succeeded. Open the dashboard's run history to inspect each
run's status and logs.
For API access, set BEX_API_URL to your API origin, BEX_TOKEN to an
authorized Bearer token, and SERVICE_ID to the cron service's id:
curl --fail-with-body "$BEX_API_URL/v1/cron-jobs/$SERVICE_ID/runs" \
-H "Authorization: Bearer $BEX_TOKEN"Trigger or cancel a run
A manual trigger can interrupt current work: Bex requests cancellation of an active run before creating the replacement. To trigger:
curl --fail-with-body -X POST \
"$BEX_API_URL/v1/cron-jobs/$SERVICE_ID/runs" \
-H "Authorization: Bearer $BEX_TOKEN"The response represents the requested run; cancellation and startup happen asynchronously. Follow run history and logs for the outcome. To cancel the currently active run:
curl --fail-with-body -X DELETE \
"$BEX_API_URL/v1/cron-jobs/$SERVICE_ID/runs" \
-H "Authorization: Bearer $BEX_TOKEN"Cancellation does not undo database writes or external side effects already performed. Make jobs safe to retry and protect operations that must not run twice.
Scheduling and execution limits
- Scheduled runs use Kubernetes
Forbidconcurrency policy. Overlapping scheduled executions are skipped rather than launched concurrently. The operator also suspends the schedule while a manual run is active. - Suspending the service pauses scheduling; use cancellation to stop an active run. Resume restores scheduling. Do not rely on suspension as an exact replay queue for missed work.
- Bex's current cron controller does not set a 12-hour job deadline. Set a timeout in your application when tasks must finish within a fixed duration.
- Cron jobs do not expose a listener or have HTTP readiness checks. Use run results and logs to detect failure.
These are Bex implementation details. Render's cron documentation describes its own scheduling and maximum-duration behavior; do not assume those limits transfer unchanged.
Troubleshoot a missing or failed run
Check that the deployment completed, the schedule is valid, the service is not suspended, and another execution is not still active. For failed executions, inspect the command's exit status and logs, credentials, dependency reachability, and whether the task exceeds its available resources.
See App lifecycle for suspend/resume and Secrets for database and API credentials.
For an explicitly requested standalone command rather than a recurring schedule, see one-off jobs and their execution-environment limits.