Automation – Tự động hóa quy trình Lập trình No Code/Low Code

Lỗi n8n self-hosted bị treo, bỏ lỡ trigger? Hướng dẫn toàn diện về Queue Mode để mở rộng hệ thống bền vững

Cuộn để đọc

Chào các bạn! Hôm nay Toàn muốn chia sẻ về một vấn đề mà rất nhiều người dùng n8n self-hosted đều gặp phải – và thẳng thắn mà nói, chính Toàn cũng từng đau đầu với nó khi mới bắt đầu.

📑Mục lục

Câu chuyện thường diễn ra như thế này: Các bạn thuê một VPS, cài n8n bằng Docker đơn giản, chạy lệnh docker run và boom – một hệ thống tự động hóa tuyệt vời ra đời. Ban đầu, mọi thứ đẹp như mơ. Vài workflow cá nhân chạy ngon lành, tự động hóa được một số công việc lặp đi lặp lại – perfect!

Nhưng rồi các bạn bắt đầu thêm nhiều workflow hơn. Đặc biệt là các workflow chạy theo lịch trình – tạo báo cáo hàng ngày, đồng bộ dữ liệu khách hàng, gửi email marketing định kỳ. Và đây là lúc những “dấu hiệu đáng lo” bắt đầu xuất hiện.

Giao diện n8n đột nhiên chậm như sên bò. Có lúc treo hẳn luôn, các bạn không vào được nữa. Workflow thì báo lỗi mà không hiểu tại sao. Nhưng điều kinh khủng nhất mà Toàn thấy nhiều doanh nghiệp gặp phải: các workflow hẹn giờ bắt đầu “miss” – chạy sai giờ hoặc không chạy luôn, mà chẳng có thông báo lỗi gì cả. Silent failure – kiểu lỗi nguy hiểm nhất đó các bạn.

Với vai trò là n8n Verified Creator, hôm nay, Toàn sẽ hướng dẫn các bạn chi tiết cách chuyển từ kiến trúc mặc định (dễ bị tắc nghẽn) sang Queue Mode – kiến trúc production thực sự mà các hệ thống lớn đang dùng. Không phải lý thuyết suông đâu nhé, mà là những gì Toàn đang áp dụng thực tế mỗi ngày.

[nguyenthieutoan.com] Biểu đồ thể hiện hiệu suất của n8n giảm dần khi tăng số lượng workflow ở chế độ mặc định, đường màu đỏ thể hiện hiệu suất giảm mạnh sau ngưỡng 20 workflows trong khi đường màu xanh của Queue Mode vẫn duy trì ổn định ngay cả với 100+ workflows

I. VẤN ĐỀ CỐT LÕI: TẠI SAO N8N “NGẤT” KHI CÁC BẠN MỞ RỘNG?

OK, trước khi Toàn hướng dẫn các bạn fix, mình cần hiểu rõ vấn đề đã. Không phải n8n yếu hay gì đâu, mà là cách setup mặc định không được thiết kế cho quy mô lớn. Giống như các bạn mua xe máy để đi trong phố, nhưng lại đòi nó chở 5 người đi xuyên Việt vậy.

1. Kiến trúc mặc định: Một người làm hết mọi việc

Khi các bạn cài n8n theo cách thông thường (gọi là Main Mode), toàn bộ hệ thống chạy trong một tiến trình duy nhất. Điều này có nghĩa là một “nhân viên” phải gánh hết mọi việc:

  • Chạy giao diện web: Phục vụ trang để các bạn vào tạo workflow
  • Xử lý API: Nhận các lệnh tạo, sửa, xóa workflow và credentials
  • Lắng nghe triggers: Theo dõi webhook, cron schedule liên tục
  • Chạy tất cả workflows: Thực thi mọi workflow đang hoạt động

Toàn hay ví von nó giống một quán cơm chỉ có một người phục vụ. Người đó phải: đón khách, nhận order, vào bếp nấu, mang đồ ăn ra, và dọn bàn. Khi chỉ có 3-4 bàn khách thì OK. Nhưng khi quán đông 20-30 bàn, chuyện gì sẽ xảy ra? Đúng rồi – thảm họa toàn tập!

Khách chờ mãi không thấy đồ ăn, món bị trễ, người phục vụ kiệt sức. n8n cũng vậy đó các bạn. Một tiến trình không thể gánh nổi mọi thứ khi hệ thống lớn lên.

[nguyenthieutoan.com] Sơ đồ minh họa kiến trúc n8n Main Mode với một tiến trình duy nhất n8n process ở giữa được kết nối với database SQLite hoặc PostgreSQL, xung quanh là các icons thể hiện các chức năng UI Editor, API Handler, Trigger Listener và Workflow Execution đều chạy trong cùng một tiến trình duy nhất này tạo ra điểm nghẽn

2. Ba “điểm nghẽn” gây sụp đổ hệ thống

Khi hệ thống phải xử lý ngày càng nhiều việc, ba vấn đề nghiêm trọng sẽ xuất hiện. Toàn sẽ giải thích chi tiết để các bạn hiểu rõ nhé.

Cạn kiệt tài nguyên (CPU và RAM)

Mỗi workflow tốn một lượng CPU và RAM nhất định. Workflow xử lý file CSV 5000 dòng? RAM bay mất vài trăm MB. Workflow có logic phức tạp với nhiều nodes? CPU phải làm việc cật lực. Khi 10-20 workflows như vậy chạy cùng lúc trong cùng một tiến trình, chúng “giành giật” tài nguyên với nhau như đám người chen lấn lên xe bus.

