Blog
ENPL

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.

·4 min read
GitHub Actions vs cron — when to pick which in 2026

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 test

Standard. 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.sh

This 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.sh

Checks 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.sh

Network 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.