Edge runtime vs Node runtime: quando scegliere l'uno o l'altro nel SaaS
Edge vince su cold start e latenza globale. Node vince su librerie, durata e accesso a database. La scelta non è binaria, e la maggior parte dei SaaS in produzione usa entrambi.
L'Edge runtime è un ambiente V8 isolate che esegue il codice in 300+ Points of Presence con cold start sotto i 100ms; il Node runtime è un processo Node.js completo che gira in data center regionali con un'API più ampia e un costo di avvio più alto. Risolvono problemi diversi, e la risposta giusta per un SaaS quasi mai è "tutto Edge" o "tutto Node".
Questo articolo è per chi guida l'engineering e deve scegliere il runtime per ogni route in Next.js 16 o in qualsiasi framework che esponga lo stesso split. Ci concentriamo su ciò che si rompe davvero in produzione, non sul marketing.
TL;DR
Scegli Edge per route brevi, sensibili alla latenza, che usano solo Web API: middleware, controlli di auth, routing A/B, rewrite per geolocalizzazione, relay di token streaming. Scegli Node per route che dipendono da pacchetti npm pesanti, parlano con un database SQL via driver persistente, durano più di qualche secondo, generano PDF o usano il filesystem. La maggior parte dei SaaS che spediamo gira il middleware su Edge e le API CRUD su Node, e questo split copre da solo il ~95% delle decisioni.
Confronto a colpo d'occhio
AsseEdge runtimeNode runtimeMotoreV8 isolate (sottoinsieme Web API)Processo Node.js completoCold start (P50)~100ms~250ms warm, ~860ms coldDistribuzione geograficaPoP globaliUna o poche regionPacchetti npmSolo edge-compatibleQualsiasi pacchetto npmLimite bundle1-4 MB su VercelFino a 250 MB unzippedDurata massima300s (streaming entro 25s)Fino a 800s su Vercel ProFilesystemNessunoCompletoModuli nativiNessunoSìConnessioni persistentiNoSì (con riserve)Dove vince Edge
Latenza di cold start
Il benchmark più citato sul tema, condotto da openstatus, ha misurato 106ms P50 per Edge contro 246ms warm e 859ms cold per Vercel serverless: 9x più veloce nei cold path e 2x quando già warm (openstatus, 2024). Il motivo è strutturale: i V8 isolate condividono un singolo processo OS, quindi avviarne uno è un'allocazione di memoria sotto il millisecondo. Una funzione serverless Node deve far partire un processo Node, parsare node_modules ed eseguire il codice applicativo: centinaia di millisecondi anche con un bundle piccolo.
Per un middleware che gira a ogni richiesta, questo conta. Anche 200ms di cold-start su un middleware di gating bastano a far saltare i target di TTFB e a spingere il Largest Contentful Paint in giallo.
Prossimità globale
Le funzioni Edge si eseguono nel PoP più vicino all'utente. Una richiesta da San Paolo verso una region Node solo a Francoforte impiega 200+ms di rete prima ancora che il codice giri. La stessa richiesta verso una funzione Edge atterra in un PoP a San Paolo e il round-trip scende a 30ms. Per route la cui risposta è "setta un cookie, fai redirect o rewrite", quei 200ms sono l'intero budget di latenza.
Streaming di token da un LLM
I runtime Edge implementano nativamente ReadableStream e la piattaforma Vercel li inoltra al client senza bufferizzare. Per UI di chat che fanno streaming di token da Claude, GPT o Gemini, Edge tiene bassa la latenza percepita perché i token arrivano all'utente man mano che raggiungono il PoP, non dopo che una region Node li ha rebufferizzati.
Dove vince Node
Compatibilità delle librerie
Edge esegue un sottoinsieme stretto di Web API. Niente fs, niente child_process, niente net, niente crypto nativo, niente eval, niente new Function(). Qualsiasi pacchetto npm che tocchi quelle API, direttamente o in modo transitivo, non gira (Next.js Edge API reference).
L'elenco dei pacchetti incompatibili è lungo: jsonwebtoken, bcrypt, sharp, puppeteer, pdfkit, gran parte degli ORM con driver nativi, e ogni pacchetto che usa global Node-specific. Alcuni hanno alternative edge-compatible (jose per i JWT, @node-rs/argon2 per l'hashing, l'edge client di Prisma) ma la migrazione non è gratis, soprattutto quando ti accorgi del rewrite a metà di una feature.
Accesso al database
Le connessioni TCP persistenti verso un database SQL non esistono su Edge. Il modello è HTTP-based: ogni query apre una connessione fresca via proxy o driver serverless. Funziona per pattern read-heavy piccoli, ma transazioni, prepared statement e query lunghe sono più lente e più costose dell'equivalente Node. Lo vediamo in pratica su Supabase: una funzione serverless Node con client postgres in pool gestisce di routine una transazione da 6 statement in 40ms; lo stesso lavoro via API HTTP Supabase da Edge sta a 120-200ms.
Lavoro long-running e CPU-intensive
Le funzioni Edge su Vercel devono iniziare a streammare una risposta entro 25 secondi, anche se l'invocation totale può durare fino a 300s (Vercel, marzo 2025). Per generare PDF, trasformare immagini, impacchettare ZIP o per qualsiasi lavoro CPU sincrono che blocca prima di produrre output, Node è il runtime più sicuro. Anche la CPU stessa è più debole su Edge: i V8 isolate sono schedulati in modo aggressivo e possono essere prelazionati, mentre le funzioni Node hanno uno slot di esecuzione dedicato.
Dimensione del bundle
Il limite di bundle Edge su Vercel è tra 1 MB e 4 MB a seconda del piano e della piattaforma, e include tutto ciò che è importato in modo transitivo (Vercel Functions Limits). Un SDK di medie dimensioni basta a sforarlo. Le funzioni Node arrivano a 250 MB unzipped: raramente un vincolo.
La questione middleware (Next.js 15.5+)
Per due anni il middleware Next.js è stato solo Edge. Questo costringeva i team a fare gli auth check contro uno store di sessione HTTP-based (Upstash, Clerk, JWT Auth.js) e a evitare ogni dipendenza Node-specific nel path del middleware. In Next.js 15.5, Vercel ha reso stabile il supporto Node.js per il middleware dopo la fase sperimentale di 15.2 (release notes Next.js 15.5). Next.js 16 mantiene la rotta.
L'effetto pratico: ora puoi far girare una libreria solo-Node (un session validator che ha bisogno di crypto, un client ORM, un SDK feature-flag che usa fs) nel middleware senza giocare a Edge polyfill. Il trade-off è la regressione di cold-start: il middleware Node è più lento a partire del middleware Edge, quindi i vantaggi di "middleware su Edge" reggono ancora per route di gating ad alto traffico.
La nostra regola: middleware Edge come default; passare a middleware Node solo quando l'alternativa Edge richiede tre swap di pacchetto edge-compatible per soddisfare una sola feature.
Cosa giriamo davvero in produzione
Lo split che spediamo sulla maggior parte dei progetti SaaS Studio:
- Edge: middleware (routing i18n, auth gate, A/B, geolocalizzazione),
/api/health, endpoint di image rewrite, relay streaming LLM, endpoint di lettura a basso rischio che colpiscono Upstash Redis. - Node: tutto il CRUD admin contro Supabase, upload di file su R2, webhook Stripe, generazione PDF, qualsiasi cosa che tocchi il filesystem, job schedulati.
Il default per una nuova route è Node, e promuoviamo una route a Edge solo quando misuriamo un guadagno di latenza che giustifichi la superficie di vincoli. "Default a Edge" è un errore comune nei SaaS early-stage: spinge auth e accesso DB in un runtime dove sono più lenti e costosi, e poi spinge il team in un porting di 2 settimane verso Node quando un webhook Stripe deve girare per 12 secondi.
L'albero decisionale
Davanti a una nuova route lo percorriamo in quest'ordine:
- La route deve leggere la request e agire in meno di 50ms (geolocalizzazione, auth gate, rewrite)? Edge.
- La route fa streaming di token da un LLM? Edge.
- La route dipende da un singolo pacchetto npm che tira API Node? Node.
- La route fa una transazione DB multi-statement? Node.
- La route potrebbe girare più di 25 secondi prima di iniziare a streammare? Node.
- Il bundle della route è già oltre 1 MB? Node.
- Niente di sopra e la route è ad alto traffico? Edge, misurato.
- Altrimenti: Node, default.
Le decisioni prese così sono reversibili. Quelle prese seguendo "tutto Edge, è più veloce" di solito non lo sono, perché quando il team sbatte contro il muro mezza codebase è già scritta solo contro Web API.
Domande frequenti
- Can I mix Edge and Node runtimes in the same Next.js app?
- Yes, and most production apps do. You set the runtime per route segment with the route-segment config (export const runtime = 'edge' or 'nodejs'), and Next.js builds and deploys each route accordingly. Middleware is a separate decision since Next.js 15.5 made Node middleware stable, but you still pick one runtime for the middleware as a whole.
- Is Edge always cheaper than Node on Vercel?
- Not always. Edge invocations are billed differently and the GB-Hours math depends on your traffic shape. For high-traffic short routes, Edge tends to be cheaper because of faster cold starts and less compute time per request. For long-running CPU-bound work, Node is usually cheaper because Edge would either time out or burn longer at higher rates.
- What happens if my Edge function exceeds the bundle size limit?
- The deploy fails. Vercel surfaces a build error naming the route and the bundle size. The fix is either to swap an Edge-incompatible package for a lighter alternative, lazy-load on the client, or move the route to the Node runtime. There is no soft-degradation, the route does not ship until the bundle is under the limit.
- Should I use Edge for my Stripe webhook?
- No. Stripe webhooks need raw body access, signature verification with crypto primitives that some libraries implement only in Node, and tolerance for occasional 5 to 15 second processing windows. Run them on Node with maxDuration set generously, and let the queue or DB write absorb retries.
Studio
Inizia un progetto.
Un partner unico per aziende, PA, startup e SaaS. Produzione più veloce, tecnologie moderne, costi ridotti. Un team, una fattura.