Kết quả các bạn sẽ thấy gì? Hệ thống chậm dần, rồi đơ hẳn. Trong trường hợp tệ nhất, hệ điều hành sẽ “giết chết” luôn tiến trình n8n để giải phóng RAM (cái này gọi là OOM Killer). Lúc đó toàn bộ n8n restart, mọi workflow đang chạy dở đều bị dừng giữa chừng.

Toàn có một khách hàng từng gặp đúng tình huống này. Họ chạy 30 workflows, trong đó có mấy cái xử lý ảnh và video. Cứ 2-3 ngày lại thấy n8n tự restart một cái. Check logs mới thấy OOM Killer đã “hạ sát” nó. Khổ nỗi là không có cảnh báo gì trước đó cả.

[nguyenthieutoan.com] Biểu đồ minh họa việc sử dụng CPU và RAM của n8n tăng vọt khi có nhiều workflows chạy đồng thời trong chế độ Main Mode, đường màu đỏ thể hiện mức sử dụng RAM vượt quá 90% và đường màu cam thể hiện CPU usage đạt 100%, dẫn đến cảnh báo Out of Memory với icon nguy hiểm

Một điểm chết duy nhất (Single Point of Failure)

Vì mọi thứ đều chạy trong một tiến trình, nếu nó chết thì tất cả chết theo. Một lỗi trong MỘT workflow có thể kéo theo cả hệ thống sụp đổ. Các bạn tưởng tượng nhé:

  • Giao diện web không vào được → không thể sửa workflow
  • Webhook bị từ chối → khách hàng không gửi được data vào hệ thống
  • Tất cả workflows đang chạy bị dừng đột ngột
  • Các lịch trình bị bỏ lỡ hoàn toàn

Và đây là điều đáng sợ nhất: Các bạn chỉ biết khi có người phàn nàn hoặc lúc tình cờ check system. Không có email cảnh báo, không có gì cả. Silent death!

Vấn đề “missed cron” – Im lặng và nguy hiểm nhất

Đây là vấn đề mà Toàn thấy các doanh nghiệp gặp nhiều nhất, và cũng là lý do chính khiến họ liên hệ với GenStaff để fix. Để Toàn kể các bạn nghe một case study thực tế nhé.

Trong kiến trúc mặc định, workflows được thực thi tuần tự hoặc bán song song. Hãy xem tình huống này:

  1. Workflow A (tạo báo cáo doanh thu) được hẹn chạy lúc 23:00 mỗi ngày. Workflow này nặng, cần xử lý data từ nhiều nguồn, mất khoảng 15 phút.
  2. Workflow B (đồng bộ dữ liệu khách hàng vào CRM) được hẹn chạy lúc 23:05.
  3. Vì Workflow A đang “chiếm dụng” toàn bộ tiến trình, Workflow B phải xếp hàng chờ đợi.
  4. Đến 23:15 khi A mới chạy xong, thời điểm trigger của B (23:05) đã qua rồi.
  5. n8n không có cơ chế “catch-up” để chạy lại các cron job bị lỡ → Workflow B bị bỏ qua hoàn toàn!

Điều đáng sợ? Không có cảnh báo nào cả. Logs không ghi gì, UI không báo lỗi. Các bạn chỉ phát hiện khi:

  • Sales team phàn nàn data CRM bị thiếu
  • Tình cờ vào xem execution history và thấy có ngày không chạy
  • Khách hàng phàn nàn không nhận được email tự động

Toàn có một khách hàng trong lĩnh vực F&B. Họ có workflow tự động gửi báo cáo doanh thu cho các chi nhánh mỗi sáng 7:00. Hệ thống miss hẳn 2 tuần không ai biết, cho đến khi một giám đốc chi nhánh hỏi sao lâu không nhận được báo cáo. May là không phải dữ liệu tài chính nhạy cảm, nhưng cũng đủ để họ mất niềm tin vào automation rồi.

[nguyenthieutoan.com] Sơ đồ timeline minh họa vấn đề missed cron trong n8n Main Mode, thể hiện Workflow A chạy từ 23:00 đến 23:15 chiếm dụng toàn bộ tiến trình được biểu thị bằng thanh màu đỏ, trong khi Workflow B có trigger ở 23:05 nhưng không thể chạy được và bị skip hoàn toàn, được đánh dấu bằng dấu X màu đỏ với chú thích Silent Failure No Error Log

II. GIẢI PHÁP TOÀN DIỆN: QUEUE MODE LÀ GÌ VÀ TẠI SAO NÓ QUAN TRỌNG?

OK, sau khi hiểu rõ vấn đề, giờ Toàn sẽ giới thiệu các bạn giải pháp: Queue Mode. Đây không phải chỉ là một setting nhỏ, mà là một sự thay đổi kiến trúc toàn diện, biến n8n từ công cụ cá nhân thành nền tảng enterprise có thể mở rộng.

Xem thêm về automation và AI trong doanh nghiệp tại: Hướng dẫn toàn tập AI Agent trong n8n

1. Queue Mode hoạt động thế nào?

Thay vì một người làm hết mọi việc, Queue Mode chia công việc thành các vai trò chuyên biệt – như một nhà hàng tổ chức bài bản:

  • n8n-main: Như người đón tiếp và quản lý. Chỉ lo về UI, API và triggers. Khi có workflow cần chạy, nó tạo một “job” (đơn hàng) và đẩy vào hàng đợi.
  • n8n-workers (nhiều workers): Như các đầu bếp trong bếp. Mỗi worker là một tiến trình độc lập, chỉ làm việc duy nhất là “nhặt” job từ hàng đợi rồi thực thi. Các bạn có thể có 2, 5, 10 workers tùy thích!
  • Redis: Như bảng order trong bếp. Đây là hệ thống message queue – main process đẩy job vào đây, workers lấy job ra để làm.
  • PostgreSQL: Cơ sở dữ liệu chính (bắt buộc phải dùng PostgreSQL, không dùng SQLite được nữa).

