Every 30 Minutes Cron Expression
Runs on the hour and on the half-hour.
*/30 * * * * in POSIX cron
Expression
*/30 * * * *Try it in the tester →Field Breakdown
How It Works
Step value `*/30` fires at minutes 0 and 30 of every hour — twice per hour, 48 times per day.
Example Run Times
- 12:00:00
- 12:30:00
- 13:00:00
- 13:30:00
- 14:00:00
Frequently Asked Questions
Is `0,30 * * * *` equivalent?
Yes, identical. Use whichever form is clearer for your team.
*/30 * * * * in Quartz / Spring
Twice an hour, on the hour and on the half — 48 runs per day. Despite looking like an open-ended step, */30 in a 0-59 minute field can only ever match minutes 0 and 30.
Quartz / Spring expression
0 */30 * * * ?Try it in the tester →At second 0, every 30 minutes, every hour
Unix / POSIX equivalent: */30 * * * *
Field Breakdown
Using It with Quartz / Spring
Half-hourly is a common compromise for jobs that are too heavy for five-minute polling but too latency-sensitive for hourly batches: sitemap pings, search-index refreshes, and reconciliation sweeps against payment providers. In Quartz, schedule it with CronScheduleBuilder.cronSchedule("0 */30 * * * ?"); in Spring Boot the same string goes straight into the @Scheduled annotation, and Spring 5.3's CronExpression class will validate it at context startup, failing fast on typos.
Quartz-Specific Notes
- →0/30 and */30 are interchangeable here — both anchor at minute 0 and yield only :00 and :30.
- →If the scheduler was down across several slots, the default misfire resolution fires once immediately on restart rather than replaying every missed half hour.
Frequently Asked Questions
Will this run at minute 30 of the hour my app starts, even mid-hour?
It fires at the next :00 or :30 boundary after the trigger is scheduled. An app booted at 14:40 first fires at 15:00 — there is no catch-up for the 14:30 slot it missed before existing.
How do I make it 30-minutely but offset, say :10 and :40?
Use an explicit list in the minute field: 0 10,40 * * * ?. Step syntax always anchors at 0, so */30 can't produce offset pairs.
Does fall-back DST give me a duplicate 01:30 run?
No. Quartz resolves each CronTrigger fire time once, so the repeated wall-clock 01:30 does not trigger a second execution.
*/30 * * * * in AWS EventBridge
The */30 step matches minutes 0 and 30, so this rule fires twice an hour — 48 invocations across a UTC day. Half-hourly is a popular compromise for sync jobs whose source data simply does not change faster.
AWS EventBridge expression
cron(*/30 * * * ? *)Try it in the tester →Every 30 minutes UTC
Unix / POSIX equivalent: */30 * * * *
Field Breakdown
Using It with AWS EventBridge
Drop the expression into the ScheduleExpression of an AWS::Events::Rule in CloudFormation or the --schedule-expression flag of aws events put-rule, then register a target ARN with put-targets. Typical half-hour workloads include Salesforce-to-warehouse syncs, certificate and credential expiry scanners, and Step Functions executions that compact small files written to S3 since the previous run. The on-the-hour and bottom-of-the-hour timing makes run logs easy to eyeball in CloudWatch.
AWS-Specific Notes
- →Only two minute values match — 0 and 30 — so each invocation processes a predictable 30-minute window of data.
- →Because */30 steps from zero, there is no way to get :15 and :45 with a bare step; write cron(15,45 * * * ? *) explicitly instead.
- →The trailing year field accepts values 1970-2199, so this rule will happily keep firing twice an hour until you disable it or 2199 arrives.
Frequently Asked Questions
Does cron(*/30 * * * ? *) mean every 30 minutes or twice per hour?
Both descriptions hold here, but only because 30 divides 60 evenly. The rule literally matches minutes 0 and 30 of each hour, giving exact 30-minute gaps.
My half-hourly Lambda occasionally runs twice in quick succession — why?
EventBridge invokes targets at least once per match. Rare duplicate deliveries are expected behavior, so guard with an idempotency key keyed on the scheduled time in the event payload.
Can I pause this over the weekend?
Restrict the day-of-week field instead of using ?, e.g. cron(*/30 * ? * 2-6 *) runs only Monday through Friday since EventBridge counts Sunday as 1.
*/30 * * * * in GitHub Actions
Two ticks per hour: */30 matches UTC minutes 0 and 30, giving 48 scheduled runs per day. On GitHub Actions this is the classic cadence for jobs that should feel fresh without paying high-frequency costs in queue delay and billed minutes.
GitHub Actions expression
*/30 * * * *Try it in the tester →Every 30 minutes UTC
Unix / POSIX equivalent: */30 * * * *
Field Breakdown
Using It with GitHub Actions
Author it as on: schedule: - cron: "*/30 * * * *" in any workflow under .github/workflows on the default branch. Half-hourly is a sweet spot for dependency-vulnerability sweeps against a private registry, posting CI-health digests to Slack via a webhook step, and reconciling deployment state with what a cloud provider reports. Both fire minutes are round numbers, so if start-time jitter bothers you, 17,47 * * * * delivers the identical interval from calmer slots.
GitHub-Specific Notes
- →Fires at :00 and :30 exactly on the UTC clock — a run delayed to 12:07 does not push the next tick to 12:37; the schedule stays anchored to :00/:30.
- →Both slots are popular round numbers; the :00 run in particular competes with every hourly and daily job on the platform.
- →If the repository is public and sees no activity for 60 days, GitHub suspends this schedule silently — watch for the warning email or the banner in the Actions tab.
Frequently Asked Questions
Is every 30 minutes too frequent for a public repo on the free plan?
Public repositories get free Actions minutes on GitHub-hosted runners, so frequency costs nothing in billing — the real constraints are queue delay and the 60-day inactivity auto-disable.
Why choose 17,47 over */30?
Identical cadence, different slots. Minutes 17 and 47 are far less contested than 0 and 30, so runs start closer to their nominal time. GitHub's own docs recommend avoiding the top of the hour.