What is a Job and CronJob in Kubernetes? Explained Simply (2026)
Deployments run forever. Jobs run once and stop. CronJobs run on a schedule. Here's how both work, when to use them, and simple examples to get started.
Not every workload runs forever. Database migrations, report generation, data processing — these need to run once (or on a schedule) and stop. That's what Job and CronJob are for.
The Problem They Solve
A Deployment keeps pods running forever — if the pod exits, it restarts.
# Deployment — restarts on exit (always running)
kind: Deployment
spec:
template:
spec:
containers:
- name: app
image: nginx
restartPolicy: Always # defaultFor a database migration, you don't want "always running." You want "run once, succeed, then stop." That's a Job.
What Is a Job?
A Job creates one or more pods, waits for them to complete successfully, then marks itself as Done.
apiVersion: batch/v1
kind: Job
metadata:
name: db-migration
spec:
template:
spec:
restartPolicy: Never # ← required for Jobs (not Always)
containers:
- name: migrate
image: my-app:v2.0
command: ["python", "manage.py", "migrate"]kubectl apply -f job.yaml
# Watch the job
kubectl get jobs
# NAME COMPLETIONS DURATION AGE
# db-migration 1/1 8s 15s ← 1/1 = done!
# Check the pod it created
kubectl get pods --selector=job-name=db-migration
# NAME STATUS
# db-migration-abc12 Completed ← pod stays for log inspection
# View logs
kubectl logs job/db-migrationJob Life Cycle
Job created
↓
Pod starts running
↓
Pod exits with code 0 (success)?
├── Yes → Job = Completed ✅
└── No → Retry (up to backoffLimit times)
↓
All retries failed → Job = Failed ❌
Key Job Fields
spec:
completions: 1 # how many pods must succeed (default: 1)
parallelism: 1 # how many pods run at once (default: 1)
backoffLimit: 3 # retry count on failure (default: 6)
activeDeadlineSeconds: 300 # kill job after 5 min regardless
ttlSecondsAfterFinished: 3600 # auto-delete pods 1hr after completionRun 10 tasks in parallel
spec:
completions: 10 # need 10 successful completions
parallelism: 3 # run 3 at a timeRound 1: pods 1, 2, 3 run simultaneously
Round 2: pods 4, 5, 6
Round 3: pods 7, 8, 9
Round 4: pod 10
→ Job complete when 10/10 succeed
Common Job Use Cases
| Use Case | Example |
|---|---|
| Database migration | python manage.py migrate |
| Sending bulk emails | python send_newsletter.py |
| Data processing | python process_csv.py |
| One-time setup | kubectl exec alternative |
| ML training run | Train a model on a dataset |
| Report generation | Generate and upload PDF report |
What Is a CronJob?
A CronJob creates Jobs on a schedule — like Linux cron, but for Kubernetes.
apiVersion: batch/v1
kind: CronJob
metadata:
name: nightly-backup
spec:
schedule: "0 2 * * *" # 2 AM every day
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: backup
image: my-backup:latest
command: ["sh", "-c", "pg_dump $DATABASE_URL | gzip | aws s3 cp - s3://backups/$(date +%Y%m%d).sql.gz"]kubectl apply -f cronjob.yaml
# Check CronJob
kubectl get cronjobs
# NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE
# nightly-backup 0 2 * * * False 0 14h
# See jobs it created
kubectl get jobs --selector=cronjob=nightly-backupCron Schedule Syntax
┌─── minute (0-59)
│ ┌── hour (0-23)
│ │ ┌─ day of month (1-31)
│ │ │ ┌ month (1-12)
│ │ │ │ ┌ day of week (0-7, 0=Sunday)
│ │ │ │ │
* * * * *
Examples:
"*/5 * * * *" → every 5 minutes
"0 * * * *" → every hour
"0 9 * * 1-5" → 9 AM on weekdays
"0 0 1 * *" → midnight on 1st of every month
"30 3 * * *" → 3:30 AM daily (UTC)
Set timezone (Kubernetes 1.27+):
spec:
schedule: "0 9 * * *"
timeZone: "Asia/Kolkata" # 9 AM ISTCronJob Key Fields
spec:
schedule: "*/10 * * * *"
timeZone: "Asia/Kolkata"
concurrencyPolicy: Forbid # don't start new job if one is running
successfulJobsHistoryLimit: 3 # keep last 3 successful jobs
failedJobsHistoryLimit: 3 # keep last 3 failed jobs
startingDeadlineSeconds: 60 # skip if more than 60s late
suspend: false # pause CronJob without deletingconcurrencyPolicy options:
Allow— run multiple jobs at once (default)Forbid— skip new run if one is still runningReplace— kill current job, start new one
Job vs CronJob vs Deployment
| Deployment | Job | CronJob | |
|---|---|---|---|
| Runs | Forever | Once | On schedule |
| Restart on exit | Always | Never/OnFailure | Never/OnFailure |
| Use for | Web apps, APIs | Migrations, one-time tasks | Backups, reports, cleanup |
| Completes | Never | When pods succeed | Each scheduled run |
Useful Commands
# Create a one-off job quickly (no YAML needed)
kubectl create job hello --image=busybox -- echo "Hello World"
# Manually trigger a CronJob right now (for testing)
kubectl create job --from=cronjob/nightly-backup manual-test
# Pause a CronJob
kubectl patch cronjob nightly-backup -p '{"spec":{"suspend":true}}'
# Resume
kubectl patch cronjob nightly-backup -p '{"spec":{"suspend":false}}'
# Delete a job and its pods
kubectl delete job db-migration
# Delete completed jobs
kubectl delete jobs --field-selector status.successful=1Complete Example: Weekly Report
apiVersion: batch/v1
kind: CronJob
metadata:
name: weekly-report
namespace: production
spec:
schedule: "0 8 * * 1" # 8 AM every Monday
timeZone: "Asia/Kolkata"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 4 # keep 1 month of history
failedJobsHistoryLimit: 4
jobTemplate:
spec:
backoffLimit: 2
activeDeadlineSeconds: 1800 # fail after 30 min
ttlSecondsAfterFinished: 604800 # auto-delete after 1 week
template:
spec:
restartPolicy: OnFailure
containers:
- name: reporter
image: my-reporter:latest
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: app-secrets
key: DATABASE_URL
- name: SLACK_WEBHOOK
valueFrom:
secretKeyRef:
name: app-secrets
key: SLACK_WEBHOOK
resources:
requests:
cpu: "200m"
memory: "256Mi"Learn More
- KodeKloud Kubernetes for Beginners — Job and CronJob labs
- CKA Exam on Udemy — Jobs covered in CKA
- devopsboys.com/interview-prep — Kubernetes interview questions
Stay ahead of the curve
Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.
Related Articles
Build a Kubernetes Cluster with kubeadm from Scratch (2026)
Step-by-step guide to building a real multi-node Kubernetes cluster using kubeadm — no managed services, no shortcuts.
How to Build a DevOps Home Lab for Free in 2026
You don't need expensive hardware to practice DevOps. Here's how to build a complete home lab with Kubernetes, CI/CD, and monitoring using free tools and cloud free tiers.
How to Migrate from Ingress-NGINX to Kubernetes Gateway API in 2026
Step-by-step guide to migrating from Ingress-NGINX to Kubernetes Gateway API. Includes YAML examples, implementation choices, testing strategy, and cutover plan.