Quay lại ví dụ quán cơm: bây giờ các bạn có người đón khách riêng (main), nhiều đầu bếp trong bếp (workers), và một hệ thống order rõ ràng (Redis). Mỗi người làm việc của mình, không ai “nghẹt thở”, khách hàng được phục vụ nhanh chóng và ổn định.

[nguyenthieutoan.com] Sơ đồ kiến trúc n8n Queue Mode với các thành phần được tách biệt rõ ràng bao gồm n8n-main container xử lý UI API và Triggers ở trên cùng, Redis message queue ở giữa được biểu thị bằng hình hộp màu xanh với các job đang xếp hàng, ba n8n-worker containers ở dưới cùng cùng xử lý các jobs song song được nối với PostgreSQL database, các mũi tên chỉ luồng dữ liệu từ main xuống Redis rồi phân phối đến các workers

2. So sánh cụ thể: Main Mode vs Queue Mode

Để các bạn dễ hình dung hơn, Toàn làm một bảng so sánh chi tiết này:

Tiêu chí Main Mode (mặc định) Queue Mode (production)
Cách hoạt động Một tiến trình đơn lẻ làm hết mọi việc Chia nhỏ công việc ra nhiều tiến trình chuyên biệt
Các thành phần • n8n process (làm tất cả)
– Database (SQLite hoặc PostgreSQL)
• n8n-main (UI, API, Trigger)
– Nhiều n8n-workers (thực thi)
– Redis (message queue)
– PostgreSQL (database)
Xử lý đồng thời Rất hạn chế, dễ bị tắc nghẽn khi có nhiều workflow Cao, có thể xử lý hàng trăm workflows cùng lúc
Khả năng mở rộng Chỉ nâng cấp CPU/RAM máy chủ (vertical scaling – có giới hạn vật lý) Thêm workers dễ dàng (horizontal scaling – gần như không giới hạn)
Độ tin cậy Thấp. Một lỗi → toàn bộ hệ thống sập Cao. Worker chết → workers khác vẫn xử lý tiếp
Vấn đề missed cron Xảy ra thường xuyên khi hệ thống bận Không xảy ra vì jobs được xếp hàng và xử lý đầy đủ
Độ phức tạp setup Đơn giản, 1 lệnh docker run là xong Phức tạp hơn, cần setup nhiều containers
Chi phí vận hành Thấp ban đầu (1 VPS cơ bản) Cao hơn (cần VPS mạnh hơn), nhưng xứng đáng
Phù hợp cho • Thử nghiệm cá nhân
– Workflows đơn giản, không quan trọng
– Development environment
• Production environment
Hệ thống business-critical
– Workflows quan trọng cần độ tin cậy cao

Các bạn thấy đó, sự khác biệt rất lớn. Nếu hệ thống n8n của các bạn đang phục vụ cho business thực sự (không phải chỉ test chơi), thì Queue Mode là điều bắt buộc, không phải optional nhé!

[nguyenthieutoan.com] So sánh trực quan giữa Main Mode và Queue Mode với hai sơ đồ song song, bên trái hiển thị Main Mode với một tiến trình duy nhất bị quá tải được biểu thị bằng màu đỏ và biểu tượng cảnh báo overload, bên phải hiển thị Queue Mode với nhiều workers phân tán màu xanh lá cây hoạt động song song qua Redis queue ở giữa, có mũi tên thể hiện luồng công việc được phân bổ đều đặn

III. HƯỚNG DẪN TRIỂN KHAI QUEUE MODE CHI TIẾT (TỪNG BƯỚC)

OK, đến phần quan trọng nhất! Toàn sẽ hướng dẫn các bạn từng bước một để chuyển đổi hệ thống sang Queue Mode. Đây là cách mà Toàn đang áp dụng cho khách hàng tại GenStaff, đã test kỹ càng và chạy ổn định trên production.

Chúng ta sẽ dùng DockerDocker Compose – cách hiệu quả và dễ quản lý nhất.

1. BƯỚC 0: Chuẩn bị trước khi bắt đầu

Trước khi bắt đầu, các bạn cần đảm bảo có đủ những thứ sau:

  • VPS/Server: Chạy hệ điều hành Linux, Toàn recommend Ubuntu 22.04 LTS hoặc mới hơn
  • Docker + Docker Compose: Đã cài đặt phiên bản mới nhất (Docker 20+, Docker Compose 2+)
  • Kiến thức cơ bản: Biết dùng SSH để remote vào server và command line Linux cơ bản
  • Domain (khuyến khích): Một tên miền đã trỏ về IP server để setup webhook đàng hoàng

Về cấu hình máy chủ:

  • Setup nhỏ (2 workers): Tối thiểu 2 CPU cores, 4GB RAM
  • Setup trung bình (5 workers): 4 CPU cores, 8GB RAM
  • Setup lớn (10 workers): 8 CPU cores, 16GB RAM

Lưu ý: Con số này chỉ là tham khảo. Nếu workflows của các bạn đơn giản thì dùng ít RAM hơn cũng được. Còn nếu xử lý ảnh/video/data lớn thì cần nhiều hơn nhé.

2. BƯỚC 1: Tạo thư mục dự án và cấu trúc cơ bản

SSH vào server của các bạn và chạy lệnh:

# Tạo thư mục chính cho dự án
mkdir ~/n8n-production && cd ~/n8n-production

# Kiểm tra đã vào đúng thư mục chưa
pwd

Đơn giản thế thôi! Chúng ta sẽ dùng Docker volumes để lưu dữ liệu, nên không cần tạo nhiều thư mục con phức tạp.

