Introduction
Zilean is a self-hosted scheduled job runner. It keeps the definition of every job — its schedule, its retry backoff, its success-path looping, its parallelism — in a Postgres table, and it applies changes to that table on the job’s very next run.
It is a Go application built on the River job queue, with an embedded admin UI and an embedded copy of River UI behind a single login.
The core promise
Section titled “The core promise”Every behavior change is a row write, never a code or deploy change.
Editing a job’s row takes effect on the next scheduled run or the next job attempt. No redeploy. No editing crontab files on a host. No re-uploading a DAG or workflow YAML and waiting for a scheduler to pick it up.
That is the one thing Zilean is built to do well, and it is the reason to reach for it over the neighboring tools:
| How a change is made | |
|---|---|
| cron | Edit a crontab file on the host; needs shell access, and the job definition lives wherever the host is. |
| Zapier / n8n | Edit in a hosted UI you don’t run, with your credentials and payloads on someone else’s infrastructure. |
| Airflow | Change Python, re-upload the DAG, wait for the DAG processor to reparse it. |
| Obsidian Scheduler | A web UI or its API, no redeploy needed — the same category as Zilean here. It’s a self-hosted JVM process, though, with the heavier baseline footprint that implies; see Deploying to AWS for a sizing comparison. |
| Zilean | Write a Postgres row (via the admin UI or the JSON API). Effective on the next run. |
Zilean is also deliberately lightweight: eight small Go binaries with no JVM or other managed runtime underneath them, sized to run comfortably on a single small instance rather than a cluster. See Deploying to AWS for concrete sizing.
Who it’s for
Section titled “Who it’s for”A small group of people who trust each other and their network, managing their own scheduled jobs on their own infrastructure. Zilean has real users, roles and permissions — it is not single-user — but its design assumptions are “a handful of trusted operators,” not anonymous public internet users.
Concretely, that shapes two things you should know up front:
- Global variables and script bodies are stored as plaintext. A job’s
auth_configsecret (bearer token, basic auth password, API key) is encrypted at rest, but global variable values and script job bodies are not — anything that can read the database can read those. - Script jobs have limited sandboxing. Bash, Node/TypeScript, and Groovy script jobs
can all run confined in a
bwrap(bubblewrap) sandbox with no access to the broader container filesystem, once you opt in. See Script jobs for the full security posture and deployment checklist.
What a job is
Section titled “What a job is”A job is one row in the registry, and it is one of two kinds:
- An HTTP job calls a URL on a schedule.
- A script job runs a Bash, JavaScript/TypeScript, or Groovy script on a schedule, each runtime in its own isolated worker.
Both kinds share the same scheduling, looping, retry and pooling machinery. See Job types.
Three mechanisms, deliberately kept separate
Section titled “Three mechanisms, deliberately kept separate”Most schedulers give you one general-purpose “retry policy.” Zilean gives you three independent per-job mechanisms, and never merges them into one control:
- Loop re-calls a job along its success path, until a value in the response says to stop. This is how you drain a queue or paginate a backlog in one firing.
- Retry re-calls a job along its error path, with exponential backoff.
- Pooling fans a single firing out into N parallel calls, each looping and retrying independently.
A job can loop without retrying, retry without looping, do both, or do either across a pool. See Loop, retry & pooling.
Visibility over automation
Section titled “Visibility over automation”Zilean surfaces what is happening rather than hiding execution behind an abstraction. Every attempt is recorded, every job has an activity chart and a heartbeat, worker processes report their own CPU and memory, and the embedded River UI exposes the raw queue internals — the actual job rows, states, attempts and errors.
Next steps
Section titled “Next steps”- Installation — get a Zilean instance running.
- Configuration — the environment variables it reads.
- Your first job — register a job and watch it run.
- Architecture — how the services fit together.
Docs for AI tools
Section titled “Docs for AI tools”These docs are also published in the llms.txt format, so you can hand them to an LLM or coding agent:
llms.txt: an index of the documentation sets.llms-full.txt: the complete documentation in one file.llms-small.txt: a trimmed version for smaller context windows.