1. cron 이란 무엇인가
cron 은 Unix 계열 OS 가 주기적으로 명령을 실행하게 하는 스케줄러의 이름이자 그 스케줄을 기술하는 문법을 뜻합니다. 1975년 Brian Kernighan 이 처음 설계했고 현재 Linux·macOS·BSD, 각종 배포 스크립트, Kubernetes CronJob, GitHub Actions schedule:, AWS EventBridge Cron, Jenkins 등 거의 모든 스케줄러가 같은 문법을 재활용합니다.
2. POSIX 5필드
표준 cron 표현식은 공백으로 구분된 5개 필드로 구성됩니다.
┌──────── 분(minute) 0-59 │ ┌────── 시(hour) 0-23 │ │ ┌──── 일(day-of-month)1-31 │ │ │ ┌── 월(month) 1-12 또는 JAN-DEC │ │ │ │ ┌ 요일(day-of-week)0-6 (0 또는 7 = 일요일) 또는 SUN-SAT * * * * *
예를 들어 0 9 * * 1-5 는 분=0, 시=9, 일=매일, 월=매월, 요일=월~금 이므로 "평일 오전 9시 정각에 실행" 으로 해석됩니다.
3. 5개 연산자
*— 해당 필드의 모든 값.* * * * *는 매 분 실행.a,b,c— 리스트.0 9,13,18 * * *→ 매일 오전 9시·오후 1시·오후 6시.a-b— 범위.0 9 * * 1-5→ 월요일~금요일.*/n— 스텝.*/15 * * * *→ 매 15분마다. 범위와 결합해0-30/5 * * * *→ 매 정각 0·5·10·…·30분.JAN..DEC,SUN..SAT— 영문 3자 이름 축약. 대소문자 무관.0 0 * * SUN→ 매주 일요일 자정.
4. 축약 키워드
| 키워드 | 동의 |
|---|---|
@yearly / @annually | 0 0 1 1 * |
@monthly | 0 0 1 * * |
@weekly | 0 0 * * 0 |
@daily / @midnight | 0 0 * * * |
@hourly | 0 * * * * |
5. 일(day-of-month) 과 요일(day-of-week) 이 모두 지정되면?
함정이 하나 있습니다. 두 필드가 모두 제한 되어 있으면 Vixie cron / Linux cron 은 둘 중 어느 하나라도만족하면 실행합니다 (OR). 반대로 Quartz (Java 생태계) 는 둘 모두 만족해야 실행합니다 (AND). 이 도구는 POSIX 표준인 OR 해석을 따릅니다. 요일 조건을 확정하려면 일 필드를 * 로, 일 조건을 확정하려면 요일 필드를 * 로 남겨 두세요.
6. 실전 스케줄 10선
0 9 * * 1-5— 평일 오전 9시. 업무 알림, 출근 리포트.*/15 * * * *— 매 15분. 외부 API 동기화, 헬스체크.0 0 * * 0— 매주 일요일 자정. 주간 리포트 생성.0 2 * * *— 매일 새벽 2시. DB 백업의 관례 시간.0 0 1 * *— 매월 1일 자정. 월간 청구·통계 집계.30 18 * * 5— 매주 금요일 오후 6시 30분. 주간 회고 알림.0 */6 * * *— 6시간마다. 캐시 새로고침.0 9,18 * * *— 매일 오전 9시·오후 6시. 출·퇴근 체크인.0 0 1 1 *— 새해 자정. 연간 리셋 작업.0 9 * * 1-5와0 10 * * 6,0— 평일 9시·주말 10시 (두 cron 으로 분리).
7. 운영 환경별 주의점
- Linux cron (Vixie) — 기본값. 타임존은 시스템 TZ. 시스템 시간 KST 가 아니면 9시간 어긋납니다.
CRON_TZ=Asia/Seoul를 crontab 상단에 선언하세요. - Kubernetes CronJob — UTC 기본.
spec.timeZone: "Asia/Seoul"(1.27+) 또는 표현식 자체를 UTC 기준으로 작성. - GitHub Actions — UTC 고정, 타임존 변경 불가. 한국 오전 9시를 원하면
0 0 * * *(=UTC 자정 = KST 9시). - AWS EventBridge — 6필드 (분·시·일·월·요일·년),
?와L,W,#지원. POSIX 표현식을 그대로 넣으면 실패합니다. - Quartz (Spring·Quartz Scheduler) — 6~7필드 (초 포함), 일/요일 동시 지정 불가 (
?필요).
8. 디버깅 체크리스트
- 표현식을 이 변환기에 붙여넣어 자연어 설명이 의도와 일치하는지 먼저 확인.
- "다음 실행 시각" 10건을 보고 의도한 간격과 맞는지 확인.
- 프로덕션 타임존이 KST 인지 UTC 인지 확인. 9시간 오프셋 실수가 가장 흔함.
- 일·요일 동시 지정 시 Vixie vs Quartz 차이 기억.
- 실행 로그에 "실행 안 됨" 이 뜨면 cron 데몬이 실행 중인지 확인 (
systemctl status cron).
9. 이 도구의 범위
이 도구는 POSIX 5필드를 기준으로 하며, Quartz 의 초 필드·L·W·# 같은 확장 문법은 후속 릴리스에서 추가할 예정입니다. AWS EventBridge 전용 6필드, GitHub Actions 전용 탭도 로드맵에 있습니다.
10. Vixie cron 의 역사와 현대 구현체 계보
오늘 우리가 쓰는 표현식의 골격은 1987년 Paul Vixie 가 BSD 용으로 새로 작성한 cron 데몬에서 굳어졌습니다. 이전 SVR4 cron 은 환경변수 처리·로그 형식이 제각각이었지만, Vixie cron 이 시스템 crontab(/etc/crontab) 의 사용자 필드 추가, 디렉토리 단위 분할(cron.d), 표준 메일 보고 등을 정리하면서 데비안·우분투·페도라·RHEL 의 기본 구현으로 자리 잡았습니다. macOS 와 Alpine Linux 가 채택한 BusyBox cron 은 Vixie 의 축약본이라 CRON_TZ나 @reboot 일부 토큰을 지원하지 않는 경우가 있어, 동일한 표현식이 페도라에서는 정상이고 도커 알파인 컨테이너 안에서는 침묵하는 사고가 자주 일어납니다. 이 도구의 해석은 Vixie cron 의 동작을 우선 기준으로 삼되, 표현식 자체에는 영향이 없는 데몬 차이는 안내 문구로 별도 표기합니다.
11. KST·UTC 9시간 오프셋이 가장 자주 부르는 사고
한국에서 운영되는 백엔드의 시간 오류 중 절반 이상은 두 가지 패턴으로 모입니다. 첫째, 한국 사용자에게 오전 9시 푸시를 보내려고 0 9 * * * 를 적었는데 서버 TZ 가 UTC 라 KST 오후 6시에 발송되는 사례. 둘째, 로컬 개발 환경에서 KST 로 잘 돌던 표현식이 EC2·EKS·Cloud Run 등 클라우드 리전이 미국·일본 UTC 인 인프라로 옮겨가면서 새벽에 무더기로 실행되는 사례입니다. 권장 운영 패턴은 명확합니다. (1) 컨테이너 이미지 안에 tzdata 를 설치하고TZ=Asia/Seoul 을 명시, (2) crontab 상단에 CRON_TZ=Asia/Seoul 한 줄을 박아 두고, (3) 표현식 주석에 "KST 기준 09:00" 같은 의도 시각을 적어 두면 코드 리뷰에서 9시간 오프셋 실수를 조기에 잡을 수 있습니다. 이 도구는 입력 표현식 옆에 KST·UTC 두 컬럼으로 다음 실행 시각을 동시에 보여 주어 시야의 사각지대를 줄입니다.
12. Kubernetes CronJob 실전 운영 체크리스트
Kubernetes 의 CronJob 은 표면적으로 cron 문법을 따르지만, 잡(job) 객체를 매번 새로 생성하는 구조이기 때문에 다음 항목을 명시하지 않으면 운영 사고가 누적됩니다. 우선 concurrencyPolicy 를 Forbid또는 Replace 로 설정해 직전 잡이 끝나기 전에 새 잡이 또 떠 데이터가 이중 처리되는 경합을 막아야 합니다.startingDeadlineSeconds 는 노드 장애나 컨트롤플레인 재기동으로 늦게 깬 잡을 어디까지 허용할지 결정하는데, 이 값이 표현식 간격보다 짧으면 영영 누락된 채 다음 회차로 넘어갑니다. successfulJobsHistoryLimit 과failedJobsHistoryLimit 를 1~3 으로 두어 etcd 가 잡 객체에 잠식되지 않도록 하고,spec.timeZone 을 1.27 이상에서 명시하면 UTC 변환을 코드 머리에 두지 않아도 됩니다. 또한 매우 짧은 주기 (*/1) 는 API 서버 부하를 부르므로 가급적 큐 기반 워커로 옮기는 편이 좋습니다.
13. GitHub Actions schedule 의 한계와 우회법
GitHub Actions 의 schedule: 트리거는 사용하기 쉬워 보이지만 운영에 들어가면 세 가지 함정을 만납니다. 첫째, 타임존이 UTC 로 고정되어 한국 기준 시각으로 적으면 9시간이 어긋납니다. 둘째, 무료 플랜에서는 인기 시각 (정각·15·30·45 분)에 잡이 폭주해 실제 실행이 5~40분 늦게 시작되는 경우가 잦습니다. 셋째, 기본 브랜치 가장 최신 커밋의 워크플로 파일만 스케줄을 인식하므로 PR 브랜치에서 추가한 cron 은 머지 전에는 동작하지 않습니다. 안정 운영을 위해서는 핵심 잡을 정각이 아닌 7·23·37 분처럼 덜 붐비는 분으로 옮기고, 사용자에게 보여지는 알림은 시각 보증이 필요한 외부 스케줄러(Cron-job.org·EventBridge·Cloud Scheduler)로 분리한 뒤 GitHub Actions 는 빌드·테스트 등 지연 허용 잡으로 한정하는 패턴이 견고합니다.
14. AWS EventBridge 6필드와 POSIX 의 차이 해부
EventBridge 의 cron 식은 분·시·일·월·요일·년 여섯 필드이며, 일과 요일을 동시에 쓸 수 없어 한쪽은 반드시 물음표로 비워야 합니다. 또한 매월 말일을 뜻하는 L, 평일에 가장 가까운 날을 뜻하는 W, "n째 요일"을 지정하는 # 같은 확장 토큰이 추가되어 표현력은 풍부하지만 POSIX 와의 호환성은 끊겨 있습니다. 예를 들어 매월 마지막 평일 오후 6시는 EventBridge 에서 0 18 LW * ? * 한 줄로 끝나지만, POSIX 에서는 28~31일을 모두 후보로 두고 셸 분기로 "내일이 1일이면 실행"을 따로 처리해야 합니다. AWS 콘솔에 표현식을 직접 입력하기 전에 이 도구로 POSIX 의도를 먼저 확정한 뒤 AWS 문법으로 옮기는 두 단계 작업이 사고를 줄여 줍니다.
15. 한국 SaaS 운영에서 자주 쓰는 표현식 모음
한국 시장의 마이크로 SaaS·이커머스·콘텐츠 플랫폼이 실제로 쓰는 표현식은 의외로 좁은 범위에 집중되어 있습니다. 결제 정산 배치는 매월 1일 새벽 3시(0 3 1 * *), 일일 매출 리포트는 평일 오전 7시 30분 (30 7 * * 1-5), 외부 API 토큰 갱신은 50분 간격(*/50 * * * *) 으로 토큰 만료 직전에 한 번 더 갱신해 두는 패턴이 흔합니다. 카카오 알림톡은 광고성 야간 발송이 제한되므로 0 9-21 * * * 처럼 시간 창을 좁히고, 네이버 쇼핑 광고 입찰가 조정처럼 분단위 경쟁이 필요한 잡은 */3 9-23 * * * 같이 영업시간만 촘촘하게 두는 식입니다. 이 도구는 사용자가 자주 쓰는 표현식 5건을 브라우저에 자동 저장해, 다음 방문 시 즉시 다시 띄울 수 있게 합니다.
16. 도구가 변환을 거절하는 경우와 그 의미
본 도구는 표현식 자체가 POSIX 5필드 문법을 벗어나거나, 필드 값의 범위(분 0~59, 시 0~23, 일 1~31, 월 1~12, 요일 0~7) 를 넘는 경우 변환을 거절합니다. 자주 보이는 사고는 Quartz 의 초 필드를 그대로 붙여 6필드로 만든 경우, AWS EventBridge 의 년 필드까지 포함한 6필드, 그리고 일요일을 7 로 적었는데 0 으로 정규화되는 데몬과 그렇지 않은 데몬을 혼동한 경우 입니다. 거절 메시지에는 어떤 필드가 어떤 이유로 잘못됐는지 함께 표시되므로, 그 안내만 따라가도 사고의 절반은 이 도구 안에서 끝납니다. 변환에 성공한 표현식도 우측 패널에서 "다음 실행 시각 10건" 을 KST·UTC 두 줄로 함께 보여 주어 의도와 어긋난 9시간 오프셋을 즉시 잡아낼 수 있습니다.
17. 표현식 명명 규칙 — 사람에게 친절한 cron 의 작은 디테일
프로덕션에서 cron 을 운영하는 팀은 표현식 옆에 짧은 주석을 다는 작은 규칙으로 사고를 크게 줄입니다. 권장 패턴은 다음과 같습니다. 첫째, 표현식 뒤에 의도 시각을 사람의 언어로 함께 적기(예: 0 9 * * 1-5 평일 KST 오전 9시 업무 알림 발송). 둘째, 잡 이름을 동사로 시작(send-, sync-, cleanup-, backup-, refresh-) 해 잡 종류를 한 눈에 구분. 셋째, 알림이 필요한 잡과 자동 복구만 되면 충분한 잡을 같은 디렉토리에 두지 않기. 이 세 규칙만 지켜도 야간 호출의 절반은 회피됩니다. 본 도구의 변환 결과 패널은 자연어 설명을 그대로 복사 가능한 형태로 제공해 주석에 붙여 두기 좋게 설계되었습니다.
18. cron 도입 전에 한 번 더 고민할 대안
모든 주기성 잡이 cron 으로 해결되지는 않습니다. 실행 시각의 정확성이 1초 단위로 필요하거나, 작업이 분산 워커에 뿌려져야 한다면 BullMQ·Celery·Sidekiq 같은 큐 시스템에 지연 잡(delayed job) 으로 등록하는 편이 안정적입니다. 사용자 별로 다른 시각에 트리거가 필요한 사례(예: 사용자가 설정한 알림 시각) 도 cron 대신 데이터베이스에 "다음 실행 시각" 컬럼을 두고 워커가 매 분 조회하는 방식이 확장성이 좋습니다. cron 은 시스템 전역 주기 잡, 운영자가 직접 관리하는 배치, 그리고 외부 인터페이스가 단순한 잡에 가장 잘 맞습니다. 이 도구는 cron 표현식 자체의 해석을 도와주지만, 표현식 뒤의 잡 설계가 cron 에 맞는지까지 점검해 보는 시간이 매번 충분히 값집니다.