import Fastify from 'fastify';
import { Queue, Worker } from 'bullmq';
const fastify = Fastify({ logger: true });
const queue = new Queue('invoices', { connection: { host: 'localhost', port: 6379 } });
fastify.post('/api/invoices', async (request, reply) => {
const { orderId } = request.body as { orderId: string };
await queue.add('generate', { orderId }, { attempts: 3 });
return reply.status(202).send({ queued: true });
});
const worker = new Worker('invoices', async (job) => {
// Procesare lungă fără stres de timeout
console.log(`Factura generată pentru: ${job.data.orderId}`);
}, { connection: { host: 'localhost', port: 6379 } });
fastify.listen({ port: 4000, host: '0.0.0.0' });Am văzut prea multe echipe care împing totul în Next.js doar pentru că „e deja acolo”. Ai nevoie de un webhook? Trântești un Route Handler. Ai un script de sincronizare? Server Action sau cron ciudat.
Merge brici la început, dar te lovești repede de pereți când proiectul crește.
Limitările pe care nu ți le spune documentația
Next.js a fost gândit în primul rând ca un framework de UI care face și ceva backend la nevoie. Dacă hostezi pe Vercel sau folosești serverless adapters, ești limitat la cicluri scurte de execuție: timeout la 10-15 secunde pe planurile uzuale, fără conexiuni TCP persistente, fără memorie împărțită între request-uri.
La o platformă de e-commerce cu vreo 12.000 de comenzi pe zi, am încercat să procesăm generarea de facturi PDF și sincronizarea cu ERP-ul direct din API routes. Rezultatul? Timeouts dese, pool-ul de PostgreSQL sufocat din cauză că fiecare instanță serverless deschidea conexiuni proprii și costuri dublate pe infrastructură fără motiv.
Trei scenarii clare în care un proces Node câștigă
-
Background jobs și cozi (BullMQ / Redis): Un job processor are nevoie de un proces long-running care ascultă constant pe un queue. Nu poți pune un Redis worker într-o funcție lambda sau într-un Route Handler fără hack-uri oribile. Un script simplu pornit cu PM2 rezolvă asta elegant și consumă sub 80MB RAM.
-
WebSockets și streaming lung: Dacă ai dashboard-uri în timp real sau procesezi fișiere mari în chunks, Next.js te încurcă. Un server Node minimalist cu Fastify sau direct
@fastify/websocketține 10.000 de conexiuni idle pe o mașină ieftină fără să clipească. -
Gestionarea conexiunilor la DB: Într-un proces de sine stătător pe un VPS sau container, ai un connection pool stabil de 10-20 conexiuni. În serverless, 200 de vizitatori simultani pot însemna 200 de conexiuni noi la Postgres, riscând să trântească baza.
Trade-off-ul real: ce pierzi când decuplezi
Nu e totul roz. Odată ce ai separat serverul, pierzi typing-ul partajat nativ între frontend și backend pe care ți-l dădeau Server Actions. Trebuie să configurezi un monorepo (Turborepo sau npm workspaces), să definești un contract tRPC sau OpenAPI și să te ocupi de două pipeline-uri de CI/CD în loc de unul singur.
În plus, mentenanța de infrastructură revine la tine. Dacă Next.js îl arunci pe Vercel și uiți de el, pentru procesul de Node trebuie să configurezi PM2, log rotation și un reverse proxy (Nginx sau Caddy) în fața lui.
Regula mea după vreo 4 migrări de genul ăsta: dacă logica ta backend răspunde în sub 200ms și e doar un CRUD simplu pentru ecran, las-o în Next. Dacă atinge fișiere pe disc, ascultă evenimente sau rulează mai mult de 2 secunde, scoate-o într-un serviciu separat din prima zi.