엔지니어링 · 2026년 8월 24일

Cron 표현식 레퍼런스 — 실제로 필요한 모든 예제

매분, 평일 오전 9시, 매월 1일, 마지막 금요일 — 각 필드의 설명과 함께 복붙 가능한 cron 표현식.

cron 표현식은 컴퓨터에 “이 일정에 이것을 실행해”라고 말하는 가장 간결한 방법이다. 다섯 개의 필드, 모두 숫자와 특수 문자, 문법을 배우면 모호함이 없다. 문제: 실제로 필요한 일반적인 패턴이 약 15개이고, 나머지 시간은 crontab -e 프롬프트에서 일요일이 0인지 7인지 기억하려고 쳐다보고 있다.

이 글은 5년 전에 가지고 싶었던 치트시트이다. 모든 일반적인 패턴을 복붙 가능한 표현식, 설명, 그리고 사람들을 당기는 Gotcha와 함께 설명한다.

다섯 개의 필드

* * * * *
│ │ │ │ │
│ │ │ │ └── 요일 (0-6, 일요일=0)
│ │ │ └──── 월 (1-12)
│ │ └────── 일 (1-31)
│ └──────── 시 (0-23)
└────────── 분 (0-59)

각 필드는 다음을 가질 수 있다:

  • 특정 값: 5
  • 와일드카드: * (모든 값)
  • 범위: 1-5
  • 스텝: */15 (매 15)
  • 목록: 1,15,30
  • 스텝이 포함된 범위: 1-30/5 (1과 30 사이 매 5)

이것이 전부이다. 나머지는 이 기본 요소들을 조합하는 것이다.

패턴

매분

* * * * *

사용 사례: 항상 실행되고 있어야 하고 스케줄러가 재생성하는 작업. 원하는 것은 거의 아니다.

매 N분

*/5 * * * *      # 매 5분
*/15 * * * *     # 매 15분
*/30 * * * *     # 매 30분

*/5는 “0부터 시작하여 매 5분”을 의미한다. 즉, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55.

Gotcha: */5의 첫 실행은 분 0이고, crontab을 저장한 시점이 아니다. 12:03에 저장하면 첫 실행은 12:08이 아니라 12:05이다.

매시간 정각

0 * * * *

Gotcha: 이것은 “매시간 분 0”이고, 1:00, 2:00, 3:00 등이다. “매시간 30분_past”를 원하면 30 * * * *를 사용한다.

매일 자정

0 0 * * *

Gotcha: 서버의 시간대이다. cron은 시스템 시간대를 사용한다. 서버가 UTC이고 미국 동부 자정을 원하면 변환이 필요하다. 가장 깔끔한 수정: 시스템 시간대를 원하는 것으로 구성하거나, CRON_TZ 환경 변수를 설정한다(대부분의 최신 cron 구현체가 지원).

매일 특정 시간

0 9 * * *       # 오전 9:00
30 14 * * *     # 오후 2:30
0 0 * * *       # 자정
15 3 * * *      # 오전 3:15

평일 오전 9시

0 9 * * 1-5

1-5는 요일이고, 월요일부터 금요일까지이다.

Gotcha: 0과 7은 모두 일요일을 의미한다. POSIX 사양은 둘 다 허용한다. 대부분의 구현체는 실수로 7을 사용해도 허용한다. 그것을 의존하지 마라.

매주 월요일

0 0 * * 1

매주 월요일 자정.

주 2회 (월요일과 목요일)

0 9 * * 1,4

월요일과 목요일 오전 9시.

매월 1일

0 0 1 * *

1일 자정.

매월 마지막 날

0 0 L * *

L은 Vixie cron / Quartz 확장이다. 표준 cron에는 없다. 표준 cron을 사용하는 경우 “마지막 날” 근사치에 의존해야 한다. 0 0 28-31 * *처럼 (28일, 29일, 30일, 31일에 실행되고, 2월에는 28일에 실행된다).

매 분기

0 0 1 */3 *

1월, 4월, 7월, 10월 1일 자정.

매주 일요일 정오

0 12 * * 0

매 6시간

0 */6 * * *

0:00, 6:00, 12:00, 18:00.

평일 오전 9시~오후 5시 매분

