Architecture
Husky is intentionally compact. One binary owns the scheduler, executor, local API, dashboard, and state store.
High-level design
husky.yaml + huskyd.yaml
│
▼
husky daemon
│
┌────────┼────────┬───────────────┬───────────────┐
▼ ▼ ▼ ▼ ▼
DAG scheduler executor SQLite HTTP/WebSocket
build loop pool state API + dashboard
Main runtime pieces
CLI
The husky CLI starts and controls the daemon, validates config, and exposes operator commands such as:
startstopreloadstatusrunlogshistoryauditdag
Most commands talk to the daemon through a local socket.
Daemon
The daemon is the long-running process that:
- loads config
- computes schedules
- dispatches jobs
- tracks retries
- runs healthchecks
- persists state
- serves the dashboard and API
It can run in the background with husky start or foreground with husky daemon run.
Config loaders
Husky separates workflow definition from daemon runtime settings:
husky.yamldefines jobshuskyd.yamldefines API, auth, TLS, logging, storage, limits, and runtime behavior
Both are validated before use.
Scheduler
The scheduler resolves wall-clock schedules using per-job timezone settings. It handles:
- default run times
- interval schedules
- day-list schedules
- DST gaps and overlaps
- catchup after restart
DAG engine
Dependency edges come from both depends_on and after:<job>. Husky topologically sorts the graph and rejects cycles before startup or reload completes.
Executor
Jobs run as subprocesses. Husky captures stdout and stderr in real time, enforces timeouts, and kills process groups when required.
Execution logic also handles:
- retries with backoff and jitter
- concurrency policies
- output capture
- downstream template rendering
- post-run healthchecks
State store
Husky persists local runtime state in SQLite using WAL mode. Important tables include:
job_runsjob_staterun_logsrun_outputsalerts
This gives the dashboard and CLI a durable source of truth without external services.
API and dashboard
The daemon serves:
- REST endpoints under
/api/* - live log streaming under
/ws/logs/* - an embedded dashboard at
/
The dashboard is compiled from the web/ app and embedded into the binary.
Request and execution flow
Scheduled run
- Scheduler computes a due job.
- DAG rules and job state are checked.
- A run row is created.
- The executor launches the subprocess.
- Logs stream into SQLite and WebSocket clients.
- Output variables are captured.
- Healthcheck runs if configured.
- Alerts and downstream triggers are evaluated.
job_stateis updated.
Manual run
A manual trigger follows the same execution path, but the run is recorded with trigger=manual and may carry a reason string.
Data directories
By default Husky stores runtime state under .husky/.
Common files:
husky.sockhusky.pidhusky.dbapi.addrhuskyd.log
These are generated artifacts and should not be committed.
Platform model
Husky is built for Linux, macOS, and Windows. Process handling, sockets, signal behavior, and detach logic use platform-specific code where needed, but the workflow model stays the same.
Design boundaries
Husky is local-first. It does not require:
- a separate control plane
- a message broker
- an external database
- a Kubernetes deployment
That constraint keeps the product simple and makes the repository the center of workflow ownership.