3. BƯỚC 2: Tạo file môi trường (.env)

File này sẽ chứa các thông tin nhạy cảm như passwords, encryption keys. Rất quan trọng là các bạn phải giữ kín file này nhé!

Tạo file bằng lệnh:

nano .env

Dán nội dung sau vào (nhớ đổi tất cả các password thành password mạnh của riêng các bạn nhé):

# Password cho PostgreSQL database
DB_POSTGRES_PASSWORD=matkhaumanh_database_cua_ban

# Password cho Redis
N8N_REDIS_PASSWORD=matkhaumanh_redis_cua_ban

# Encryption key - phải là chuỗi dài và random
N8N_ENCRYPTION_KEY=chuoimahoacuaban_phairatrandom_daitoi32kytu

# Password để login vào n8n UI
N8N_BASIC_AUTH_PASSWORD=matkhaudangnhap_n8n_cua_ban

Mẹo quan trọng từ Toàn:

  • Với N8N_ENCRYPTION_KEY, các bạn có thể tạo bằng lệnh: openssl rand -hex 32
  • Đừng để passwords quá đơn giản kiểu “123456” hay “password” nhé!
  • Đừng commit file này lên Github hay share cho ai cả
  • Backup file này ra chỗ khác để lỡ có vấn đề còn restore lại được

Lưu file bằng Ctrl + X, sau đó nhấn YEnter.

4. BƯỚC 3: Tạo file docker-compose.yml chi tiết

Đây là “trái tim” của hệ thống các bạn nhé. File này định nghĩa tất cả các containers và cách chúng làm việc với nhau.

Tạo file:

nano docker-compose.yml

Dán toàn bộ nội dung sau vào. Toàn có comment chi tiết từng phần để các bạn hiểu rõ:

version: '3.8'

services:
  # ==========================================
  # PostgreSQL Database
  # Lưu trữ tất cả workflows, credentials, execution history
  # ==========================================
  postgres:
    image: postgres:16
    container_name: n8n-db
    restart: always
    environment:
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=${DB_POSTGRES_PASSWORD}
      - POSTGRES_DB=n8n
    volumes:
      - n8n_postgres_16:/var/lib/postgresql/data
    networks: 
      - webnet
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U n8n"]
      interval: 10s
      timeout: 5s
      retries: 5

  # ==========================================
  # Redis Message Queue
  # Quản lý hàng đợi công việc giữa main và workers
  # ==========================================
  redis:
    image: redis:7-alpine
    container_name: n8n-redis
    restart: always
    command: ["redis-server", "--appendonly", "yes", "--requirepass", "${N8N_REDIS_PASSWORD}"]
    volumes:
      - n8n_redis_data:/data
    networks: 
      - webnet
    healthcheck:
      test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

  # ==========================================
  # n8n Main Process
  # Chịu trách nhiệm: UI, API, Triggers
  # Không thực thi workflows (để workers làm)
  # ==========================================
  n8n:
    image: n8nio/n8n:latest
    container_name: n8n-main
    restart: always
    command: start
    environment:
      # === Database Configuration ===
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=${DB_POSTGRES_PASSWORD}

      # === Queue Mode Configuration ===
      - EXECUTIONS_MODE=queue
      - QUEUE_BULL_REDIS_HOST=redis
      - QUEUE_BULL_REDIS_PORT=6379
      - QUEUE_BULL_REDIS_PASSWORD=${N8N_REDIS_PASSWORD}

      # === Security & URLs ===
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - N8N_HOST=n8n.domain-cua-ban.com
      - N8N_PROTOCOL=https
      - N8N_PORT=5678
      - WEBHOOK_URL=https://n8n.domain-cua-ban.com/

      # === Basic Auth cho UI (Bảo vệ trang web) ===
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER=admin
      - N8N_BASIC_AUTH_PASSWORD=${N8N_BASIC_AUTH_PASSWORD}

      # === Tối ưu hóa quan trọng ===
      # Kích hoạt task runners mới (từ n8n 1.50+)
      - N8N_RUNNERS_ENABLED=true
      # Workflow test thủ công cũng chạy trên worker
      - OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS=true

      # === Timezone ===
      - GENERIC_TIMEZONE=Asia/Ho_Chi_Minh
      - TZ=Asia/Ho_Chi_Minh

      # === Tự động dọn dẹp execution history ===
      - EXECUTIONS_DATA_PRUNE=true
      - EXECUTIONS_DATA_MAX_AGE=336  # 14 ngày (336 giờ)
      - EXECUTIONS_DATA_PRUNE_MAX_COUNT=10000

      # === Log Level ===
      - N8N_LOG_LEVEL=warn  # warn cho production, debug khi troubleshoot
      
      # === Security Enhancement ===
      - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true

    volumes:
      - n8n_data:/home/node/.n8n
    networks:
      - webnet
      # QUAN TRỌNG: Thay đổi tên network này theo reverse proxy của bạn
      - proxy-nginx_proxy-net
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy

  # ==========================================
  # n8n Worker 1
  # Chuyên xử lý workflows, không có UI
  # ==========================================
  n8n-worker-1:
    image: n8nio/n8n:latest
    container_name: n8n-worker-1
    restart: always
    # concurrency=5 nghĩa là worker này có thể xử lý 5 jobs đồng thời
    command: worker --concurrency=5
    environment:
      # === Database ===
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=${DB_POSTGRES_PASSWORD}

      # === Queue ===
      - EXECUTIONS_MODE=queue
      - QUEUE_BULL_REDIS_HOST=redis
      - QUEUE_BULL_REDIS_PORT=6379
      - QUEUE_BULL_REDIS_PASSWORD=${N8N_REDIS_PASSWORD}

      # === Security ===
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      
      # === Timezone ===
      - GENERIC_TIMEZONE=Asia/Ho_Chi_Minh
      - TZ=Asia/Ho_Chi_Minh

      # === Performance ===
      - N8N_LOG_LEVEL=warn

    networks: 
      - webnet
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy

  # ==========================================
  # n8n Worker 2
  # Copy của worker 1, xử lý song song
  # ==========================================
  n8n-worker-2:
    image: n8nio/n8n:latest
    container_name: n8n-worker-2
    restart: always
    command: worker --concurrency=5
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=${DB_POSTGRES_PASSWORD}

      - EXECUTIONS_MODE=queue
      - QUEUE_BULL_REDIS_HOST=redis
      - QUEUE_BULL_REDIS_PORT=6379
      - QUEUE_BULL_REDIS_PASSWORD=${N8N_REDIS_PASSWORD}

      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - GENERIC_TIMEZONE=Asia/Ho_Chi_Minh
      - TZ=Asia/Ho_Chi_Minh
      - N8N_LOG_LEVEL=warn

    networks: 
      - webnet
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy

