Skip to main content
Tools Harbor

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?

SchedulerMinimum cron interval
Linux crontab1 minute (* * * * *)
Kubernetes CronJob1 minute
AWS EventBridge1 minute
GitHub Actions5 minutes (enforced — anything shorter is silently coalesced)
Quartz1 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