← 모든 글

잠들기 전에 실행하는 것

매일 밤 노트북을 닫기 전에 명령어 하나를 실행해요. 프로덕션 사이트의 15,000개 페이지를 전부 점검하는 명령어예요. 모든 블로그 포스트, 모든 회사 페이지, 모든 프로그래매틱 가이드, 모든 로케일 변형을 확인해요. 페이지마다 HTTP 상태를 검증하고, TTFB를 측정하고, Cloudflare 캐시 상태를 확인하고, 오류가 있으면 기록해요. 전체 점검은 완료까지 약 6시간이 걸려요. 제가 자는 동안 백그라운드에서 실행돼요.

빠른 크리티컬 패스 점검도 함께 실행하는데, 이건 2분이면 끝나요. 헬스 엔드포인트, 사이트맵, 매출 페이지, S티어 회사 허브, 마켓 페이지, 프로그래매틱 콘텐츠 인덱스, i18n 블로그 아카이브를 점검해요. 이 점검은 직접 지켜봐요. 하나라도 실패하면, 잠들기 전에 원인을 조사해요.

이 루틴이 생성하는 리포트는 이런 형태예요:

NIGHTCHECK -- 2026-03-27 (morning)
Overnight comprehensive: 16,228/16,602 ok (97.7%)
Avg TTFB: 715ms
S-tier companies: ALL PASS, ALL HIT
Markets: ALL PASS (89-175ms HIT)
i18n blogs: es 95ms HIT | ja 196ms HIT | de 181ms HIT

누구도 이걸 하라고 요청하지 않았어요. 어떤 티켓에도 이 작업이 포함되어 있지 않아요. 스프린트에 “nightcheck 실행”이 들어간 적도 없어요. 이 루틴은 제가 보지 않는 시간에도 사이트가 제대로 작동하는지 신경 쓰기 때문에 존재해요.

왜 매일 밤인가

사이트는 매일 바뀌어요. 하루 동안 87개의 커밋을 배포할 수도 있어요. i18n 번역, 크롤 프로바이더 업데이트, CRO 실험, 성능 수정, 로고 보정 같은 것들이에요. 각 커밋은 개별적으로 테스트돼요. 하지만 87개 커밋의 조합은 개별 커밋으로는 드러나지 않는 장애를 만들어낼 수 있어요.

번역 배치가 블로그 사이트맵을 렌더링 임계값 너머로 밀어낼 수도 있어요. 새로운 프로바이더가 렌더링에 14초나 걸리는 회사 페이지를 만들어낼 수도 있어요. 캐시 헤더 변경으로 Cloudflare가 이전에 빠르던 라우트의 캐싱을 중단할 수도 있어요. CSS 리팩터링이 특정 로케일에서만 템플릿을 깨뜨릴 수도 있어요.

nightcheck는 조합 장애를 잡아내요. “이 커밋이 뭔가를 깨뜨렸나”가 아니라 “오늘 모든 변경이 반영된 후에도 사이트가 작동하는가”를 확인하는 거예요. 이 차이가 중요한 이유는 조합 장애가 CI에서는 보이지 않기 때문이에요. 각 커밋은 자체 테스트를 통과해요. 87개 커밋이 각각 자체 테스트를 통과한다고 해서 전체 시스템이 작동한다는 보장은 없어요.

무엇을 측정하는가

점검은 네 단계로 나뉘어요:

P0 인프라. 헬스 엔드포인트가 데이터베이스 연결 상태와 함께 정상을 반환하는지 확인해요. 사이트맵이 유효한 XML을 반환하는지, robots.txt와 llms.txt가 존재하는지, RSS 피드가 유효한지 확인해요. 이것들이 깨지면 검색 엔진에 사이트가 보이지 않게 돼요.

P0 매출. 홈페이지, 이력서 빌더, 분석기, 가격 페이지가 모두 로딩되는지 확인해요. 이 페이지들이 깨지면 직접적으로 매출 손실이 발생해요. 이력서 빌더는 역사적으로 가장 느린 페이지라 5초에 WARN 임계값이 설정되어 있어요.

