GitHub Actions vs cron — when to pick which in 2026
GitHub Actions are great for CI/CD and public repos, local cron for anything touching your infrastructure. Showing the rule and concrete cases.

GitHub Actions is the standard for CI/CD. Cron has worked for 50 years. After years of using both I have a clear rule for picking which. Showing concretes from my setup, some things in GHA, some in cron, each with a specific reason.
Quick rule
GHA when: build/test of public artifact, public repo, you want auditable logs, you want visibility.
Cron when: it touches local infra, secrets, private data, you want < 1s startup.
What I have in GitHub Actions
1. Build + test portfolio on every PR
# .github/workflows/ci.yml
name: CI
on: [pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm run build
- run: npm testStandard. Time: ~3 min. Visible on the PR as a check. Worth it because every PR sees the result.
2. Auto-deploy demo to staging on push to staging branch
on:
push:
branches: [staging]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: |
ssh kkaletka@$STAGING_HOST "cd /home/kkaletka/portfolio-staging && \
git pull && docker compose up -d --build"GHA fires SSH to my mini PC. I have an SSH key registered with GHA secrets. Every push to staging = rebuild in 30 seconds.
3. Weekly dependency audit for an open-source repo
.github/workflows/audit.yml with cron: '0 0 * * 0' (Sunday 00:00 UTC). npm audit --json → output to a GitHub issue if HIGH/CRITICAL.
Public visibility. Other contributors see it.
What I have in cron (mini PC)
1. Blog publisher (daily 9:00)
0 9 * * * /home/kkaletka/kamilkaletka-portfolio/scripts/publish-due-drafts.shThis script rebuilds the portfolio Docker container. Requires local access to docker compose. GHA wouldn't work here (no access to my Docker daemon).
2. Backup status (hourly)
0 * * * * /home/kkaletka/docker/scripts/backup-check.shChecks Proxmox snapshot age. Local path, local Telegram token. GHA has 1-min minimum granularity and a cost, overkill.
3. AEGIS audit (every 5 minutes)
*/5 * * * * /home/kkaletka/docker/scripts/aegis-watch.shNetwork watchdog. Checks if the Cloudflare tunnel is alive, containers respond, DNS works. GHA would cost $$$ at 12 runs per hour.
4. claudeclaw morning briefing (8:00)
Cron in ~/.openclaw/cron/jobs.json. Fires the Claude Code agent with a prompt. Agent has access to my MCP, hosts, secrets. GHA doesn't.
Decision rule via questions
Six questions I ask myself:
1. Does the operation touch local infra (Docker, Proxmox, secrets)?
- Yes → cron
- No → continue
2. Is this a public repo where I want a visibility check?
- Yes → GHA
- No → continue
3. Do I need cadence faster than once per minute?
- Yes → cron (GHA min granularity = 1 min, real lag ~30s)
- No → continue
4. Does the run take > 30 minutes?
- Yes → cron (GHA free has 6h cap, paid is billed minutes)
- No → continue
5. Should the result be auditable by the team/others?
- Yes → GHA (logs, runs, badges)
- No → cron
6. Do I need a commit-based trigger?
- Yes → GHA (push/PR triggers natively)
- No → cron
In practice most of my automation answers "local infra" on question 1, goes to cron. Public CI/CD lands in GHA.
Hybrid pattern
Sometimes I want GHA as a trigger + cron as a worker:
[Push to main on GitHub]
↓
[GHA workflow: send webhook to mini PC]
↓
[mini PC: receive, fire local script]
↓
[Local Docker rebuild]The webhook listener is ~30 lines of Python with aiohttp. Gives me GHA visibility + local infra access.
Anti-patterns
1. Self-hosted GHA runner on the mini PC. Gave me "locality with GHA UI", but in practice: GHA agent updates keep interrupting, the runner is less stable than cron, and you still have to maintain infra.
2. Cron with 30+ entries. Hard to maintain. With 30+, switch to systemd timers. More declarative, better logs.
3. GHA for heavy ML/data work. Free tier has a 6h limit + paid mode is expensive on GPU runners. Better your own VM.
My split
Currently:
- GHA: 4 workflows (CI, staging deploy, audit, release)
- crontab: 11 entries
- claudeclaw cron: 7 jobs (most disabled due to OAuth issues)
- systemd timers: 2
GHA is the minority by count, but handles 100% of public-facing workflows. Cron is the majority, handles 100% of private infra.
Picking GHA vs cron isn't a fashion question. It's about where the work lives and who needs to see the result. The six-question rule cuts the decision to 30 seconds. The hybrid pattern (GHA webhook → local) gives you the best of both worlds.