리포트 자동 발행 크론, 150.0시간은 어떤 계산에서 나왔나
리포트 자동 발행 크론은 리포트형 콘텐츠 1편을 쓰고 발행까지 하는 예약 작업입니다. 작업 이름은 `report_autopublish`입니다. 사람이 하던 일을 그대로 옮긴 작업이라, 이 자동화가 일을 얼마나 덜어 주는지도 사람 기준으로 적었습니다. 목록에 적힌 한 줄은 이렇습니다.
- 실행 일정: `20 8 * * *` — 매일 오전 8시 20분
- 최근 30일 실행: 100회 (셈법: 산출 마커)
- 사람이 하면 건당 90분 — 동일 형식 리포트 1편 수기 작성 60분 + 검수·발행 30분
- 근거 등급: 추정(estimate)
- 대체 시간: 150.0시간 (100회 × 90분)
계산은 곱셈 한 번입니다. 실행 횟수 100회에 건당 90분을 곱해 시간으로 바꾸면 150.0시간이 나옵니다. 곱하는 값은 둘뿐이라, 둘 중 하나만 흔들려도 결과가 같이 흔들립니다.
건당 90분 쪽에는 처음부터 추정이라는 이름표를 달아 뒀습니다. 사람이 시계를 들고 잰 값이 아니라, 같은 형식의 리포트를 손으로 쓰면 60분, 검수하고 올리는 데 30분이 든다고 보고 더한 값입니다. 반면 100회 쪽에는 그런 이름표가 없었습니다. 기계가 센 숫자라서 믿어도 된다고 여겼기 때문입니다.
이 글은 그 가정이 무너진 기록입니다. 곱하는 두 값 가운데 의심하지 않던 쪽, 실행 횟수에서 문제가 나왔습니다.
하루 한 번 도는 크론이 어떻게 30일에 100회를 돌까
크론 일정 `20 8 * * *`은 다섯 칸으로 읽습니다. 앞에서부터 분·시·일·월·요일이고, 별표는 «아무 때나»라는 뜻입니다. 그래서 이 줄은 «매일 8시 20분에 한 번»을 뜻합니다. 날짜와 요일 칸이 전부 별표라 한 달 내내 빠짐없이 돌지만, 하루에 두 번 도는 날은 없습니다.
이 일정표대로라면 30일 동안 실행은 30회가 상한입니다. 그런데 목록에는 100회가 적혀 있습니다. 상한을 한참 넘는 값이고, 기계가 셌으니 믿어도 된다는 처음 가정은 일정표 한 줄과 나란히 놓는 순간 성립하지 않았습니다.

일정표 밖에서 실행이 늘어날 길이 없지는 않습니다. 사람이 손으로 스크립트를 한 번 더 돌릴 수도 있고, 다른 예약 작업이 같은 스크립트를 부를 수도 있습니다. 하지만 어느 쪽이든 그 순간부터 100은 «일정표대로 돈 횟수»가 아닙니다. 무엇이 더해졌는지 모르는 채로 곱셈에 넣을 수는 없습니다.
같은 목록의 기술블로그 작업도 사정이 같습니다. 일정은 `20 2 * * *`, 매일 새벽 2시 20분에 한 번인데 최근 30일 실행이 50회로 적혀 있습니다. 이쪽 대체 시간 100.0시간도 50회 × 120분에서 나왔습니다. 두 작업은 하는 일이 다르지만 한 가지가 같았습니다. 실행 횟수를 세는 방법입니다.
셈법을 나눠 보니 어긋남이 한쪽에만 몰렸다
이 목록에는 하루 한 번 도는 작업이 일곱 줄 있습니다. 줄마다 최근 30일 실행 횟수를 어떻게 셌는지, 곧 셈법이 함께 적혀 있어서 셈법별로 나눠 봤습니다. 셈법은 세 가지입니다.
- 산출 마커 — 이름 그대로라면 작업이 산출물을 낼 때 남기는 표시를 센다 (리포트형 콘텐츠·기술블로그)
- 공용 로그 grep — 여러 작업이 함께 쓰는 로그 파일에서 해당 작업의 줄을 찾아 센다 (채용 사이트 공고 수집 세 곳·판매 서비스 후보 스캔)
- 전용 로그 — 그 작업만 쓰는 로그를 센다 (리드 이메일 수집)

