Cookbook
Practical recipes. All examples assume downctl is on your PATH.
Mirror model downloads
downctl get hf://meta-llama/Llama-3-8B \
--include '*.safetensors' --exclude '*.gguf' \
-d ~/models/llama3 -j 4
Only the weights are fetched, four files at a time. Set
[plugins.huggingface] mirror = "https://hf-mirror.com" to route through a
mirror, and token (or HF_TOKEN) for gated repositories.
Verify a download end to end
# one file
downctl get https://example.com/model.bin --checksum sha256:<hex>
# a whole release, against the project's SHA256SUMS
downctl get gh://owner/repo --checksums SHA256SUMS
A mismatch re-downloads (up to twice) before failing, and the file is recorded
in .downctl.failed for --retry-failed.
Resume a huge download across sessions
Nothing special to do — re-run the same command:
downctl get https://example.com/huge.iso -d /data
# Ctrl+C, machine reboot, whatever...
downctl get https://example.com/huge.iso -d /data # resumes, only missing pieces
Tune the connection count freely; changing --connections reslices the
bitmap rather than restarting:
downctl get https://example.com/huge.iso --connections 4 # keeps progress
Nightly mirror of an S3 prefix
#!/usr/bin/env bash
set -euo pipefail
export AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=...
downctl get s3://bucket/datasets/ \
--include '*.parquet' \
-d /srv/datasets \
--skip-existing \
--retries 5
--skip-existing makes the run cheap when little changed.
Fetch a private GitHub release asset
export GITHUB_TOKEN=ghp_xxx
downctl get gh://my-org/private-app --include '*.tar.gz' -d /opt/app
With a token, assets are fetched through the GitHub API so credentials stay on the API host.
Verify after the fact with a sidecar
# download + write <file>.sha256 sidecars
cat > ~/.config/downctl/config.toml <<'EOF'
[core]
hooks = ["checksum"]
EOF
downctl get https://example.com/a.bin https://example.com/b.bin -d data
# later, re-verify a fresh copy against the sidecars
downctl get https://example.com/a.bin -d data2 --checksums data/a.bin.sha256
Auto-extract archives
cat > ~/.config/downctl/config.toml <<'EOF'
[core]
hooks = ["archive"]
[plugins.archive]
keep = false
EOF
downctl get https://example.com/release.tar.gz
Extraction is hardened against path traversal and refuses links/devices.
Notify when a batch finishes
[core]
hooks = ["exec"]
[plugins.exec]
command = "notify-send 'downctl' \"$DOWNCTL_TARGET done\""
events = ["on_task_finish"]
See hooks.md for the full event/variable list.
Batch from stdin
printf '%s\n' \
https://example.com/a.bin \
https://example.com/b.bin | downctl get -l - -d ~/Downloads
CI: cache a model, tolerate a flaky host
downctl get hf://org/model -d "$CACHE" \
--skip-existing --retries 8 --stall 60 -j 2
Diagnose a slow or stuck download
downctl -v get <url> # resolved tasks, mirror rewrites, resume bytes
downctl doctor # proxy / WSL / deps / plugins
downctl status <dir> # what is incomplete or failed
If a host keeps stalling, lower --stall. If it is slow to warm up, raise it
and lower --connections.