# ==========================================
# Docker Volumes
# Lưu trữ dữ liệu bền vững
# ==========================================
volumes:
  n8n_postgres_16:  # Database data
  n8n_data:         # n8n configurations, custom nodes, etc.
  n8n_redis_data:   # Redis persistence

# ==========================================
# Networks
# ==========================================
networks:
  webnet:  # Internal network cho các containers
  proxy-nginx_proxy-net:  # External network để kết nối với reverse proxy
    external: true

Những điểm các bạn cần chỉnh sửa:

  1. Domain: Đổi n8n.domain-cua-ban.com thành domain thật của các bạn
  2. Network: Đổi proxy-nginx_proxy-net thành tên network của reverse proxy mà các bạn đang dùng (Nginx Proxy Manager, Traefik, Caddy, etc.)
  3. Concurrency: Mỗi worker mặc định là --concurrency=5. Nếu server mạnh, các bạn có thể tăng lên 10 hoặc 15

Giải thích một số config quan trọng:

  • OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS: Khi các bạn nhấn nút “Test workflow” trên UI, nó sẽ chạy trên worker thay vì main process. Rất quan trọng!
  • EXECUTIONS_DATA_PRUNE: Tự động xóa execution history cũ. Nếu không bật, database sẽ to dần và chậm lại
  • healthcheck: Docker sẽ kiểm tra xem PostgreSQL và Redis đã sẵn sàng chưa trước khi start n8n

[nguyenthieutoan.com] Sơ đồ trực quan của cấu trúc docker-compose.yml với 5 containers chính được sắp xếp theo layers từ trên xuống dưới bao gồm n8n-main container ở trên cùng được highlight màu xanh dương với label UI API Triggers, hai n8n-worker containers ở giữa màu xanh lá với label Execution Engine, ở dưới cùng là postgres container màu cam và redis container màu đỏ, các volumes được thể hiện bằng icons ổ đĩa kết nối với các containers tương ứng

5. BƯỚC 4: Khởi chạy hệ thống lần đầu

Giờ là lúc “bấm nút khởi động” rồi! Các bạn chạy lệnh sau:

# Pull tất cả images về trước (để tracking progress)
docker-compose pull

# Khởi chạy tất cả containers ở background
docker-compose up -d

# Đợi khoảng 30 giây để mọi thứ khởi động xong, rồi check status
docker-compose ps

Nếu mọi thứ OK, các bạn sẽ thấy output giống thế này:

NAME           IMAGE              STATUS         PORTS
n8n-db         postgres:16        Up (healthy)   5432/tcp
n8n-redis      redis:7-alpine     Up (healthy)   6379/tcp
n8n-main       n8nio/n8n:latest   Up             5678/tcp
n8n-worker-1   n8nio/n8n:latest   Up
n8n-worker-2   n8nio/n8n:latest   Up

Nếu có container nào bị lỗi:

# Xem logs của container đó
docker-compose logs -f n8n-main

# Hoặc xem logs của tất cả
docker-compose logs -f

Các lỗi thường gặp mà Toàn hay thấy:

  • Network not found: Các bạn chưa tạo external network cho reverse proxy, hoặc đặt sai tên
  • Permission denied: Thư mục volumes không có quyền write. Fix bằng sudo chown -R 1000:1000 volumes/
  • Port already in use: Port 5678 đang bị chiếm bởi service khác

6. BƯỚC 5: Verify hệ thống đang chạy đúng

Sau khi khởi động xong, các bạn cần verify một số điểm:

1. Check n8n UI có vào được không:

Mở trình duyệt và vào https://n8n.domain-cua-ban.com. Nếu thấy trang login của n8n là OK!

2. Test một workflow đơn giản:

  • Login vào n8n
  • Tạo workflow mới với Schedule Trigger (chạy mỗi phút)
  • Thêm node “Set” để log ra một message
  • Save và activate workflow
  • Đợi 1-2 phút và check execution history

3. Check workers có nhặt jobs không:

# Xem logs của workers
docker-compose logs -f n8n-worker-1
docker-compose logs -f n8n-worker-2

Các bạn sẽ thấy dòng logs kiểu:

Worker ready and waiting for jobs...
Processing job: workflow-execution-xyz123

Nếu thấy các dòng này là workers đang hoạt động tốt!

[nguyenthieutoan.com] Screenshot minh họa terminal hiển thị logs của các n8n workers đang hoạt động với nhiều dòng màu xanh lá cây thể hiện workers đang xử lý jobs thành công, có timestamps bên trái và workflow IDs, số lượng jobs đang xử lý được highlight với màu vàng, background màu đen terminal truyền thống

