n8n에서 실행 기록을 90일 동안 보관하자 데이터베이스가 38GB에 도달했습니다
요약
n8n에서 LLM 워크플로우를 운영하며 실행 기록(execution history) 때문에 데이터베이스 용량이 급증하는 문제를 겪었습니다. 이 글은 n8n의 과도한 로깅과 바이너리 블롭 저장으로 인해 발생한 DB 부하 해결책을 제시합니다. 핵심적으로, 성공 기록 보존 최소화와 명시적인 데이터 정리 정책(pruning) 설정을 통해 용량을 효율적으로 관리하는 방법을 설명합니다.
핵심 포인트
- 성공 실행 기록의 페이로드는 디버깅 가치가 낮으므로 저장 범위를 실패한 기록으로 제한하세요.
- n8n의 데이터 정리 설정(`EXECUTIONS_DATA_PRUNE`)을 활용하여 성공/실패 기록 보존 기간을 명시적으로 지정해야 합니다.
- 데이터베이스 크기 모니터링용 메타 워크플로우를 구축하여 용량 초과 시 경고 시스템을 구현하는 것이 좋습니다.
n8n에서 실행 기록을 90일 동안 보관하자 데이터베이스가 38 GB
프로덕션 환경에서 n8n으로 LLM 워크플로우를 운영하는 '내 공개 빌드(build-in-public)' 시리즈의 일부입니다. 이번 주 사건은 다음과 같습니다: 제가 자체 호스팅한 n8n이 실행 목록을 불러오는 데 20초가 걸리기 시작했고, 디스크 사용량 그래프는 방 건너편에서도 기울기가 보일 정도였습니다.
실행 목록 로딩이 멈춘 아침
실패한 실행(failed run)을 디버깅하던 중 알아차렸습니다. 'Executions'를 클릭했는데 페이지가 그냥 멈춰 있었습니다. 무언가를 렌더링하기까지 스피너만 20초 동안 돌아갔습니다. 그리고 디스크를 확인해 보니: n8n 인스턴스 뒤에 있는 Postgres 볼륨이 38 GB에 도달했으며, 지난 한 달 동안만 약 4 GB가 증가했습니다.
원인은 사용자 데이터가 아니었습니다. 실행 기록(execution history) 때문이었습니다. n8n의 기본 설정은 모든 것을 보관하는 것입니다—모든 실행, 모든 노드의 입력 및 출력, 파일을 건드린 경우 전체 바이너리 블롭까지 포함합니다—그리고 저는 기본 설정을 단 한 번도 변경한 적이 없었습니다. 12개 워크플로우에 걸친 60일간의 크론 스케줄(cron schedules)이 각각 자신의 전체 페이로드, 심지어 큰 파일들까지 성실하게 아카이브하고 있었습니다.
가장 쓰라렸던 부분은 이것입니다: 저는 프루닝 설정(pruning settings)에 대해 알고 있었습니다. 몇 달 전에 문서에서 그것들을 봤었고
바이너리 데이터가 더 문제입니다. 이미지를 다운로드하거나 PDF 파일을 처리하는 워크플로우는 n8n에게 디스크에 저장하도록 지시하지 않는 한, 해당 블롭(blob)을 인라인으로 유지합니다. 저는 콘텐츠 파이프라인을 위해 제품 이미지를 가져오는 워크플로우를 가지고 있었는데, 실행할 때마다 모든 이미지가 보관되었고, Postgres가 이를 용서해주지 않았습니다.
세 단계로 해결하기
레벨 1: 불필요한 것은 저장하지 않기 (10분). n8n의 실행 설정에서는 워크플로우별로 무엇을 영구 보존할지 선택할 수 있습니다. 성공적인 실행 기록, 실패한 실행 기록, 또는 아무것도 저장하지 않을 수 있습니다. 저처럼 빈번하게 실행되고 위험도가 낮은 워크플로우(99%의 시간 동안 성공하는)의 경우, 저는 실패한 실행 기록만 저장하도록 변경했습니다. 성공적으로 완료된 실행의 전체 페이로드(payload)가 가진 디버깅 가치는 거의 0에 가깝습니다. 제가 실제로 열어보는 것은 실패한 기록들입니다. 이 한 가지 변화만으로 하룻밤 사이에 신규 데이터 증가량을 약 80% 절감할 수 있었습니다.
레벨 2: 희망이 아닌 일정에 따라 정리하기. 여전히 기록을 유지하고 싶은 워크플로우(LLM 관련, 때때로 프롬프트 동작을 감사하는 경우)의 경우, 명시적인 정리를 설정했습니다. 성공한 실행은 14일 동안 보관하고, 실패한 실행은 90일 동안 보관하도록 했습니다. n8n의 데이터 정리 설정(EXECUTIONS_DATA_PRUNE=true, 최대 기간 및 간격 지정)이 이를 자동으로 처리해줍니다. 제가 별도로 크론 작업(cron job)을 만들 필요가 없습니다. 오래된 성공 기록들은 조용히 사라지고, 실패한 기록들만 사후 분석(post-mortem)에 충분할 만큼 오랫동안 남아있습니다.
레벨 3: 디스크를 놀라움이 아닌 측정 지표로 다루기. 저는 작은 메타 워크플로우—아이러니하지만요—를 추가하여 매일 데이터베이스 크기를 확인하도록 했습니다. 만약 크기가 임계값을 초과하면, 저에게 메시지를 보냅니다. 이제 저장 공간은 밤 11시에 디버깅 세션 중에 발견하는 것이 아니라, _경고_를 받는 대상이 되었습니다. 전체 시스템은 하나의 Postgres 노드와 IF 노드로 구성되어 있습니다. 구축하는 데 15분이 걸렸지만, 눈에 보이지 않던 것을 보이게 만들면서 이미 그 비용을 회수했습니다.
솔직한 수치들
이전: 38GB, 월 약 4GB 증가, 실행 목록 로딩에 20초 이상 소요. 세 단계 정책을 적용한 후 6주 차: 6.2GB, 주간 변화 없음, 실행 목록은 2초 이내 로드. 제가 유지했던 90일 실패 기록 덕분에 여전히 조사하고 싶은 모든 사고(incident)를 가지고 있습니다. 단지 아무도 열어보지 않을 수천 건의 성공적인 실행 기록을 아카이브하는 것을 중단했을 뿐입니다.
불편한 진실은 이겁니다. 저는 90일간의 성공적인 실행 기록이 필요했던 것이 아닙니다. 제가 필요했던 것은 90일간의 실패 기록과 약 2주간의 성공 기록 정도였습니다. 기본 설정 자체가 틀린 것은 아니지만, '절대 아무것도 잃지 않는다'는 것에만 최적화되어 있어서 데이터에는 훌륭하지만 데이터베이스에는 치명적인 것입니다.
한 줄 규칙
성공적인 실행은 자산이 아니라 로그입니다. 실패 기록은 길게 보관하고, 성공 기록은 짧게 보관하며, 디스크 사용량을 스스로가 알려주기 전에 매일 대시보드에 표시하세요.
만약 n8n을 직접 호스팅(self-hosting)하고 있다면, 지금 바로 실행 설정을 확인해 보세요. 적어도 하나의 워크플로우는 여전히 '모두 저장' 상태로 되어 있을 것이고 — 당신의 디스크가 그것을 알고 있습니다.
저는 AI Automation Lab을 구축하고 있습니다. 프로덕션 레디 n8n 워크플로우 템플릿입니다. 무료 AI Hook Generator가 대부분의 사람들이 시작하는 곳이며, AI Inbox Triage & Reply Drafter는 제가 이 프로덕션 레슨을 가장 많이 배운 유료 워크플로우입니다. 제 오픈 소스 패턴은 github.com/zhp910318/n8n-ai-automation-lab에서 확인하실 수 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기