P1 SEO 표면. 블로그 아카이브, 필러 허브 페이지, 회사 디렉터리, 채용 브라우즈, 다섯 개 프로그래매틱 콘텐츠 인덱스(이력서 가이드, 연봉 가이드, 자기소개서 가이드, 면접 질문, ATS 키워드), 네 개 i18n 블로그 샘플, 20개 S티어 회사 허브 전체를 점검해요. 오가닉 트래픽을 유도하는 페이지들이에요. Google 회사 페이지에서 404가 나면 SEO 인시던트예요.

P2 종합. 블로그와 회사 사이트맵의 모든 URL을 점검해요. 6시간짜리 백그라운드 점검이에요. 롱테일 장애를 잡아내요. 잘못된 인용 때문에 500 에러를 내는 단일 블로그 포스트나, 대규모 회사의 N+1 쿼리로 타임아웃되는 회사 페이지 같은 것들이에요.

각 페이지는 실제 사용자와 유사한 User-Agent 헤더를 사용한 curl로 점검해요. 기본 curl은 Cloudflare에서 403을 받아요. HTTP 상태 및 TTFB와 함께 캐시 상태 헤더도 캡처해요. 페이지가 200을 반환하면서도 HIT여야 할 곳에서 DYNAMIC을 보여줄 수 있는데, 이는 캐시 규칙이 잘못 설정되었다는 뜻이에요. TTFB 측정값은 브라우저 렌더링 시간이 아니라 실제 서버 측 지연 시간이에요.

TTFB 추세

2026년 3월부터 이 점검을 실행해 왔어요. TTFB 추세는 성능의 이야기를 보여줘요:

날짜 평균 TTFB 최악의 페이지 캐시 상태
3월 21일 (캐시 퍼지 후) 1,156ms Austin market 14,290ms ALL DYNAMIC
3월 23일 (캐시 활성화) 958ms markets 2-3s Most HIT
3월 25일 (쿼리 수정) 715ms ats-optimization 6.3s All HIT
3월 27일 (안정화) 715ms zh-hans/blog 3.7s 34/36 HIT

이 추세는 마켓 페이지 성능 개선 여정을 담고 있어요. 캐시 퍼지가 문제를 드러냈고(14.3초), 엣지 캐싱이 문제를 가렸고(89-175ms HIT), 쿼리 구조 수정이 근본 원인을 해결했어요(108ms 오리진). 매일 밤의 추세 데이터가 없었다면, 엣지 캐시가 해결책이라고 믿었을 거예요. TTFB 측정값이 리밸리데이션 중에도 오리진 렌더링이 여전히 느리다는 것을 증명했고, 그래서 쿼리 리팩터링을 정당화할 수 있었어요.

nightcheck가 성능 문제를 고친 건 아니에요. 성능 문제를 측정 가능하게 만들었고, 그래서 고칠 수 있게 된 거예요.

아무도 보지 않는 것

nightcheck에서 가장 가치 있는 부분은 아무도 보지 않을 때 실행된다는 점이에요. “16,228개 페이지가 밤새 통과했습니다”라는 Slack 알림은 없어요. 녹색으로 바뀌는 대시보드도 없어요. 리포트는 로그 파일에 존재하고, 다음 날 아침 커피를 마시며 읽어요.

의식이 없다는 게 핵심이에요. nightcheck는 보여주기 위한 품질이 아니에요. 스탠드업을 위한 지표가 아니에요. 개인적인 규율이에요. 내가 자는 동안 모든 게 작동했는가? 그렇다면 좋아요. 아니라면, 정확히 무엇이 언제 실패했는지 알 수 있어요.

이 규율은 복리로 쌓여요. 매일 밤의 점검이 내일 비교를 위한 기준선을 만들어요. 특정 페이지에서 50ms의 TTFB 증가가 감지되면 조사를 시작해요. 50ms가 사용자에게 중요해서가 아니라, 증가가 무언가 변했다는 신호이기 때문이에요. 새로운 의존성이 지연을 추가했을 수도 있어요. 캐시 규칙이 만료되었을 수도 있어요. 데이터셋 증가와 함께 데이터베이스 쿼리가 느려졌을 수도 있어요. 매일 밤의 기준선이 드리프트를 문제가 되기 전에 보이게 만들어요.