7. BƯỚC 6: Mở rộng workers khi hệ thống lớn lên

Đây chính là điểm mạnh nhất của Queue Mode! Khi hệ thống của các bạn phát triển và cần xử lý nhiều workflows hơn, các bạn chỉ cần thêm workers.

Cách thêm worker thứ 3:

Mở file docker-compose.yml và copy-paste thêm một section worker mới:

  # ==========================================
  # n8n Worker 3
  # ==========================================
  n8n-worker-3:
    image: n8nio/n8n:latest
    container_name: n8n-worker-3
    restart: always
    command: worker --concurrency=5
    environment:
      # Copy y hệt config của worker-1 và worker-2
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=${DB_POSTGRES_PASSWORD}

      - EXECUTIONS_MODE=queue
      - QUEUE_BULL_REDIS_HOST=redis
      - QUEUE_BULL_REDIS_PORT=6379
      - QUEUE_BULL_REDIS_PASSWORD=${N8N_REDIS_PASSWORD}

      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - GENERIC_TIMEZONE=Asia/Ho_Chi_Minh
      - TZ=Asia/Ho_Chi_Minh
      - N8N_LOG_LEVEL=warn

    networks: 
      - webnet
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy

Sau đó restart hệ thống để worker mới hoạt động:

# Restart để apply changes
docker-compose up -d

# Check status
docker-compose ps

Worker mới sẽ tự động join vào hệ thống và bắt đầu nhặt jobs từ Redis queue. Không cần restart n8n-main hay làm gì thêm cả!

Làm thế nào biết cần bao nhiêu workers?

Dựa vào kinh nghiệm của Toàn, các bạn có thể tham khảo:

  • 10-30 workflows: 2 workers là đủ
  • 30-70 workflows: 3-5 workers
  • 70-150 workflows: 5-8 workers
  • 150+ workflows: 8-15 workers

Nhưng quan trọng hơn là: monitor hệ thống! Nếu các bạn thấy CPU/RAM vẫn còn dư, có thể giảm số workers. Nếu thấy jobs xếp hàng lâu, tăng workers lên.

Các bạn có thể tham khảo thêm tài liệu chính thức từ n8n: Queue Mode Configuration | n8n Docs

[nguyenthieutoan.com] Infographic minh họa quy trình scaling workers dễ dàng trong Queue Mode với 3 bước được đánh số từ 1 đến 3, bước 1 hiển thị 2 workers màu xanh đang hoạt động với icon edit file docker-compose.yml, bước 2 hiển thị thêm worker thứ 3 màu xanh lá nhạt đang được thêm vào với mũi tên chỉ lệnh docker-compose up -d, bước 3 hiển thị 3 workers cùng làm việc song song qua Redis queue với icon checkmark màu xanh lá và text No Restart Required

IV. MẸO TỐI ƯU HÓA VÀ BEST PRACTICES TỪ KINH NGHIỆM THỰC TẾ

Chuyển sang Queue Mode là bước nền tảng quan trọng nhất. Nhưng để hệ thống chạy thực sự mượt mà, Toàn muốn chia sẻ thêm một số kỹ thuật tối ưu mà mình học được qua hơn 100 dự án triển khai.

1. Tối ưu workflow từ bên trong

Kiến trúc tốt chỉ là nửa câu chuyện. Cách các bạn thiết kế workflow cũng ảnh hưởng rất lớn đến performance.

Xử lý dữ liệu lớn đúng cách với SplitInBatches

Giả sử các bạn có một workflow cần xử lý file CSV 10,000 dòng. Đừng load hết 10,000 dòng vào RAM một lúc! Hãy dùng node SplitInBatches:

  • Chia 10,000 dòng thành 100 batch, mỗi batch 100 dòng
  • Xử lý từng batch một
  • RAM giảm đáng kể, tránh lỗi “out of memory”
  • Có thể retry từng batch nếu lỗi

Xem thêm về kỹ thuật xử lý data trong n8n tại: Giải đáp các câu hỏi về n8n

Chia nhỏ workflows phức tạp thành sub-workflows

Workflow quá dài, có quá nhiều nodes? Chia nó thành các sub-workflows nhỏ hơn. Ví dụ:

  • Main workflow: Orchestrator, điều phối công việc
  • Sub-workflow 1: Fetch data từ API
  • Sub-workflow 2: Transform và clean data
  • Sub-workflow 3: Save vào database

Lợi ích:

  • Dễ debug và maintain
  • Tái sử dụng được logic
  • Performance tốt hơn
  • Team có thể làm việc song song

2. Monitoring và alerting – Cực kỳ quan trọng!

Các bạn biết câu “You can’t fix what you can’t measure” không? Đúng vậy đó. Nếu không có monitoring, các bạn sẽ không biết hệ thống đang có vấn đề cho đến khi quá muộn.

Setup monitoring cơ bản (miễn phí)

Đây là bộ tools mà Toàn recommend cho mọi hệ thống production:

  • Healthchecks.io: Service miễn phí để monitor cron jobs. Setup rất đơn giản:
    • Tạo account free
    • Tạo check cho mỗi workflow quan trọng
    • Thêm node HTTP Request vào cuối workflow để ping Healthchecks
    • Nếu workflow không chạy, Healthchecks sẽ gửi email/Slack alert cho các bạn
  • Uptime Kuma: Self-hosted monitoring tool cực kỳ đẹp và dễ dùng:
    • Monitor uptime của n8n UI
    • Monitor webhook endpoints
    • Gửi alerts qua nhiều channels: Email, Telegram, Discord, Slack…

Setup monitoring nâng cao (cho serious production)

