왜 만들었나요
스케줄러(크론탭)에 걸어둔 배치가 4시 정각이 아니라 4시 5분에 돈다는 걸 배포 다음 날 로그를 보고서야 알았습니다. 자리 하나만 잘못 세도 실행 시각이 어긋나니까요. 그 확인 왕복이 싫어서 만들었습니다.
표현식을 넣으면 사람 말로 풀어 줍니다. 앞으로 실제 몇 시에 도는지 다음 실행 시각까지 보여 줍니다.
로딩 중...
스케줄러(크론탭)에 걸어둔 배치가 4시 정각이 아니라 4시 5분에 돈다는 걸 배포 다음 날 로그를 보고서야 알았습니다. 자리 하나만 잘못 세도 실행 시각이 어긋나니까요. 그 확인 왕복이 싫어서 만들었습니다.
Note
입력한 표현식은 서버로 전송되지 않습니다. 해석과 계산이 전부 브라우저 안에서 이뤄집니다.
입력창 아래 오른쪽 크론 환경 버튼에서 환경을 고릅니다. 일반 crontab이면 Unix/Linux, 스프링·Quartz면 Quartz/Spring, AWS면 EventBridge 입니다. 표현식을 붙여넣으면 칸 수를 보고 환경을 자동으로 맞춰 주기도 합니다. 옆의 프리셋 버튼을 누르면 자주 쓰는 표현식이 바로 채워집니다.

입력창에 표현식을 치거나 붙여넣습니다. 맞으면 평일(월–금) 오전 9시에 실행 같은 설명과 다음 실행 시각, 칸마다 뜻을 풀어 주는 필드별 분석이 바로 나옵니다. 틀리면 입력창이 빨갛게 되고 아래에 "시: 값이 범위를 벗어났습니다" 처럼 문제 칸 이름과 이유가 표시됩니다.

아래 다음 실행 예정에서 향후 5번의 시각을 확인합니다. 오른쪽 시간대 선택으로 UTC·서울·도쿄·상하이·뭄바이·파리·런던·뉴욕·LA 아홉 곳을 바꿔 볼 수 있습니다.