이것은 복합 컨텍스트를 운영에 적용한 거예요. 매일 밤의 점검이 데이터 포인트를 축적해요. 데이터 포인트가 쌓여 추세가 돼요. 그 추세가 단일 점검으로는 절대 드러나지 않을 문제들을 보이게 만들어요.

루틴이 곧 기준이다

nightcheck를 크론 작업으로 자동화하고 대시보드만 확인할 수도 있어요. 수동으로 실행하는 이유는 실행하는 행위 자체가 관심을 기울이는 습관을 유지시키기 때문이에요. 점검이 다른 사람의 일이 되거나, 무시하는 알림이 되거나, 확인을 멈추는 대시보드가 되는 순간, 기준이 무너져요.

기준은 “사이트가 자동화된 점검을 통과한다”가 아니에요. 기준은 “내가 직접 사이트가 작동하는지 확인한 후 잠자리에 들었다”예요. 차이는 책임감이에요. 조용히 실패하는 자동화 점검은 자동화의 버그예요. 내가 건너뛴 수동 점검은 내가 무엇에 관심을 두는지에 대한 선택이에요.

매일 밤 실행하는 이유는 대안이 모든 것이 여전히 작동한다고 믿는 것이기 때문이에요. 검증 없는 신뢰는 희망이에요. 희망은 운영 전략이 아니에요.


FAQ

전체 점검은 얼마나 걸리나요?

빠른 크리티컬 패스 점검은 2-3분이 걸려요(36개 페이지의 TTFB 및 캐시 측정). 종합 사이트맵 점검은 5-7시간이 걸려요(15,000개 이상 페이지). 빠른 점검은 동기적으로 실행되고, 종합 점검은 백그라운드에서 실행돼요.

왜 업타임 모니터링 서비스를 사용하지 않나요?

업타임 서비스는 페이지가 200을 반환하는지만 확인해요. nightcheck는 페이지가 올바른 캐시 상태, 허용 가능한 TTFB, 예상되는 콘텐츠 구조와 함께 200을 반환하는지 확인해요. 200을 반환하면서 14초가 걸리고 캐시가 DYNAMIC인 페이지는 기술적으로는 살아 있지만 운영적으로는 고장 난 거예요.

실패가 발생하면 어떻게 하나요?

매출 페이지나 인프라 페이지에서 실패가 발생하면 잠들기 전에 조사해요. 종합 점검의 실패는 다음 날 아침에 로그를 검토하고 페이지 유형별로 우선순위를 매겨요. 실패한 블로그 포스트는 실패한 회사 허브보다 우선순위가 낮아요. 트래픽이 많은 페이지의 DYNAMIC 캐시가 트래픽이 적은 페이지의 느린 TTFB보다 우선순위가 높아요.

확장이 가능한가요?

현재 규모는 15,000개 페이지예요. 종합 점검은 I/O 바운드(순차적 curl 요청)이지 컴퓨트 바운드가 아니에요. 페이지 수가 두 배가 되면 실행 시간도 두 배가 돼요. 30,000개 페이지라면 점검에 12시간이 걸리는데, 이는 여전히 야간 윈도우 안에 들어와요. 그 이상이 되면 레이트 리미팅을 적용한 병렬 점검이 필요할 거예요.

관련 게시물

품질만이 유일한 변수입니다

시간, 비용, 자원, 노력은 제약 조건이 아닙니다. 핵심 질문은 '무엇이 효율적인가'가 아니라 '무엇이 올바른가'입니다. AI 에이전트와 함께 구축하기 위한 철학.

4 분 소요

한밤의 크롤링

자정부터 오전 6시 사이에 Googlebot은 21,000페이지를, Bingbot은 10,000페이지를 크롤링하고, 종합 점검은 15,000페이지를 처리해요. 이 사이트는 오후 3시보다 새벽 3시에 더 활발하게 움직…

4 분 소요

AI 에이전트는 당신이 읽을 수 있는 것보다 빠르게 코드를 작성합니다

이번 주 다섯 개의 연구 그룹이 동일한 문제에 대해 발표했습니다: AI 에이전트는 개발자가 이해할 수 있는 것보다 빠르게 코드를 생산합니다. 부채는 당신의 머릿속에 있습니다.

15 분 소요