Kiedy rejestrujesz nowego użytkownika w aplikacji — co musi się stać zanim wyślesz mu potwierdzenie?
Zapis do bazy: tak, to musi być natychmiastowe. Wysłanie e-maila powitalnego: nie musi być w tej samej sekundzie. Wygenerowanie miniaturki zdjęcia profilowego: zdecydowanie nie.
Pierwsze kolejki zadań weszły do juz-ide w październiku 2025. Nie dlatego, że coś było wolne — ale dlatego, że nie wszystko powinno dziać się jednocześnie.
Problem, który nie był problemem wydajnościowym
W sierpniu 2025 wdrożyłem system uprawnień z pamięcią podręczną. Kiedy zmieniam rolę użytkownika, ta pamięć musi zostać odświeżona — inaczej przez jakiś czas aplikacja pamiętałaby stare uprawnienia.
Pierwsze podejście: odśwież w tej samej chwili co zmiana roli. Działało. Ale logika biznesowa (zmiana roli) była spleciona z infrastrukturą (odświeżanie pamięci). Trudno testować, trudno zmieniać.
Drugie podejście: zmiana roli → sygnał do kolejki → system odświeża pamięć w tle. Logika zmiany roli nie wie nic o tym, jak działa pamięć podręczna.
To nie była optymalizacja wydajności. To rozdzielenie odpowiedzialności.
Co trafia do kolejki w juz-ide
Trzy rodzaje zadań, które lepiej pasują do poczekalni niż do natychmiastowego wykonania:
Odświeżanie uprawnień — kiedy rola lub dane użytkownika się zmieniają, zapamiętane uprawnienia muszą zostać wyliczone od nowa. Nie musi to dziać się równocześnie z samą zmianą, ale musi się w końcu wydarzyć.
Logi RODO — każde wrażliwe działanie (zapis, odczyt, usunięcie danych osobowych) generuje wpis w rejestrze. Gdyby ten wpis był częścią głównej operacji, awaria logu oznaczałaby cofnięcie całej rejestracji użytkownika. Rejestracja nie powinna się odwijać dlatego, że log zawiódł.
Powiadomienia — e-maile weryfikacyjne i SMS-y (w planach). Mogą poczekać kilka sekund. Nie powinny spowalniać głównej odpowiedzi aplikacji.
Dlaczego gotowa biblioteka, a nie „zrób to sam”
Był kuszący skrót: tabela w bazie danych z listą zadań do wykonania, pętla która je przetwarza co kilka sekund. Wielu zaczyna tak.
Wybrałem gotową bibliotekę kolejek z dwóch powodów:
Pierwszy: ma wbudowane rzeczy, których nie chcę pisać samemu — automatyczne ponowienie zadania gdy coś zawiedzie, osobną poczekalnię dla zadań, których nie da się przetworzyć, zadania opóźnione i cykliczne. Napisanie tego samemu to kilka dni pracy, która nie wnosi nic do produktu.
Drugi: serwer pamięci podręcznej był już w systemie (do przechowywania uprawnień). Dodanie kolejki na tej samej infrastrukturze to konfiguracja, nie nowa technologia do utrzymania.
Kolejki i zdarzenia domenowe w architekturze DDD
W architekturze DDD kolejki łączą się naturalnie ze zdarzeniami domenowymi. Wzorzec w juz-ide:
- Agregat publikuje
DomainEventprzezEventBusbiblioteki vytches-ddd - Handler domenowy rejestruje zdarzenie do kolejki BullMQ (Redis)
- Konsument kolejki wykonuje efekt uboczny (cache, audit, notification)
Domena nie wie o kolejkach. Kolejki nie wiedzą o domenie. Łączy je zdarzenie — czysta granica.