* 9-17 * * 1-5

월요일부터 금요일까지 9:00:00부터 17:59:59까지 매분 실행되는 작업. 아마 너무 공격적이지만 — 가능하다.

매월 1일 오전 2시 30분

30 2 1 * *

매월 마지막 금요일 오후 11시

0 23 * * 5#5

5#5는 “매월 5번째 금요일”이다(Quartz 문법). #과 L은 비표준 확장이고 — 표준 cron에는 “매월 마지막 금요일” 표현식이 없다. 표준 cron에서 이것이 필요하면, 날짜를 확인하는 래퍼 스크립트가 필요하다.

매 30초

표준 cron은 1분 이하로 갈 수 없다. 분 이하 스케줄링의 경우:

  • systemd 타이머: OnUnitActiveSec=30s
  • Kubernetes CronJob: 불가능(최소 1분). 루프 내 sleep 30이 있는 일반 Job을 사용한다.
  • Node.js 앱: 프로세스 내 setInterval(fn, 30_000).

일광 절약 시간

cron은 일광 절약 시간(DST)을 구현에 따라 작업을 두 번 실행(봄 앞당기기)하거나 건너뛰기(가을 뒤로)로 처리한다. 시간에 민감한 작업(청구 실행, 보고서)인 경우 DST 놀라움을 피하기 위해 1-3 AM 윈도우 바깥으로 충분히 스케줄한다.

Quartz 스케줄러는 DST 플래그로 이를 처리한다. 표준 cron은 그렇지 않다.

1분 해상도 제한

cron은 본질적으로 1분 해상도 도구이다. 분 이하 스케줄링이 필요하면 답은 “다른 도구를 사용하라”이다. 특히 Kubernetes의 경우:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: every-30-seconds
spec:
  schedule: "* * * * *"
  startingDeadlineSeconds: 10
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - name: worker
              image: myworker:latest
              command: ["/bin/sh", "-c", "for i in 1 2; do do_work; sleep 30; done"]

이것은 분당 두 개의 하위 작업을 발행하여 30초마다 작업을 실행한다. 거칠지만 작동한다.

Quarkus, EventBridge, Kubernetes CronJob은?

다른 스케줄러는 약간 다른 cron 문법을 사용한다. 다섯 필드 형태가 가장 일반적이다. 몇 가지 다른 것들:

  • Quartz: 여섯 필드(초 포함), “특정 값 없음”을 위한 ? 와일드카드.
  • AWS EventBridge: 여섯 필드, L과 # 확장 지원.
  • Kubernetes CronJob: 다섯 필드, L이나 # 지원 없음.
  • Spring @Scheduled: 여섯 필드(초 포함), ?와 L 지원.
  • GitHub Actions: 다섯 필드, 확장 없음.

표준과 일치하지 않는 도구를 사용하는 경우 문서를 확인한다. 이 치트시트의 대부분의 패턴은 직접 전환된다. 비표준 확장(L, #, W)은 그렇지 않다.

문법을 암기하지 않고 cron 표현식 생성

문법을 암기하고 싶지 않다면, DevSpeedTools의 cron 생성기에서 다섯 개의 필드를 클릭하고 다음 다섯 번의 예약된 실행을 보여준다. “0 9 * * 1-5가 정말 평일 오전 9시를 의미하는지” 확인하는 가장 빠른 방법이다 — 답은 예이지만, 다음 실행 날짜를 보면 패턴이 구체화된다.

일회성 표현식의 경우, crontab.guru가 표준 레퍼런스이다. cron 생성기는 같은 작업을 하고 완전한 클라이언트 사이드이므로, 붙여넣는 표현식은 절대 브라우저를 떠나지 않는다.

요약

Cron 표현식은 몇 가지 규칙을 가진 작은 DSL이다. 다섯 개의 필드, * (임의), - (범위), / (스텝), , (목록)를 배우면, 필요할 95%의 스케줄을 표현할 수 있다. 나머지 5%는 스케줄러별 확장이나 다른 도구가 필요하다. 의심이 나면, 다음 실행을 보여주는 도구로 표현식을 생성하고 미리보기하라 — 멘탈 디버깅보다 훨씬 빠르다.