> For the complete documentation index, see [llms.txt](https://wonjoon.gitbook.io/joons-til/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wonjoon.gitbook.io/joons-til/automation/why-fetchresults-is-deprecated.md).

# what is n8n

## n8n 이란?

nodemation을 줄인 표현입니다.

#### 왜 node가 핵심 설계 단위인가?

워크 플로우를 노드 그래프(DAG에 가까운 형태)로 모델링합니다. \
이로써 조합/재사용/확장(커스텀 노드)이 쉬워집니다.

#### 코드 기반 파이프라인에 비해 갖는 구조적 트레이드 오프는?

* 장점: 가시성/운영편의/비개발자 협업
* 단점:
  * 복잡한 조건/추상화는 코드(컴스텀 함수/스크립트 노드)로 다시 내려가야합니다.
  * 그래프가 커질수록 텟그트/버전관리/리뷰 전략이 중요

## 많은 자동화 도구 중 n8n의 장점은?

* 셀프호스팅/배포 유연성: 데이터/크리덴셜을 내부에 두고 운영하기 쉽고, 필요하면 확장도 가능합니다.
* 큐 기반 확장: 메인 프로세스와 워크플로 실행을 분리해, 워커를 여러 대 붙여 처리량을 늘릴 수 있습니다.
* 노드 생태계 + 커스텀: 트리거/액션/로직 노드 조합으로 "통합 파이프라인"을 빠르게 만들고, 부족하면 커스텀 노드/코드로 보완하는 방향이 일반적입니다.
* 웹훅을 API 엔드포인트처럼: Webhook 노드는 외부 요청으로 워크플로를 시작하는 트리거이고, 응답 반환 방식도 제공해 "간단한 백엔드 엔드포인트" 처럼 쓸 수 있습니다.

#### Zapier/Make 같은 SaaS 자동화와 비교해 n8n의 본질적 차이는?

* 셀프호스트
* 확장성(큐/워커)
* 커스터마이징(코드/노드 개발)
* 운영(모니터링/장애대응)까지 사용자의 책임

#### 큐 모드로 스케일할 때 생기는 운영 이슈(중복 실행, 순서 보장, 재시도, 멱등성)을 어떻게 다루고 있나요?

* 워크플로 설계를 "멱등"하게
* 외부 API 호출은 재시도/백오프/서킷브레이커 관점
* 순서가 필요한 작업은 키 기반 직렬화/락/단일 워커 전략 고민

## n8n은 기존 백엔드 서버와 비교해 아키텍처 관점에서 뭐가 다른가요?

**전통 백엔드 서버:**

* 요청 라우팅(HTTP)
* 비즈니스 로직
* 데이터 저장
* 비동기 작업 큐
* 스케줄러 등 개발자가 직접 조립.

n8n:

* 서버 프레임워크가 아닌 워크플로 실행/오케스트레이션 플랫폼에 가깝습니다
* 로직이 코드 팔일이 아니라 워크플로(노드 그래프)로 저장/실행됩니다.
* 트리거(웹훅/스케줄/이벤트)로 시작된 실행이 실행 기록/상태와 함께 관리되는 쪽에 초점이 있습니다.

특히 큐 모드에서는 구성요소가 더 "분산 시스템"처럼 나뉩니다.

* 메인(UI/API, 트리거/스케줄) <-> Redis 큐 <-> 워커(실행) <-> DB(상태 기록)

#### n8n을 백엔드 대체로 쓰면 안되는/조심해야하는 경계는 어디인가요?

복잡한 도메인 로직/트랜잭션/고성능 API는 전통 백엔드가 유리합니다.\
n8n은 통합/자동화/오케스트레이션에 강합니다.

#### Webhook 노드로 API처럼 쓸 때, 성능/보안/버전관리 이슈를 어떻게 설계하나요?

<figure><img src="/files/2nEDlIEDE31kHN6oUr8P" alt=""><figcaption></figcaption></figure>

핵심 포인트:

* 인증(서명검증/토큰), rate limit, 입력 검증
* 테스트 URL/프로덕션 URL 분리 운영
* 워크플로 변경이 곧 API 변경 -> 버전 분기(워크플로 버전/별도 엔드포인트) 전략 필요

## n8n은 어떤 "엔진"으로 구성되고 각 역할은?

1. Main(웹 앱/오케스트레이션): UI(에디터) + API + 트리거 등록/스케줄 관리, 실행을 직접 하거나(단일 모드) 큐에(큐 모드) 넣습니다.
2. Worker(실행 엔진): 큐에서 Job을 가져와 노드들을 순서대로 실행하고 결과/상태를 저장.
3. Webhook 처리(웹훅 엔드포인트): Webhook 트리거 요청을 받아 워크플로 실행을 시작하거나, 워크플로 결과를 HTTP 응답으로 반환.
4. DB(상태/메타데이터 저장): 워크플로 정의, 크리덴셜 메타, 실행 이력/상태 등을 영속화. (DB+Redis 조합을 전제로 설명)
5. Redis(큐/브로커): 큐 모드에서 실행을 분산하기 위한 브로커.
6. Task Runner(작업 실행 격리): n8n 작업을 내부/외부 러너로 실행할 수 있게 하는 구성. 운영 환경에서는 격리를 보장(보안/안정성 관점)

#### 단일 모드 vs 큐 모드 차이와, 언제 큐 모드로 가야하나?

동시 실행/처리량/장애 격리/스케일 아웃 필요 시 큐 모드.

#### 워커를 늘렸을 떄도 "같은 워크플로가 중복으로 실행"될 수 있는 조건과 방지 전략

트리거 중복(웹훅 재전송, 스케줄 겹침), 재시도를\
멱등키/디듀프 저장소/락/외부 시스템의 idempotency key 활

## workflows, trigger, node는 무엇이고 어떤 역할인가요?

<figure><img src="/files/1xZ31Z9DE6zO0LLK470n" alt=""><figcaption></figcaption></figure>

* workflow: 자동화의 "설계도". 노드들의 연결 그래프
* trigger node: 워크플로의 시작점. 이벤트 조건이 만족되면 실행을 시작
  * 예: webhook 노드는 외부 HTTP 요청으로 시작
  * 예: manual trigger는 테스트용 수동 실행 시작점
  * (참고: 예전 workflow trigger는 deprecated 되고 기능이 n8n trigger로 옮겨짐)
* node: 한 단계의 작업 단위(외부 API호출, 데이터 변환, 조건 분기, DB 쓰기 등). 입력 데이터를 받아 처리하고 다음 노드로 넘김

#### 트리거가 "상시 대기(listen)하는 방식과 폴링(polling) 방식의 차이는?

* 웹훅 = 푸시/이벤트 기반
* 폴링 = 주시적으로 조회(지연/비용/부하 trade-off)

#### 노드 간 데이터 전달에서 스키마/형식 문제를 어떻게 관리하나?

노드 출력 형태(JSON/바이너리), 변환 노드로 정규화, 필드 누락 방어, 에러 분기(try/catch 패턴), 테스트 데이터 고정

#### 실행/장애/재시도 설계

<figure><img src="/files/gAh0MUDNWIOsQnOinRpZ" alt=""><figcaption></figcaption></figure>

* 자동화는 성공보다는 실패 경로가 더 중요합니다. 재시도 정책, 중복 실행 대비, 부분 실패 처리, DLQ 유사 운영, 알림/모니터링
* 큐 모드에서의 분산 실행 흐름을 말로 그릴 수 있어야 함.

#### 실패한 실행을 재처리할 때 데이터 일관성은 어떻게 보장하나?

**재처리는 중복 실행을 전체로 하므로, 이벤트 ID 기반 멱등키 + 상태머신(단계별 커밋) + 필요시 보상 트랜잭션**

핵심은 “재처리는 결국 **중복 실행**을 전제로 하므로, 시스템을 **멱등(idempotent)** 하게 설계”하는 겁니다.

1. **멱등 키(디듀프 키)로 ‘같은 작업’ 재실행을 흡수**

* 외부에서 들어오는 이벤트에 고유 ID(예: webhook event\_id, message\_id)가 있으면 그걸 **idempotency key**로 씁니다.
* 처리 전에 DB/캐시에 `processed_events(event_id)` 같은 테이블/키를 조회하고, 이미 있으면 **바로 종료(또는 이전 결과 반환)**.
* 없다면 **먼저 “처리 시작 기록”을 저장**(가능하면 유니크 제약) → 그 다음 실제 side-effect(결제, 발송, 티켓 생성 등)를 실행.

2. **side-effect를 “원자적 커밋”처럼 다루기 (Outbox / Saga 관점)**

* “DB 업데이트 + 외부 API 호출” 같이 **2개의 시스템**이 엮이면 트랜잭션이 끊깁니다.
* 그래서 현실적 해법은:
  * DB에 상태를 먼저 기록(예: `PENDING`) → 외부 호출 성공 시 `DONE`으로 전이
  * 또는 Outbox 패턴처럼 “보낼 메시지/요청”을 DB에 먼저 적재하고, 별도 흐름이 전송 후 `SENT`로 마킹

3. **부분 실패(Partial failure)를 상태 머신으로 모델링**

* 실행은 한 번에 “올 성공”이 아니라 단계별 실패가 납니다.
* 각 단계(예: “주문 생성 → 결제 승인 → 영수증 발송”)를 상태로 나누고,
  * 재시도는 **마지막 성공 단계 이후부터** 재개하도록(= 재처리 범위를 최소화)
  * 실패 시에는 **보상(취소/롤백 API)** 또는 **수동 검증 큐(사람이 보는 큐)** 로 보냄

4. **n8n 큐 모드에서 특히 중요한 포인트**

* 큐 모드는 메인/워커가 분리되고(메인은 오케스트레이션, 워커는 실행), Redis 큐를 통해 작업이 분산됩니다. 즉, **재시도/재전송/워커 장애**로 “같은 입력이 다시 실행”될 수 있다는 전제가 강해집니다.\
  → 그래서 위의 멱등/상태기반 설계가 사실상 필수입니다.

#### 외부 API rate limit/timeout이 잦을 때, 워크플로 레벨에서 어떤 패턴을 쓰나요?

<figure><img src="/files/viCw3u4tiZqB5MZKEyMp" alt=""><figcaption></figcaption></figure>

실무에서는 “**호출을 줄이고(최적화)**, **망가져도 버티고(회복탄력성)**, **다시 돌려도 안전(멱등)**” 3축으로 갑니다.

1. **백오프 + 지터(jitter)**

* 429(Too Many Requests), 5xx, timeout은 즉시 재시도하면 더 악화됩니다.
* **지수 백오프(예: 1s→2s→4s…) + 랜덤 지터**로 “동시 재시도 폭주”를 피합니다.

2. **레이트리밋 친화적 설계(스로틀/동시성 제한)**

* 한 번에 병렬로 많이 때리면 rate limit에 바로 걸립니다.
* 워크플로에서 **동시 호출 수를 제한**하거나, 큐에 넣고 **워커 수/동시 실행량**을 조절합니다(큐 모드 자체가 운영적 스로틀 도구가 됨).

3. **벌크화(Batching)**

* “N번 호출”을 “1번 벌크 호출”로 바꿀 수 있으면 가장 강력합니다.
* 예: CRM 레코드 200개 업데이트 → 개별 PATCH 200번 대신 batch endpoint 1\~2번.

4. **캐시 / 조건부 요청**

* 동일한 조회를 반복하면 rate limit을 소모합니다.
* 캐시(짧은 TTL이라도) + ETag/If-Modified-Since 같은 조건부 요청이 가능하면 적극 사용.

5. **서킷 브레이커 + 폴백**

* timeout이 연속으로 나면 **일정 시간 호출을 끊고(open)**, 빠르게 실패시키거나 대체 경로(캐시 값, “나중에 처리”)로 폴백합니다.
* 자동화는 “지금 실패해도 나중에 처리”가 가능한 일이 많아서, **DLQ 유사 큐로 보내고 알림**이 잘 맞습니다.

#### 자동화 플랫폼에서 권한분리를 어떻게 설계하나요?

원칙은 “**편집 권한**과 **비밀(크리덴셜) 접근 권한**을 분리”하고, 자동화 실행은 “최소권한”으로 제한하는 겁니다.

1. **RBAC(역할 기반)로 최소권한**

* 역할 예시:
  * Viewer: 실행 결과만 보기
  * Editor: 워크플로 편집 가능
  * Operator: 재실행/중지/롤백 운영 권한
  * Admin/Security: 크리덴셜/환경변수 관리
* 특히 “Editor가 크리덴셜을 평문으로 볼 수 있다”면 내부자 위협이 커집니다.

2. **크리덴셜은 ‘참조’만 하게**

* 워크플로는 크리덴셜을 “선택/참조”만 하고, 값 자체는 숨김.
* 교체/회전(rotate)은 보안 담당자가 하고, 워크플로는 동일 참조를 유지.

3. **실행 격리(코드 실행이 특히 위험)**

* n8n은 Code node에서 사용자 JS/Python 실행이 가능하고, 이를 안전/성능 목적으로 task runner로 분리할 수 있습니다.
* 공식 문서도 내부 모드는 프로덕션에서 보안 리스크가 될 수 있어 **외부 모드로 격리**를 권장합니다.\
  → 즉, “워크플로 편집 가능자”가 곧 “서버 내부에서 코드 실행 가능자”가 될 수 있으니, **격리 + 권한 통제**가 같이 가야 합니다.

#### 공통 로직을 어떻게 재사용하나요? (서브워크플로, 템플릿화)

n8n에서는 큰 워크플로를 쪼개서 **서브워크플로로 호출**하는 패턴이 대표적입니다. 공식 문서도 “다른 워크플로를 호출해 재사용하고 큰 워크플로를 작은 구성요소로 분해”하라고 안내합니다.

실무 패턴:

1. **서브워크플로(공통 함수처럼)**

* 공통 로직(예: “고객 정규화”, “권한 체크”, “Slack 알림 포맷”)을 별도 워크플로로 분리
* 시작 노드는 **Execute Sub-workflow Trigger**(다른 워크플로가 호출할 때 시작)
* 호출 측은 “execute workflow/서브워크플로 실행” 노드로 호출

2. **입력/출력 계약(Contract) 정의**

* 서브워크플로는 입력 필드/출력 형태를 명확히 고정(= 함수 시그니처)
* “호출자마다 조금씩 다른 데이터”는 앞단에서 정규화해서 넣고, 서브워크플로 내부는 단순/일관 유지

3. **템플릿/표준 스캐폴딩**

* 신규 자동화가 생길 때 공통 뼈대(로깅/알림/에러 라우팅)를 템플릿처럼 복제해 시작

#### 재사용이 많아질 때 버전 호환성/변경 영향도는 어떻게 통제하나요?

재사용이 늘면 “한 번 고치면 전부 깨지는” 상황이 옵니다. 그래서 아래 4가지를 같이 합니다.

1. **버전 분리(깨는 변경은 새 워크플로로)**

* Breaking change가 있으면 기존 서브워크플로를 덮어쓰지 말고 `subwf_v2`처럼 새 버전으로 만들고,
* 호출자들을 단계적으로 마이그레이션(= 단계적 배포).

2. **계약 테스트(Contract test)**

* 서브워크플로의 입력/출력 샘플을 고정해, 변경 시에도 동일 계약을 만족하는지 테스트.
* 특히 “필드명/타입/빈 값 처리”가 자주 깨짐 포인트라 여기부터 테스트합니다.

3. **점진 롤아웃(카나리)**

* 일부 호출자만 v2로 전환해 관측하고(에러율/지연/외부 API 실패율),
* 안정화되면 확장.

4. **관측성(Observability)으로 변경 영향 추적**

* 서브워크플로 호출을 공통 로깅/메트릭으로 남기면, 버전별 에러율 비교가 쉬워집니다.