평일 오전 9시 표현식을 넣으면 이렇게 나옵니다.
넣은 것 0 9 * * 1-5
↓
설명 평일(월–금) 오전 9시에 실행
다음 실행 2026-08-24 (월) 09:00
2026-08-25 (화) 09:00
2026-08-26 (수) 09:00 …
Unix/Linux 표준은 다섯 칸이고, 왼쪽부터 분 시 일 월 요일 순서입니다.
| 칸 | 범위 |
|---|---|
| 분 | 0-59 |
| 시 | 0-23 |
| 일 | 1-31 |
| 월 | 1-12 |
| 요일 | 0-7 (0과 7 모두 일요일) |
기호는 네 가지면 대부분 해결됩니다.
| 기호 | 뜻 | 예시 |
|---|---|---|
* | 모든 값 | 매분·매시 |
, | 나열 | 1,3,5 |
- | 범위 | 9-17 (9시부터 17시) |
/ | 간격 | */15 (분 칸에 쓰면 15분마다) |
@daily·@hourly·@midnight·@weekly·@monthly·@yearly·@reboot 같은 축약 표기도 그대로 읽어 사람 말로 풀어 줍니다.
1-7로 바뀌고 ?·L·W 기호를 더 씁니다같은 "평일 9시"라도 환경마다 모양이 다르니, 크론 표현식 생성기에서 '크론 환경'을 실제 쓰는 곳으로 맞춰 놓고 봐야 오해가 없습니다.
자리 순서는 왼쪽에서 오른쪽으로 갈수록 시간 단위가 커진다고 기억하면 됩니다. 분 → 시 → 일 → 월 → 요일 순입니다.
기호는 소리 내어 읽으면 쉽습니다. /는 "N마다", -는 "부터 까지", ,는 "그리고". 그러면 0 9-11,14 * * * 가 "매일 9시·10시·11시 그리고 14시"로 자연스럽게 풀립니다.
가장 흔한 원인 셋입니다.
9 0 * * *은 0시 9분이지 9시가 아닙니다?로 비워야 합니다. 둘 다 값을 넣으면 오류로 막힙니다0 0 13 * 5는 13일이면서 금요일인 날이 아니라 13일 또는 금요일마다 돕니다이 문법은 리눅스 crontab 하나로 끝나지 않습니다. 스프링의 @Scheduled, 쿠버네티스 CronJob, GitHub Actions, AWS EventBridge까지 주기적으로 뭔가를 돌리는 곳이면 거의 같은 다섯 칸을 다시 만납니다. 한 번 익혀 두면 새 도구를 만날 때마다 처음부터 배우지 않아도 됩니다.
정해진 시각에 프로그램을 자동 실행하는 방식입니다. 리눅스에서 시작해 지금은 대부분의 서버·클라우드 서비스가 같은 표기법을 씁니다. 이 표기를 사람 말로 풀어 주는 도구를 크론 표현식 생성기 또는 크론 표현식 빌더라고 부릅니다.
지역별 시간 기준입니다. 서버는 대개 UTC로 돌고 한국은 UTC + 9시간이라, 같은 표현식도 어느 시간대로 해석하느냐에 따라 실행 시각이 달라집니다.
가장 흔한 원인은 시간대 불일치입니다. 서버가 UTC로 동작하고 있다면 한국 시간 기준으로 쓴 표현식이 9시간 어긋나게 실행됩니다. '다음 실행 예정' 카드의 시간대 선택을 KST와 UTC로 번갈아 바꿔 보면 같은 표현식이 각각 몇 시에 도는지 비교할 수 있으니, 서버의 실제 시간대에 맞는 값인지 검증해 보세요.
안 됩니다. Linux crontab은 분·시·일·월·요일 5개 필드를 사용하지만, Spring @Scheduled는 맨 앞에 초 필드가 추가된 6필드 형식입니다. Linux에서 쓰던 0 9 * * 1-5를 Spring에 그대로 넣으면 필드가 한 칸씩 밀려 의도와 전혀 다르게 동작합니다. AWS EventBridge도 연도 필드가 포함된 6필드라 주의가 필요합니다.
L 문자를 사용하면 됩니다. 예를 들어 0 0 L * ?는 매월 마지막 날 자정에 실행됩니다. 다만 L은 표준 Unix crontab에서는 지원하지 않고 Quartz, AWS EventBridge, Spring 같은 환경에서만 사용할 수 있습니다. Linux crontab을 쓴다면 28-31 범위와 조건을 조합하거나 스크립트 내부에서 말일 여부를 직접 판단해야 합니다.
crontab의 실행 환경은 일반 셸과 다릅니다. PATH가 매우 제한적이라 셸에서는 잘 되던 명령이 crontab에서 실패하는 경우가 많습니다. 스크립트 경로를 절대 경로로 작성하고, 출력을 로그 파일로 리다이렉트해서(>> /var/log/script.log 2>&1) 실제 오류 메시지를 확인하는 것이 가장 빠른 디버깅 방법입니다.
크론 자체에는 중복 실행 방지 기능이 없습니다. 단일 서버라면 flock 명령으로 파일 잠금을 걸면 되고, Kubernetes CronJob이라면 concurrencyPolicy: Forbid 옵션으로 이전 Job이 끝나기 전에는 새 Job을 시작하지 않도록 설정할 수 있습니다. 분산 환경에서는 Redis SETNX나 DB Advisory Lock 같은 분산 잠금을 활용하세요.
마지막 업데이트:
매일 오전 4시 5분에 실행
┌───────────── 분 (0-59) │ ┌─────────── 시 (0-23) │ │ ┌───────── 일 (1-31) │ │ │ ┌─────── 월 (1-12) │ │ │ │ ┌───── 요일 (0-7) │ │ │ │ │ * * * * * 실행할 명령
| 기호 | 의미 | 예시 | 동일 표현 |
|---|---|---|---|
| * | 모든 값 | 매분 | |
| - | 범위 | 매시 1~10분 | |
| , | 값 목록 | 매시 1분과 10분 | |
| / | 간격 | 10분마다 | |
| @yearly | 매년 1월 1일 자정 | 0 0 1 1 * | |
| @annually | @yearly와 동일 | 0 0 1 1 * | |
| @monthly | 매월 1일 자정 | 0 0 1 * * | |
| @weekly | 매주 일요일 자정 | 0 0 * * 0 | |
| @daily | 매일 자정 | 0 0 * * * | |
| @midnight | @daily와 동일 | 0 0 * * * | |
| @hourly | 매시 정각 | 0 * * * * | |
| @reboot | 시스템 부팅 시 1회 | — |