나란히 놓으면 규칙 하나가 보입니다. 일정표 상한 30회를 넘은 두 줄은 모두 산출 마커로 셌고, 로그로 센 다섯 줄은 모두 9회로 상한보다 적습니다. 작업이 하는 일로는 갈리지 않고 셈법으로 갈립니다.
로그 쪽이 9회로 적은 이유는 따로 풀어야 합니다. 매일 도는 작업이 30일에 9회라면 작업이 덜 돌았거나 기록이 덜 남았다는 뜻인데, 목록만으로는 둘 중 어느 쪽인지 가를 수 없습니다. 비슷한 과소 계상은 리드 이메일 수집 작업의 실행 횟수를 다시 센 기록에 따로 정리했습니다. 여기서는 위로 넘친 쪽, 산출 마커 두 줄만 봅니다.
어긋남이 셈법과 겹친다는 사실만으로 원인을 확정하지는 못합니다. 두 줄뿐이라 우연일 수도 있습니다. 다만 의심할 곳은 좁혀 줍니다. 리포트를 쓰는 스크립트 본체보다 먼저, 산출 마커가 무엇을 한 번으로 세는지부터 봐야 합니다.
100이라는 숫자는 무엇의 개수일 수 있나
목록에 적힌 정보만으로 100이 나올 수 있는 경우를 나눠 보면 네 갈래가 나옵니다. 어느 쪽인지 아직 확인하지 않았으므로 넷 다 가설입니다.
- ① 실행이 실제로 100번 있었다 — 일정표 밖에서 사람이 손으로 돌렸거나, 다른 예약 작업이 같은 스크립트를 불렀다
- ② 실행 한 번에 리포트가 여러 편 나왔다 — 마커는 실행이 아니라 리포트 편수를 센다
- ③ 리포트 1편에 마커가 여러 개 남는다 — 작성·검수·발행 단계마다, 또는 재시도할 때마다 표시가 한 번씩 찍힌다
- ④ 다른 작업의 산출물이 같은 마커로 섞여 들어갔다
네 가설은 100이라는 숫자에는 똑같이 들어맞습니다. 목록의 한 줄만 봐서는 넷을 구별할 방법이 없습니다.
차이는 150.0시간에서 납니다. 곱셈이 맞으려면 100이 세는 단위와 90분이 가리키는 단위가 같아야 합니다. 그런데 가설마다 100이 세는 대상이 달라서, 어떤 가설에서는 곱셈이 그대로 맞고 어떤 가설에서는 합계가 부풀어 오릅니다.
건당 90분의 «건»과 100회의 «회»는 같은 단위인가
건당 90분의 근거 문장은 «동일 형식 리포트 1편 수기 작성 60분 + 검수·발행 30분»입니다. 90분이 가리키는 단위는 실행 한 번이 아니라 리포트 1편입니다. 그러니 150.0시간이 맞는지는 100이 리포트 편수와 같은가로 판가름 납니다.

가설 ②라면 목록의 «회»라는 이름표만 틀리고 계산은 성립합니다. 실행은 30회를 넘지 않았어도 리포트가 100편 나왔다면, 한 편에 사람 기준 90분이 든다는 추정을 받아들이는 한 150.0시간은 그대로 남습니다. 이 경우 섣불리 «실행 30회»로 고쳐 적으면 오히려 대체 시간을 줄여 잡는 잘못을 합니다.
가설 ③과 ④라면 반대입니다. 리포트 1편이 여러 번 세어졌거나 다른 작업의 기록이 섞였으니 100은 리포트 편수보다 크고, 150.0시간도 그만큼 부풀어 있습니다. 가설 ①은 다시 돌린 실행이 새 리포트를 냈느냐에 따라 ② 쪽이 되기도 하고 ③ 쪽이 되기도 합니다. 실패한 실행을 다시 돌렸을 뿐이라면 사람도 그 리포트를 두 번 쓰지 않으니, 90분을 두 번 셀 이유가 없습니다.
기술블로그 줄도 같은 질문을 받습니다. 근거는 «6,600자 이상 기술 글 1편 수기 작성 60~90분 + 검수·발행 30분»이고, 라이브 9편의 실제 분량(11K~23K자)에서 거꾸로 계산했다고 적혀 있습니다. 적힌 범위의 위쪽 끝 90분에 30분을 더한 값이 120분입니다. 여기서도 단위는 «글 1편»이라, 50회가 글 50편이 아니라면 100.0시간도 같은 이유로 흔들립니다.
어떻게 가려낼 수 있나 — 기록 셋을 맞춰 보는 순서
가설을 가르는 데 새 계측기는 필요 없습니다. 이미 있는 기록 세 가지를 같은 30일 창에 나란히 놓으면 됩니다.
- 실제로 발행된 리포트 목록 — 30일 동안 밖으로 나간 리포트 편수. 이 수가 100에 가까우면 가설 ②, 실행 횟수에 가까우면 가설 ③·④ 쪽입니다
- 크론 실행 기록 — 이 스크립트가 실제로 시작한 날짜와 시각. 일정표 밖 실행이 있었는지(가설 ①)는 여기서 보입니다
- 산출 마커 원본 — 날짜별 마커 개수. 하루에 여러 개가 몰린 날이 있다면 그날 무엇이 몇 번 찍혔는지 엽니다(가설 ③·④)
순서는 발행 목록이 먼저입니다. 곱셈의 짝이 «리포트 1편»이니, 발행된 편수가 곧 곱해야 할 수입니다. 실행 기록과 마커 원본은 발행 편수와 100 사이의 차이를 설명하는 데 씁니다.
마커를 셀 때도 합계부터 보지 않습니다. 평가 운영 규칙에는 «평가 기준부터 짜지 말고 실제 실행 기록 20~50개를 손으로 먼저 본다»는 원칙이 있습니다. 여기서도 같습니다. 마커 몇 줄을 직접 열어 한 줄이 무엇을 뜻하는지 확인하기 전에는, 셈법 이름만 보고 100을 해석하지 않습니다.
이 확인은 아직 하지 않았습니다. 그래서 이 글에는 결론 대신 가설 네 개와 가르는 순서가 남아 있습니다. 확인을 마치면 네 가설 가운데 셋은 지워지고, 목록의 한 줄은 그 결과에 맞춰 고쳐 적습니다.
확인 전까지 150.0시간을 어떻게 적나
확인 전이라고 150.0시간을 지우지는 않습니다. 지우면 «이 자동화는 일을 덜어 주지 않는다»는 다른 주장이 되기 때문입니다. 그 주장도 확인한 적이 없습니다. 대신 숫자 옆에 이름표 두 개를 붙여 둡니다.
- 건당 90분은 추정이다 — 사람이 잰 값이 아니다
- 100회는 산출 마커로 센 값이고 일정표 상한 30회를 넘는다 — 실행 횟수로 확정하지 않았다

