Vai al contenuto
Web

Edge runtime o Node runtime: cosa cambia con Next.js 16

Next.js 16 sposta il middleware sul runtime Node e lo rinomina proxy.ts. Dove Edge resta più rapido e dove Node vince su librerie e processi lunghi.

6 maggio 2026 · 9 min di lettura · Aggiornato il 30 settembre 2026

A thin upper lane of small tiles with a dashed empty outline in it, a curved arrow down to the same tile lit on a wide lower lane carrying a block of packages and a long bar

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.

Cosa è cambiato: Next.js ha deprecato l'Edge runtime

Da Next.js 16.3 export const runtime = 'edge' è deprecato e l'indicazione ufficiale è cancellare la riga: il default è Node.js e non serve alcun sostituto (Next.js: Edge Runtime Deprecated). Next.js 16 ha anche rinominato middleware.ts in proxy.ts e l'export middleware in proxy, e la funzione proxy gira solo su Node.js (Vercel: Routing Middleware). Su Vercel le Edge Functions sono deprecate a favore delle Vercel Functions sul runtime Node.js, e ora entrambi i runtime girano su fluid compute con pricing Active CPU (Vercel: Edge Runtime).

I trade-off qui sotto descrivono ancora cosa fa bene ciascun runtime, e decidono ancora le route su Cloudflare Workers, Deno Deploy e in qualsiasi framework che mantenga lo split. Su Next.js e Vercel la scelta l'hanno già fatta per te: scrivi per Node e leggi la colonna Edge come una superficie di vincoli che non devi più aggirare.

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. Finché Next.js 16.3 non ha rimosso la scelta, la maggior parte dei SaaS che spediamo girava il middleware su Edge e le API CRUD su Node, e quello split copriva da solo il ~95% delle decisioni.

Confronto a colpo d'occhio

AsseEdge runtimeNode runtime
MotoreV8 isolate (sottoinsieme Web API)Processo Node.js completo
Cold start (P50)~100ms~250ms warm, ~860ms cold
Distribuzione geograficaPoP globaliUna o poche region
Pacchetti npmSolo edge-compatibleQualsiasi pacchetto npm
Limite bundle1-4 MB su VercelFino a 250 MB unzipped
Durata massima300s (streaming entro 25s)Fino a 800s su Vercel Pro
FilesystemNessunoCompleto
Moduli nativiNessunoSì
Connessioni persistentiNoSì (con riserve)
Stato su Next.js 16.3+Deprecato, l'export runtime viene rifiutatoDefault

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. Quel benchmark precede fluid compute, che Vercel applica ora per default al runtime Node con ottimizzazione del bytecode e pre-warming sui deploy di produzione: oggi il divario a caldo è più stretto di quanto fosse nel 2024 (Vercel: Fluid compute).

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, che ora è la questione proxy

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). Con Next.js 16 si è spinto oltre.

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, e dove il middleware Edge esiste ancora è proprio questo costo a giustificare le route di gating ad alto traffico.

Next.js 16 ha chiuso la questione rinominando il file. middleware.ts è diventato proxy.ts, l'export middleware è diventato proxy, e dentro quel file il segment config runtime viene rifiutato: il proxy gira sempre su Node.js (Next.js: proxy). Vercel costruisce il Routing Middleware su fluid compute, che porta ottimizzazione del bytecode e pre-warming in produzione sul path Node: con quello se n'è andato buona parte del vecchio vantaggio di cold start di Edge.

La nostra vecchia regola, middleware Edge come default, su Next.js 16 non ha più una leva da tirare. Scrivi il proxy per Node e tienilo sottile: leggi un cookie, fai un redirect, imposta un header. Il rinominarlo è il framework che ti dice di non metterci dentro la logica applicativa.

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 dove Edge esiste ancora promuoviamo una route solo quando misuriamo un guadagno di latenza che giustifichi la superficie di vincoli. Su Next.js 16.3 e successivi non c'è niente da promuovere: ogni route parte su Node. "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

Su una piattaforma che espone ancora entrambi i runtime, per una route nuova lo percorriamo in quest'ordine. Su Next.js 16.3 e successivi ogni ramo finisce su Node, quindi l'albero ora si legge come la mappa di quanto ti costava la colonna Edge, non come una scelta da fare:

  1. La route deve leggere la request e agire in meno di 50ms (geolocalizzazione, auth gate, rewrite)? Edge.
  2. La route fa streaming di token da un LLM? Edge.
  3. La route dipende da un singolo pacchetto npm che tira API Node? Node.
  4. La route fa una transazione DB multi-statement? Node.
  5. La route potrebbe girare più di 25 secondi prima di iniziare a streammare? Node.
  6. Il bundle della route è già oltre 1 MB? Node.
  7. Niente di sopra e la route è ad alto traffico? Edge, misurato.
  8. 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.

Aggiornato 2026-06-03: ripristinata la tabella di confronto (prima ridotta a testo).

Aggiornato 2026-09-13: Next.js ha deprecato l'Edge runtime, quindi da 16.3 runtime = 'edge' viene rifiutato, middleware.ts è ora proxy.ts e gira solo su Node, e Vercel ha spostato entrambi i runtime su fluid compute.

Domande frequenti

Articoli correlati

Studio

Inizia un progetto.

Scriviamo riguardo a ciò che costruiamo. Raccontaci cosa vuoi costruire tu.