Nếu hệ thống của các bạn thực sự quan trọng, Toàn recommend đầu tư thêm vào:

  • Prometheus + Grafana: Bộ đôi mạnh mẽ để monitoring chi tiết:
    • Metrics về CPU, RAM, disk usage
    • Số workflows đang chạy
    • Queue length (có bao nhiêu jobs đang chờ)
    • Execution time trung bình
    • Dashboard đẹp, xem được trend theo thời gian
  • Netdata: Real-time monitoring cho containers:
    • Monitor từng container riêng lẻ
    • Xem chính xác container nào đang ăn nhiều RAM/CPU
    • Free và rất dễ setup

Trust Toàn, khi có monitoring đàng hoàng, các bạn sẽ biết vấn đề TRƯỚC KHI khách hàng phàn nàn. Đó là sự khác biệt giữa một hệ thống professional và một hệ thống amateur.

[nguyenthieutoan.com] Screenshot của Grafana dashboard hiển thị các metrics quan trọng của n8n Queue Mode bao gồm đồ thị line chart màu xanh lá thể hiện số workflows đang chạy theo thời gian, bar chart màu cam thể hiện queue length theo từng worker, gauge meters thể hiện CPU usage và RAM usage với các vùng màu xanh yellow và đỏ biểu thị mức độ sử dụng, panel hiển thị execution success rate là 98.5% màu xanh lá

3. Hiểu rõ các config quan trọng

Có một số biến môi trường trong file docker-compose mà các bạn cần hiểu rõ để tối ưu hệ thống:

Về bảo mật

  • N8N_BASIC_AUTH_ACTIVE: Bật authentication cơ bản. Toàn recommend LUÔN BẬT nếu các bạn không dùng reverse proxy có auth riêng.
  • N8N_ENCRYPTION_KEY: Key để mã hóa credentials. PHẢI GIỐNG NHAU giữa main và tất cả workers!
  • N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: Bắt buộc file permissions phải đúng để tăng security.

Về performance

  • OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS: Cực kỳ quan trọng! Khi bật, việc test workflow thủ công sẽ chạy trên worker chứ không block main process.
  • N8N_RUNNERS_ENABLED: Kích hoạt task runners mới của n8n (từ version 1.50+). Tăng performance đáng kể.
  • worker –concurrency=X: Số jobs mà một worker có thể xử lý đồng thời. Default là 5, các bạn có thể tăng lên 10-15 nếu server mạnh.

Về data management

  • EXECUTIONS_DATA_PRUNE: Tự động xóa execution history cũ. PHẢI BẬT cho production!
  • EXECUTIONS_DATA_MAX_AGE: Giữ lịch sử bao lâu (đơn vị: giờ). Toàn thường set 336 giờ (14 ngày).
  • EXECUTIONS_DATA_PRUNE_MAX_COUNT: Giữ tối đa bao nhiêu executions. Set 10000 là hợp lý.

Nếu không bật data pruning, database của các bạn sẽ phình to rất nhanh và hệ thống sẽ chậm dần theo thời gian!

4. Khi nào cần nâng cấp máy chủ (Vertical Scaling)?

Queue Mode cho phép các bạn scale theo chiều ngang (thêm workers). Nhưng đôi khi, nâng cấp máy chủ (vertical scaling) cũng cần thiết.

Dấu hiệu cần nâng cấp máy chủ:

  • CPU thường xuyên ở mức >80%
  • RAM thường xuyên ở mức >90%
  • Workflows chạy chậm hơn bình thường
  • Database queries chậm

Quy tắc ngón tay cái của Toàn:

  • 2 workers: 2 CPU cores, 4GB RAM (minimum)
  • 5 workers: 4 CPU cores, 8GB RAM (comfortable)
  • 10 workers: 8 CPU cores, 16GB RAM (solid)
  • 15+ workers: 16+ CPU cores, 32GB+ RAM (enterprise)

Lưu ý: Con số này phụ thuộc vào độ phức tạp của workflows. Workflows xử lý ảnh/video hoặc data lớn sẽ cần nhiều resources hơn!

V. TROUBLESHOOTING – XỬ LÝ CÁC VẤN ĐỀ THƯỜNG GẶP

Qua kinh nghiệm hỗ trợ khách hàng, Toàn tổng hợp một số vấn đề mà các bạn có thể gặp và cách xử lý:

1. Workers không nhặt jobs

Triệu chứng: Workflows được trigger nhưng không thực thi, jobs cứ nằm trong queue.

Nguyên nhân và cách fix:

  • N8N_ENCRYPTION_KEY không khớp: Đảm bảo main và workers dùng chung một encryption key
  • Redis password sai: Check lại N8N_REDIS_PASSWORD
  • Workers chưa start: Check bằng docker-compose ps
  • Database connection lỗi: Check logs bằng docker-compose logs n8n-worker-1

2. UI chậm hoặc timeout

Triệu chứng: Vào n8n UI rất chậm, có khi timeout.

Cách fix:

  • Check CPU/RAM của container n8n-main: docker stats n8n-main
  • Bật OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS=true nếu chưa bật
  • Giảm số workflows active xuống nếu có quá nhiều
  • Check PostgreSQL có quá tải không

3. Database phình to quá nhanh

Triệu chứng: Disk space hết nhanh, database size tăng liên tục.

Cách fix:

  • Bật execution data pruning:
    EXECUTIONS_DATA_PRUNE=true
    EXECUTIONS_DATA_MAX_AGE=336
    EXECUTIONS_DATA_PRUNE_MAX_COUNT=10000
  • Tắt “Save Execution Progress” cho workflows không quan trọng
  • Manual cleanup nếu cần: SSH vào container PostgreSQL và chạy cleanup scripts

