- Posted on
- • Artificial Intelligence
Scheduling Local Artificial Intelligence Jobs with Cron
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
Scheduling Local Artificial Intelligence Jobs with Cron (Linux)
Ever watched your GPU sit idle at 2 a.m. while datasets pile up and models wait to be retrained? If you’re running AI workloads on your own hardware, cron can be the quiet, reliable teammate that keeps your pipelines humming—even when you’re asleep. In this guide, you’ll learn how to schedule local AI jobs with cron the right way: reproducibly, safely, and with good Linux hygiene.
Problem: Manual runs are brittle, easy to forget, and waste off-peak compute time.
Value: Cron-based scheduling gives you consistent, auditable runs; better resource utilization; and privacy-friendly automation right on your own machine.
Why schedule local AI jobs with cron?
Maximize idle resources: Nighttime/off-hours are perfect for training, batch inference, and data prep.
Keep data private: No need to upload sensitive data to cloud jobs.
Cost control: Use hardware you already own—no surprise bills.
Reproducibility: Cron runs scripts the same way every time; logs tell you when/what happened.
Prerequisites: Install and enable cron
Cron runs as a system service. Install and enable it for your distro:
Debian/Ubuntu (service name: cron)
sudo apt update sudo apt install cron sudo systemctl enable --now cronFedora/RHEL/CentOS (service name: crond)
sudo dnf install cronie sudo systemctl enable --now crondopenSUSE Leap/Tumbleweed (service name: cron)
sudo zypper refresh sudo zypper install cronie sudo systemctl enable --now cron
Verify it’s running:
systemctl status cron # Debian/Ubuntu/openSUSE
systemctl status crond # Fedora/RHEL/CentOS
Optional: Laptops/offline machines benefit from anacron (runs missed jobs when the system is back on).
Debian/Ubuntu:
sudo apt install anacronFedora/RHEL/CentOS:
sudo dnf install cronie-anacronopenSUSE:
sudo zypper install anacron
Step 1: Prepare a reliable AI environment
Use a Python virtual environment for repeatability. Install Python and pip:
Debian/Ubuntu:
sudo apt update sudo apt install -y python3 python3-venv python3-pipFedora/RHEL/CentOS:
sudo dnf install -y python3 python3-pipopenSUSE:
sudo zypper install -y python3 python3-pip
Create a project layout:
mkdir -p $HOME/ai-jobs/{bin,logs,work}
python3 -m venv $HOME/.venvs/ai
$HOME/.venvs/ai/bin/pip install --upgrade pip
$HOME/.venvs/ai/bin/pip install transformers sentence-transformers
Example AI job (simple batch task using Transformers). Save as:
$HOME/ai-jobs/bin/ai_job.py
#!/usr/bin/env python3
import os, datetime, pathlib
from transformers import pipeline
outdir = pathlib.Path(os.environ.get("AI_OUTDIR", str(pathlib.Path.home() / "ai-jobs" / "work")))
outdir.mkdir(parents=True, exist_ok=True)
clf = pipeline("sentiment-analysis")
texts = [
"This release is fantastic!",
"The training run failed unexpectedly.",
"The new dataset looks promising."
]
results = clf(texts)
ts = datetime.datetime.utcnow().isoformat()
with open(outdir / f"sentiment_{ts}.txt", "w") as f:
for t, r in zip(texts, results):
f.write(f"{t}\t{r}\n")
print(f"[{ts}] Wrote results to {outdir}")
Make it executable:
chmod +x $HOME/ai-jobs/bin/ai_job.py
Step 2: Wrap your job for cron (env, logging, locks, ethics to your fans)
Cron doesn’t load your shell profile and has a minimal PATH. Use a wrapper that:
Activates the venv
Sets cache directories (avoid re-downloading models each run)
Prevents overlapping runs (flock)
Nice/ionice to be a good neighbor
Optionally runs only when the GPU is idle
Save as $HOME/ai-jobs/bin/run_inference.sh:
#!/usr/bin/env bash
set -euo pipefail
JOB_NAME="nightly_inference"
BASE_DIR="$HOME/ai-jobs"
VENV="$HOME/.venvs/ai"
LOG_DIR="$BASE_DIR/logs"
WORK_DIR="$BASE_DIR/work"
LOCK_FILE="/tmp/${JOB_NAME}.lock"
mkdir -p "$LOG_DIR" "$WORK_DIR"
# Log file with UTC timestamp
STAMP="$(date -u +'%Y%m%dT%H%M%SZ')"
LOG_FILE="$LOG_DIR/${JOB_NAME}_${STAMP}.log"
# Redirect stdout/stderr to log
exec > >(tee -a "$LOG_FILE") 2>&1
echo "[$(date -u +'%F %T')] Starting $JOB_NAME..."
# Ensure predictable environment for cron
export SHELL=/bin/bash
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$HOME/.local/bin"
export HF_HOME="$HOME/.cache/huggingface"
export TRANSFORMERS_CACHE="$HF_HOME/transformers"
export AI_OUTDIR="$WORK_DIR"
# Optional: be nice to other workloads
IONICE_CLASS=${IONICE_CLASS:-2} # best-effort
IONICE_PRIO=${IONICE_PRIO:-7} # lowest priority
NICENESS=${NICENESS:-10}
# Optional: run only if GPU is sufficiently idle (skip if no NVIDIA GPU)
GPU_MAX_USED_MB=${GPU_MAX_USED_MB:-400} # lower = stricter
if command -v nvidia-smi >/dev/null 2>&1; then
USED=$(nvidia-smi --query-gpu=memory.used --format=csv,noheader,nounits | head -n1 || echo 999999)
if [ "${USED:-999999}" -gt "$GPU_MAX_USED_MB" ]; then
echo "GPU busy (${USED}MB used > ${GPU_MAX_USED_MB}MB). Skipping."
exit 0
fi
fi
# Prevent overlapping runs
flock -n "$LOCK_FILE" bash -c "
set -euo pipefail
source \"$VENV/bin/activate\"
ionice -c $IONICE_CLASS -n $IONICE_PRIO nice -n $NICENESS \
python \"$BASE_DIR/bin/ai_job.py\"
"
echo "[$(date -u +'%F %T')] Finished $JOB_NAME."
Make it executable:
chmod +x $HOME/ai-jobs/bin/run_inference.sh
Step 3: Add the cron schedule
Edit your user crontab:
crontab -e
At the top, set a sane environment (cron’s default PATH is small):
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$HOME/.local/bin
MAILTO=you@example.com
Examples:
Run nightly at 02:05 UTC:
5 2 * * * /home/youruser/ai-jobs/bin/run_inference.shEvery 15 minutes (will self-skip if GPU busy):
*/15 * * * * /home/youruser/ai-jobs/bin/run_inference.shUse special strings:
@daily /home/youruser/ai-jobs/bin/run_inference.sh @weekly /home/youruser/ai-jobs/bin/run_inference.sh
Tips:
Always use absolute paths in cron.
If you need variables, set them in the crontab or inside your wrapper.
For system-wide jobs, consider root’s crontab (
sudo crontab -e) or drop scripts into/etc/cron.{hourly,daily,weekly}using run-parts naming rules.
Step 4: Monitor and troubleshoot
Read logs you wrote:
ls -1 $HOME/ai-jobs/logs tail -n 200 -f $HOME/ai-jobs/logs/nightly_inference_*.logCheck cron service:
systemctl status cron # Debian/Ubuntu/openSUSE systemctl status crond # Fedora/RHEL/CentOSCron’s own logs:
- systemd journal:
journalctl -u cronorjournalctl -u crond - Some distros also log to
/var/log/cronor/var/log/syslog
- systemd journal:
Confirm your entries:
crontab -lGet email on failures by setting
MAILTOin crontab and ensuring local MTA or use a sendmail wrapper.
Real-world patterns you can copy
1) Nightly document embeddings
Pull new files from a folder, generate embeddings with Sentence-Transformers, push to a vector DB (e.g., SQLite/FAISS).
Schedule:
5 1 * * *to hit off-hours.
2) Weekly quantization/pruning
Quantize a model (e.g., 4-bit) to free VRAM for the week.
Heavy CPU/GPU usage—schedule
@weeklyon weekends; addnice/ioniceto behave well.
3) Rolling batch inference
Every 15 minutes, process the last N items in a queue and write outputs atomically.
Use
flockto avoid overlaps and a GPU-idle check to yield to interactive sessions.
4) Data hygiene + retrain
Nightly: clean mislabeled rows, recompute stats, kick off a quick fine-tune if there’s enough new data.
Chain jobs with lockfiles so retrain only runs if preprocessing succeeded (e.g., have the first job drop a “success” marker file).
Common pitfalls (and fixes)
My job runs manually but fails in cron
- Use absolute paths, don’t rely on
~or implicit PATH. - Export needed env vars in the wrapper.
- Activate venv explicitly with
source /path/to/venv/bin/activate.
- Use absolute paths, don’t rely on
First run is slow due to model downloads
- Set
HF_HOME/TRANSFORMERS_CACHEto a persistent path; let the first run warm the cache.
- Set
Jobs overlap and fight for resources
- Wrap invocation with
flock -n /tmp/job.lock -c "...".
- Wrap invocation with
Cron missed runs on a laptop
- Install anacron to catch up after suspend/offline periods.
Conclusion and next step
Cron can be your local MLOps engine: predictable, low-friction, and perfect for squeezing value out of your own hardware. Start with one job—like nightly inference—then grow into a small suite of reliable tasks.
Call to action:
Install and enable cron (see commands above).
Create the venv and wrapper script.
Add a simple nightly job with
crontab -e.Watch the logs tomorrow morning and iterate.
When you’re ready, extend with:
Multiple jobs with dependency markers
GPU-aware scheduling heuristics
Separate users or containers for stronger isolation
Happy automating!