검수 자동화 규칙에 «통과는 검사한 것 중 걸린 게 없다는 뜻일 뿐, 정답의 증거가 아니다»라는 문장이 있습니다. 실행 횟수도 마찬가지입니다. 기계가 셌다는 사실은 무엇을 셌는지까지 보증하지 않습니다. 같은 문서의 «못 하는 것을 한다고 하지 않는다»도 여기에 그대로 옮겨 옵니다. 모르는 단위를 아는 척 곱하지 않습니다.
자율 실행 규칙에도 이어지는 원칙이 있습니다. 검증 신호가 없는 항목은 자동으로 끝난 일로 치지 않고 사람의 검토로 넘깁니다. 대체 시간 150.0시간도 지금은 검토를 기다리는 값입니다. 목록의 다른 줄과 합쳐 하나의 큰 숫자로 말하기 전에, 이 줄부터 단위가 맞는지 확인을 마쳐야 합니다.
리포트 자동화 효과를 검토할 때 무엇을 물어야 하나
리포트나 콘텐츠를 자동으로 발행하는 도구를 들였거나 검토하고 있다면, 받은 효과 숫자에 같은 질문을 던질 수 있습니다. «한 달에 몇 시간 절감»이라는 문장은 대부분 횟수와 건당 시간의 곱이고, 곱셈은 두 값의 단위가 같을 때만 뜻이 있습니다.
- 몇 «회»는 실행 횟수인가, 산출물 개수인가, 기록 줄 수인가
- 그 횟수는 실행 일정이 허용하는 범위 안에 있나
- 건당 시간의 «건»은 무엇을 기준으로 잡았나 — 실행 한 번인가, 결과물 한 편인가
- 건당 시간은 누가 쟀나, 아니면 계산했나
넷째 질문은 자동화 절감 시간을 근거 등급으로 나눈 기록에서 다뤘습니다. 이 글은 첫째부터 셋째 질문, 곧 곱하는 두 값의 단위가 서로 맞는지를 다뤘습니다. 네 질문에 바로 답이 나오지 않는 숫자라면, 그 합계는 추정이라는 이름표와 함께 읽는 편이 안전합니다.
둘째 질문은 특히 싸게 확인할 수 있습니다. 실행 일정 한 줄과 기록된 횟수를 나란히 놓기만 하면 되고, 이번에도 그 한 번의 대조가 150.0시간을 다시 보게 만든 출발점이었습니다. 회사에서 굴리는 자동화의 효과를 이런 기준으로 따져 보고 싶다면 상담에서 이야기를 나눌 수 있습니다.
아직 풀지 못한 것
- 리포트 자동 발행 크론의 100회가 네 가설 중 어느 쪽인지 확인하지 않았습니다. 발행된 리포트 편수부터 세야 합니다.
- 기술블로그 작업의 50회에도 같은 확인이 남아 있습니다. 일정표 상한 30회를 넘는다는 점에서 사정이 같습니다.
- 로그로 센 다섯 줄이 모두 9회인 이유를 모릅니다. 작업이 덜 돌았는지, 기록이 덜 남았는지 가르지 못했습니다.
- 건당 90분은 여전히 추정입니다. 단위가 맞더라도 사람이 리포트 1편을 실제로 쓰며 시간을 재기 전까지, 곱하는 두 값 가운데 하나는 추정 위에 서 있습니다.
처음에는 곱셈에서 의심할 값을 하나로 봤습니다. 건당 90분은 추정이고 100회는 기계가 센 값이라는 구도였습니다. 일정표 한 줄과 나란히 놓자, 기계가 셌다고 믿은 쪽에도 이름표가 필요했습니다. 숫자는 그대로 두고 무엇을 셌는지를 옆에 적는 쪽을 골랐습니다.