4. Out of Memory errors

Triệu chứng: Containers bị kill bởi OOM Killer, workflows đột ngột failed.

Cách fix:

  • Tăng RAM cho server
  • Giảm concurrency của workers xuống
  • Tối ưu workflows để xử lý data theo batches
  • Set memory limits cho containers trong docker-compose

VI. CHECKLIST TRIỂN KHAI HOÀN CHỈNH

Để đảm bảo các bạn không bỏ sót bước nào, Toàn tổng hợp lại checklist đầy đủ từ A-Z:

Chuẩn bị:

  • ✅ Đã có VPS/server với cấu hình phù hợp
  • ✅ Đã cài Docker và Docker Compose
  • ✅ Đã có domain và trỏ DNS về server
  • ✅ Đã chuẩn bị reverse proxy (Nginx, Traefik, Caddy…)

Setup cơ bản:

  • ✅ Tạo thư mục ~/n8n-production
  • ✅ Tạo file .env với passwords mạnh
  • ✅ Generate encryption key bằng openssl rand -hex 32
  • ✅ Tạo file docker-compose.yml đầy đủ
  • ✅ Chỉnh sửa domain, network name, timezone

Deployment:

  • ✅ Chạy docker-compose up -d
  • ✅ Kiểm tra tất cả containers đang chạy với docker-compose ps
  • ✅ Check logs không có lỗi
  • ✅ Truy cập n8n UI thành công

Verification:

  • ✅ Test workflow đơn giản chạy được
  • ✅ Workers có nhặt jobs từ queue
  • ✅ Webhook hoạt động bình thường
  • ✅ Cron jobs chạy đúng lịch

Security & Optimization:

  • ✅ Setup SSL certificate cho domain
  • ✅ Bật Basic Auth hoặc setup OAuth
  • ✅ Bật execution data pruning
  • ✅ Setup backup tự động cho PostgreSQL
  • ✅ Setup monitoring với Healthchecks.io hoặc Uptime Kuma

Documentation:

  • ✅ Lưu lại file .env vào chỗ an toàn
  • ✅ Document các bước setup và configs
  • ✅ Setup alerting để nhận thông báo khi có vấn đề

VII. KẾT LUẬN VÀ CHIA SẺ TỪ TOÀN

Phù, bài viết hơi dài nhỉ các bạn? Nhưng Toàn nghĩ là cần thiết để các bạn hiểu đầy đủ về Queue Mode – một thay đổi kiến trúc có thể cứu cánh hệ thống n8n của các bạn.

Qua hơn 100 dự án triển khai n8n cho các doanh nghiệp tại GenStaff, Toàn có thể khẳng định rằng: Queue Mode không phải là “nice to have” – nó là điều kiện tiên quyết cho bất kỳ hệ thống n8n production nào.

Sự khác biệt giữa Main Mode và Queue Mode giống như sự khác biệt giữa một cửa hàng tạp hóa nhỏ với một siêu thị hiện đại. Cả hai đều bán hàng, nhưng cách tổ chức và khả năng phục vụ hoàn toàn khác biệt.

Những gì các bạn nhận được khi chuyển sang Queue Mode:

  • ✅ Không còn lo workflow bị miss
  • ✅ UI luôn responsive, không bị đơ
  • ✅ Có thể mở rộng gần như không giới hạn
  • ✅ Một worker chết không ảnh hưởng hệ thống
  • ✅ Xử lý hàng trăm workflows đồng thời
  • ✅ Yên tâm ngủ ngon không lo system crash lúc nửa đêm 😴

Với tư cách là n8n Verified Creator, Toàn rất vui được chia sẻ những kinh nghiệm thực tế này với cộng đồng người dùng n8n Việt Nam. Nếu các bạn gặp khó khăn trong quá trình triển khai, đừng ngại để lại comment hoặc liên hệ với mình nhé!

Một vài lời khuyên cuối cùng:

  • Đừng đợi đến khi hệ thống sập mới chuyển sang Queue Mode. Hãy làm ngay khi các bạn bắt đầu nghiêm túc với automation.
  • Đầu tư vào monitoring ngay từ đầu. Nó sẽ tiết kiệm cho các bạn rất nhiều đau đầu sau này.
  • Backup PostgreSQL database thường xuyên. Workflows và credentials của các bạn là tài sản quý giá!
  • Join cộng đồng n8n để học hỏi và chia sẻ kinh nghiệm.

Nếu các bạn thấy bài viết này hữu ích, hãy chia sẻ cho những người khác cũng đang dùng n8n nhé! Và đừng quên đăng ký nhận thông báo bên dưới để không bỏ lỡ các bài viết chuyên sâu về n8n, automation và AI trong thời gian tới.

Happy automating! 🚀

[nguyenthieutoan.com] Illustration minh họa một hệ thống n8n Queue Mode đang hoạt động ổn định và hiệu quả với nhiều workflows được biểu thị bằng các luồng màu xanh lá cây chạy song song qua các workers, dashboard hiển thị 100% uptime và 0 missed jobs màu xanh lá, biểu tượng rocket thể hiện performance cao, và character minh họa admin đang uống cà phê thư giãn với biểu tượng checkmarks và stars xung quanh thể hiện sự hài lòng

Nguyễn Thiệu Toàn

Nguyễn Thiệu Toàn

Tôi là người biến ý tưởng thành hệ thống AI và Tự động hóa thực tế. Tôi dùng Marketing để tìm hiểu những khó khăn bạn đang gặp, sau đó xây dựng các giải pháp tự động để giúp bạn thoát khỏi những công việc tẻ nhạt. Mục đích là để bạn có thể tập trung vào những việc lớn hơn, chứ không phải để thay thế vị trí của bạn.