Cron expression for every 30 seconds
Standard cron cannot run every 30 seconds. The Unix cron syntax — used by Linux crontab, Kubernetes CronJob, GitHub Actions and AWS EventBridge — has only minute-level resolution. The minimum granularity is * * * * * (every minute). For sub-minute schedules you need a different tool: Quartz cron (which has a seconds field), KEDA, a sleep-loop wrapper, or an event-driven trigger.
Why is there no cron expression for “every 30 seconds”?
Cron was designed in 1975 for batch jobs running minutes or hours apart. The original Vixie cron format used 5 fields starting at minute — there was no seconds field. Every cron flavor descended from Vixie inherited that limitation: Linux crontab, anacron, fcron, Kubernetes CronJob, GitHub Actions, AWS EventBridge.
Some newer schedulers add a seconds field. Quartz (used in Java enterprise apps) uses 7 fields: seconds, minutes, hours, day-of-month, month, day-of-week, year. So in Quartz, */30 * * * * ? * does run every 30 seconds. AWS does not use Quartz — EventBridge cron is 6-field, no seconds, despite some confusion in older AWS docs.
For sub-minute schedules in mainstream cron, the answer is “use a different tool”.
What’s the actual minimum cron interval?
| Scheduler | Minimum cron interval |
|---|---|
| Linux crontab | 1 minute (* * * * *) |
| Kubernetes CronJob | 1 minute |
| AWS EventBridge | 1 minute |
| GitHub Actions | 5 minutes (enforced — anything shorter is silently coalesced) |
| Quartz | 1 second (full seconds field) |
AWS EventBridge rate() | 1 minute |
Cron-style 1-minute is fine for most batch jobs. Sub-minute is unusual and usually a sign of the wrong abstraction.
Workarounds when you really need sub-minute
Option 1: Run a long-lived process with setInterval / sleep loop
Easiest workaround. Run a single container that loops internally:
#!/bin/bash
# every 30s loop
while true; do
/usr/local/bin/check-something
sleep 30
done
Wrap in a Kubernetes Deployment (not CronJob) so it stays alive. The pod does the timing instead of the scheduler.
apiVersion: apps/v1
kind: Deployment
metadata:
name: check-loop
spec:
replicas: 1
selector:
matchLabels: { app: check-loop }
template:
metadata:
labels: { app: check-loop }
spec:
containers:
- name: check
image: my-org/check-loop:1.0
command: ["/bin/bash", "-c", "while true; do /usr/local/bin/check-something; sleep 30; done"]
Option 2: KEDA cron scaler (Kubernetes)
KEDA supports cron-based scaling but is primarily for scaling Deployments up at certain times — not for triggering jobs. For sub-minute triggers, KEDA isn’t the right tool either.
Option 3: AWS Step Functions Express workflow
Build a Step Functions state machine with a Wait state for 30 seconds and a self-loop. Step Functions Express is billed per state transition and can sustain sub-minute loops.
Option 4: Quartz inside a Java app
If you’re already in a Java/Spring runtime, Quartz’s full 7-field cron supports */30 * * * * ? * natively. This is the cleanest option for Java apps.
Option 5: Reconsider the requirement
The most common sub-minute use case (“check this status every 30 seconds”) is usually better solved by:
- Webhooks — let the upstream system notify you when state changes
- Long polling — open a connection that returns when there’s something new
- Pub/sub — subscribe to events instead of polling
If you’re polling at 30-second intervals to detect state changes that happen rarely, you’re paying for ~2,880 wasted requests per day per subscriber.
What about AWS EventBridge rate() expressions?
rate(30 seconds) is NOT supported. EventBridge rate() minimum is rate(1 minute). Same for Scheduler. For sub-minute on AWS, you’re outside EventBridge’s scope — Step Functions or a long-running ECS task.
For schedules cron CAN do see common cron schedules, or build any standard expression with the Cron Expression Builder.
Frequently asked questions
- Why does Linux cron not support seconds?
- Historical reason. Cron was designed in 1975 for batch jobs that ran minutes or hours apart, on systems where the minute-level polling cost was already significant. The 5-field format became a Unix standard and stuck. Linux/macOS Vixie cron, anacron, fcron — none have a seconds field. Newer schedulers built for distributed systems (Quartz, AWS Step Functions) added seconds because the use cases caught up.
- What about Quartz — doesn''t it support seconds?
- Yes. Quartz uses 7 fields: seconds, minutes, hours, day-of-month, month, day-of-week, year. `*/30 * * * * ? *` in Quartz runs every 30 seconds. AWS EventBridge does NOT use Quartz syntax — it's 6-field with no seconds. Quartz is mainly used inside Java apps (Spring, Java enterprise schedulers).
- What''s the right tool for "every 30 seconds" in cloud environments?
- Depends on the runtime. In Kubernetes — KEDA's cron-trigger scaler can scale a Deployment based on time, but for "every 30 seconds" you're better off with a long-running pod that runs `setInterval` or a sleep loop. In AWS — use `rate(30 seconds)` (NOT cron) on EventBridge Scheduler, or run a Step Functions Express workflow on a 30s loop. In serverless — frequencies under 1 minute usually mean you should be event-driven, not time-driven.
Need a different schedule?
Build cron expressions for Unix, Kubernetes and AWS — with a human-readable description and the next 5 run times.
Open the Cron Expression Builder →Related
Cron expression for every 5 minutes
The cron expression `*/5 * * * *` runs every 5 minutes in Linux crontab, Kubernetes, GitHub Actions; `cron(*/5 * * * ? *)` in AWS EventBridge.
Cron expression for every 15 minutes
The cron expression `*/15 * * * *` runs every 15 minutes — at :00, :15, :30, :45 — across Linux, Kubernetes, GitHub Actions and AWS.
Cron expression for every hour
The cron expression `0 * * * *` runs once per hour on the hour. Same syntax in Linux, Kubernetes and GitHub Actions; `cron(0 * * * ? *)` in AWS EventBridge.
Cron expression for daily at midnight
The cron expression `0 0 * * *` runs once daily at midnight. Watch the timezone — Kubernetes < 1.25 and AWS EventBridge default to UTC, not local time.
Cron expression for every weekday
The cron expression `0 9 * * 1-5` runs at 9 AM Monday through Friday. AWS uses `cron(0 9 ? * MON-FRI *)` because day-of-week numbering differs.
Cron expression for the first of every month
The cron expression `0 0 1 * *` runs at midnight on the 1st of every month. AWS uses `cron(0 0 1 * ? *)`.