Every 20 Minutes Cron Expression
Runs three times per hour: minutes 0, 20, 40.
*/20 * * * * in POSIX cron
Expression
*/20 * * * *Try it in the tester →Field Breakdown
How It Works
Step value `*/20` fires at minutes 0, 20, and 40 of every hour — three runs per hour.
Example Run Times
- 12:00:00
- 12:20:00
- 12:40:00
- 13:00:00
- 13:20:00
Frequently Asked Questions
Is `0,20,40 * * * *` equivalent?
Yes — `*/20` is shorthand for the explicit list `0,20,40` in the minute field.
*/20 * * * * in Quartz / Spring
Three evenly spaced firings per hour — :00, :20, and :40 — for 72 executions a day. Since 20 divides 60, each gap is a clean twenty minutes, including the wrap from :40 to the next hour's :00.
Quartz / Spring expression
0 */20 * * * ?Try it in the tester →At second 0, every 20 minutes, every hour
Unix / POSIX equivalent: */20 * * * *
Field Breakdown
Using It with Quartz / Spring
Twenty minutes suits sources that update a few times an hour: pulling a vendor inventory feed, refreshing a geocoding or rates cache, or sweeping half-finished checkout sessions past their hold window. Spring Boot apps take it via @Scheduled(cron = "0 */20 * * * ?"); a standalone Quartz scheduler builds a CronTrigger from the identical string. With runs only twenty minutes apart, prefer idempotent job bodies over clever catch-up logic — if one slot is lost to a deploy, the next one is never far behind.
Quartz-Specific Notes
- →0 0,20,40 * * * ? is the spelled-out equivalent; the step form and the list compile to the same three minute values.
- →The anchor is movable: 0 5/20 * * * ? fires at :05, :25, and :45 — same cadence, shifted off the congested top-of-hour minute.
- →All 72 daily firings land on second 0 of their minute, so logs from this trigger align exactly with minute-bucketed metrics.
Frequently Asked Questions
Is 0/20 different from */20 in the minute field?
No — both anchor at minute 0 and match 0, 20, and 40. The */N form is shorthand for 0/N whenever the field's minimum is 0.
How do I get :10, :30, :50 instead of :00, :20, :40?
Start the step at 10: 0 10/20 * * * ? yields exactly 10, 30, and 50. Alternatively list them outright: 0 10,30,50 * * * ?.
Three runs an hour — can I drop to two during weekends?
Not in a single cron expression; one trigger has one cadence. Use two triggers — 0 */20 * ? * 2-6 for weekdays and 0 */30 * ? * 1,7 for weekends — pointing at the same job.
*/20 * * * * in AWS EventBridge
Three evenly spaced runs an hour — :00, :20, and :40 — for 72 invocations across a day. Twenty minutes is a common compromise for syncs that must finish well inside their own interval while staying gentle on rate-limited upstream APIs.
AWS EventBridge expression
cron(*/20 * * * ? *)Try it in the tester →Every 20 minutes UTC
Unix / POSIX equivalent: */20 * * * *
Field Breakdown
Using It with AWS EventBridge
You will find 20-minute EventBridge rules feeding incremental ETL (pull rows changed since the last watermark), refreshing OAuth tokens that expire on the hour, regenerating sitemaps or feeds for moderately dynamic sites, and rotating presigned URLs. Wire the expression into a rule via the console, CLI, CloudFormation, or CDK, and pick the target by job shape — Lambda for under-15-minute work, ECS RunTask when the sync can run long. The 20-minute spacing leaves comfortable headroom for a job that normally takes two or three minutes but occasionally balloons.
AWS-Specific Notes
- →Fire minutes are exactly :00, :20, and :40 in every hour, evaluated against UTC wall-clock time for classic rules.
- →To shift the phase while keeping the spacing, use an explicit list: cron(10,30,50 * * * ? *) keeps 20-minute gaps but avoids the :00 minute entirely.
- →Lambda's maximum timeout is 15 minutes, which fits inside this interval; if the sync can exceed that, front it with Step Functions or run it on ECS.
Frequently Asked Questions
How many times will this run per month, for cost purposes?
72 runs per day works out to about 2,160 in a 30-day month per target. With the five-target maximum on one rule, a fully loaded rule drives around 10,800 monthly invocations.
Can I keep 20-minute spacing but start at :05?
Yes — spell out the minutes instead of using the step: cron(5,25,45 * * * ? *). Lists and steps in the minute field are both valid; the list form gives you full control of the phase.
What happens if one sync run takes 25 minutes?
The next firing happens on schedule anyway and the two runs overlap. Guard with a lock — a conditional write to DynamoDB is the usual pattern — or let Step Functions enforce single-flight execution.
*/20 * * * * in GitHub Actions
Minutes 0, 20, and 40 of every UTC hour: three runs hourly, 72 per day. Sitting four times above the platform's 5-minute floor, the 20-minute cadence buys near-real-time freshness without operating at the edge of what the scheduler supports.
GitHub Actions expression
*/20 * * * *Try it in the tester →Every 20 minutes UTC
Unix / POSIX equivalent: */20 * * * *
Field Breakdown
Using It with GitHub Actions
Written as on: schedule: - cron: "*/20 * * * *" in a default-branch workflow, this rhythm fits polling loops where webhooks are unavailable: checking an external system for new records to mirror into issues, draining a queue of pending notifications, or refreshing a status badge from a third-party API. Keep the job lean — at 72 invocations a day, every wasted setup minute multiplies into hours of runner time by month's end.
GitHub-Specific Notes
- →Fire times are anchored to the wall clock, not to the previous run — if the 12:20 tick starts late at 12:26, the 12:40 tick is still attempted at 12:40, compressing the gap rather than sliding the schedule.
- →Several workflows in one repository all using */20 will request runners at the same three minutes each hour; staggering siblings onto offsets like "10,30,50 * * * *" spreads your own account's concurrent load.
- →All 72 daily anchors are UTC; the cadence is uniform around the clock, so there is no quiet-hours dip unless you restrict the hour field yourself.
Frequently Asked Questions
Will 72 runs a day exhaust my free Actions minutes?
On a private repository it can: 72 runs daily is about 2,190 per month, and at even one billable minute each that exceeds the 2,000 free monthly minutes on the Free plan by itself. Public repositories on GitHub-hosted runners are not billed.
What happens if one run takes 25 minutes?
The next tick fires anyway and the two instances run in parallel, which corrupts anything stateful they share. Add a concurrency key to the workflow — with cancel-in-progress or queuing, whichever suits the job — so only one instance touches the work at a time.