import Fastify from 'fastify';
import { Worker } from 'bullmq';
const fastify = Fastify({ logger: true });
// Worker dedicat ce rulează persistent fără overhead-ul de SSR/Bundling
const pdfWorker = new Worker('pdf-generation', async (job) => {
console.log(`Procesez PDF pentru comanda #${job.data.orderId}`);
// Simulare task intensiv fara sa blocam UI-ul de Next.js
return { url: `/docs/pdf-${job.data.orderId}.pdf` };
}, {
connection: { host: '127.0.0.1', port: 6379 }
});
fastify.get('/health', async () => {
return { status: 'ok', workerActive: pdfWorker.isRunning() };
});
fastify.listen({ port: 4000, host: '0.0.0.0' }, (err) => {
if (err) process.exit(1);
});Observ tot mai mulți dev-i care bagă totul în Next.js doar pentru că îl au deja în proiect. Am făcut și eu greșeala asta acum doi ani la un proiect cu peste 15k utilizatori activi zilnic, unde am pus generarea de PDF-uri și procesarea de Webhooks direct în Route Handlers. Rezultatul? Serverless function timeouts, consum de memorie scăpat de sub control și facturi uriașe pe Vercel.
Problema cu Next.js folosite pe post de elvețian al backend-ului
Next.js e genial pentru ce a fost creat: SSR, SSG, frontend modern și un BFF (Backend For Frontend) subțire. Dar în momentul în care începi să montezi job-uri de fundal, WebSockets sau logici grele de business, framework-ul devine o ancoră.
Când rulezi un Route Handler în Next.js, aduci după tine tot bundle-ul de server al framework-ului. Dacă mai ești și pe serverless, ai cold starts de 1-2 secunde pe rutele grele. Dacă ești pe Node.js de sine stătător cu next start, tot ai un footprint de memorie semnificativ (deseori peste 250MB RAM în idle) doar pentru a servi un simplu JSON.
Unde e net superior un server Node.js dedicat
Am mutat procesarea de job-uri și API-ul intern pe un server separat de Fastify, containerizat simplu pe un VPS de 10 euro pe lună. Am salvat vreo 40% la factura de cloud și latența medie a scăzut de la 180ms la sub 25ms.
Aici e unde un server Node separat câștigă fără drept de apel:
- Job Processors și Cron-uri (BullMQ / Agenda): Next.js nu e gândit să aibă un proces persistent în fundal. Dacă ai un queue worker care trebuie să asculte în Redis 24/7, un script Node dedicat care rulează cu PM2 sau în Docker este singura opțiune sănătoasă.
- WebSockets sau conexiuni de lungă durată (socket.io / SSE): În Next.js App Router, conexiunile persistente sunt un coșmar sau imposibile pe infrastructuri serverless. Un server Express/Fastify ține 10.000 de conexiuni deschise cu doar 100MB RAM.
- Microservicii de calcul intens sau I/O masiv: Un API care transformă imagini sau procesează fișiere CSV de 50MB va bloca event loop-ul în Next.js și îți va încetini randarea paginilor web pentru toți utilizatorii.
Trade-off-urile reale
Nu zic să renunți la Next.js pentru orice backend. Dacă ai doar un formular de contact și o integrare simplă cu Stripe, folosește liniștit Server Actions sau Route Handlers.
Tragerea de linie e simplă:
- Avantaj Node separat: Control total asupra memoriei, pornire instantanee (<100ms), consum redus de resurse și zero magie de bundling (Webpack/Turbopack) care să-ți strice pachetele de Node native.
- Dezavantaj: Trebuie să gestionezi alt repo sau monorepo, să scrii puțin boilerplate pentru CORS sau autentificare și să configurezi deployment-ul separat.
Dacă ai un API intern care procesează peste 50-100 req/sec sau ai job-uri în fundal, nu mai forța Next.js. Fă un serviciu Node curat cu Fastify și o să-ți mulțumești singur peste 6 luni.
Voi cum abordați separarea asta? Păstrați totul în Next până crapă sau separați backend-ul din prima zi?