Outbox pattern w n8n: API nie z webhooka
Outbox pattern w n8n to jedna z tych rzeczy, które brzmią jak architektura dla ludzi w polarach z konferencji, a potem okazuje się, że ratują Ci tyłek przy zwykłym formularzu kontaktowym.
Klasyczny scenariusz, który idzie w bengier
Masz webhook w n8n. Wpada lead. Ty od razu z webhooka wołasz CRM, fakturownię, Slacka, mailing, arkusz, może jeszcze API od kuriera, bo czemu nie. Wszystko działa na testach. Pięknie. Bengier.
A potem zewnętrzne API ma czkawkę. CRM odpowiada po 28 sekundach. Fakturujący SaaS zwraca 502. Slack przyjmuje wiadomość, ale workflow pada na następnym kroku. Lead niby był. Ale gdzie jest prawda? W n8n? W CRM? W mailingu? U Pana Boga w kajecie?
No właśnie.
W tym artykule pokażę Ci, czemu nie wołam zewnętrznego API prosto z webhooka, jak rozkładam taki proces w n8n i jak używam outbox pattern bez robienia z tego doktoratu. To jest tekst dla osób, które robią automatyzacje w n8n, zbierają dane z formularzy, budują integracje między systemami albo mają już dość jojczenia, że "czasem coś się nie wysłało".
Czym jest outbox pattern w n8n?
Outbox pattern w n8n to podejście, w którym webhook najpierw zapisuje zdarzenie do trwałego miejsca, a dopiero osobny workflow wysyła dane do zewnętrznych API.
Czyli nie robisz tak:
- Webhook przyjmuje dane.
- Webhook od razu woła CRM.
- Webhook od razu woła mailing.
- Webhook od razu woła Slacka.
- Webhook czeka, aż cały świat łaskawie odpowie.
Tylko tak:
- Webhook przyjmuje dane.
- Webhook waliduje minimum.
- Webhook zapisuje event do tabeli
outbox. - Webhook szybko zwraca odpowiedź.
- Osobny workflow bierze event z outboxa.
- Osobny workflow woła CRM, mailing, Slacka i resztę ferajny.
- Status eventu jest aktualizowany.
Outbox pattern oddziela przyjęcie zdarzenia od jego dostarczenia do zewnętrznych systemów.
I to jest cała magia. Nie potrzebujesz bębna szamańskiego ani 12 mikroserwisów. W n8n wystarczy sensownie rozdzielić odpowiedzialności. Webhook ma przyjąć dane. Worker ma je przetworzyć. Tyle.
Czemu nie wołam zewnętrznego API prosto z webhooka?
Nie wołam zewnętrznego API prosto z webhooka, bo webhook powinien być szybki, przewidywalny i możliwie głupi. "Głupi" to komplement.
Webhook to recepcja w hotelu. Ma przyjąć gościa, sprawdzić rezerwację, dać klucz i nie robić przy tym pięciu telefonów do pralni, kuchni, księgowości i instruktora jogi.
Jeżeli z webhooka od razu wołasz zewnętrzne API, podpisujesz stabilność swojego procesu pod dostępność każdego z tych serwisów naraz. Jeden odpowiada wolno, reszta czeka. Jeden pada, cały webhook pada. Lead ginie, bo fakturujący SaaS miał chwilę. I ty wiesz o tym dopiero gdy klient zadzwoni.
Outbox pattern izoluje to ryzyko. Webhook przyjmuje dane i odpowiada szybko. Dane są w bazie, bezpieczne. Worker robi resztę i może retry gdy API nie odpowiada. Klient dostaje potwierdzenie, zanim cokolwiek pójdzie do CRM.
Tabela outbox: minimal viable schema
W n8n używam Postgres jako outboxa. Minimalna tabela wygląda tak:
CREATE TABLE outbox (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
event_type TEXT NOT NULL,
payload JSONB NOT NULL,
status TEXT NOT NULL DEFAULT 'pending',
attempts INT NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
processed_at TIMESTAMPTZ
);
Status: pending, processing, done, failed. Worker bierze eventy w statusie pending, ustawia processing, robi robotę, ustawia done albo po kilku próbach failed.
attempts przy każdej próbie. Jeśli worker pada w środku, event wraca do pending i jest próbowany ponownie. Bez licznika prób skończyłbyś z eventem próbowanym w nieskończoność.
Jak to śmiga w n8n: dwa workflowy
Workflow 1: receiver (webhook)
- Webhook node przyjmuje POST.
- Function node waliduje wymagane pola (email, typ eventu).
- Postgres node: INSERT do
outboxze statusempending. - Respond to Webhook: HTTP 200 z
{"status":"queued"}.
Cały flow to sekund ułamek. Nie czeka na CRM, nie czeka na mailing. Dane są bezpieczne.
Workflow 2: worker (cron co minutę albo trigger)
- Postgres node: SELECT z
outboxWHEREstatus='pending'LIMIT 10. - Postgres node: UPDATE status na
processing, inkrementujattempts. - Switch node po
event_type: inna ścieżka dla leada, inna dla zamówienia. - HTTP Request do CRM, mailingowego, Slacka.
- Postgres node: UPDATE status na
done, zapiszprocessed_at. - Error handler: jeśli HTTP rzucił wyjątek i
attempts >= 3, ustawfailed.
Worker jest niezależny od receivera. Restart receivera, błąd w nim, nic z tego nie gubi eventów z outboxa. Dane już tam są.
Kiedy to stosować, a kiedy nie
Outbox pattern ma sens gdy:
- Webhook przyjmuje dane, które potem idą do co najmniej jednego zewnętrznego API.
- Strata eventu ma realne konsekwencje (zgubiony lead, brak faktury, nieotworzony dostęp).
- Zewnętrzne API bywa wolne albo miewało przestoje.
- Chcesz zobaczyć historię wszystkich eventów i ich statusy.
Nie stosuj outboxa gdy:
- Webhook musi odpowiedzieć czymś zależnym od zewnętrznego API (synchroniczna odpowiedź do klienta).
- Masz prosty webhook 1:1 bez żadnego side effectu w zewnętrznych systemach.
Przy synchronicznych odpowiedziach i tak możesz ogarniać część logiki asynchronicznie: odpowiedz natychmiast tym co masz, a wysyłkę maila i zapis do CRM wrzuć do outboxa.
outbox to przy okazji darmowy audit log. Widzisz kiedy co przyszło, ile prób zajęło, co zrobiło status failed. Przy debugowaniu integracji to jest fest przydatne, szczególnie gdy klient mówi "wpłaciłem, ale nie dostałem dostępu".
Najczęstsze pytania
Czym jest outbox pattern w n8n?
Outbox pattern w n8n to podejście, w którym webhook najpierw zapisuje zdarzenie do trwałej tabeli w bazie, a dopiero osobny workflow wysyła dane do zewnętrznych API. Oddziela przyjęcie zdarzenia od jego dostarczenia, dzięki czemu awaria zewnętrznego serwisu nie niszczy procesu przyjmowania danych.
Dlaczego nie wołać zewnętrznego API prosto z webhooka n8n?
Bo podpisujesz stabilność swojego procesu pod dostępność zewnętrznych serwisów. Jeśli CRM odpowiada po 28 sekundach albo mailing SaaS zwraca 502, Twój webhook czeka, timeout, lead ginie. Outbox pattern izoluje te ryzyka: webhook jest szybki i niezawodny, a dostarczanie do zewnętrznych API to zadanie workera z retry.
Chcesz webhooki, które nie gubią danych?
U Ciebie zaczynam od warsztatu procesu (90 minut, bezpłatny). Rozrysujemy przepływ integracji i powiem wprost, gdzie są słabe punkty. Bez wciskania jednego słusznego stacku.
Zamów warsztat → Lub napisz bezpośrednio.