<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jesus Manuel Garcia Torres</title>
    <description>The latest articles on DEV Community by Jesus Manuel Garcia Torres (@gartox).</description>
    <link>https://dev.to/gartox</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F766778%2F6939f151-fbef-426f-8953-d4d93afa6bd8.jpeg</url>
      <title>DEV Community: Jesus Manuel Garcia Torres</title>
      <link>https://dev.to/gartox</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gartox"/>
    <language>en</language>
    <item>
      <title>Stop Reaching for the Edge Runtime</title>
      <dc:creator>Jesus Manuel Garcia Torres</dc:creator>
      <pubDate>Sat, 29 Aug 2026 03:31:10 +0000</pubDate>
      <link>https://dev.to/gartox/stop-reaching-for-the-edge-runtime-4edg</link>
      <guid>https://dev.to/gartox/stop-reaching-for-the-edge-runtime-4edg</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffhubwmy061gree1sfrny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffhubwmy061gree1sfrny.png" alt="Stop reaching for the Edge Runtime — Fluid Compute is the default on Vercel now" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I want to show you a line of code. You almost certainly have it somewhere:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;runtime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;edge&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go look. I'll wait.&lt;/p&gt;

&lt;p&gt;Every time I open someone's Next.js repo, it's there. Usually on a streaming route, sometimes stamped across an entire API folder. And when I ask who put it there, nobody knows. The answer is always some version of &lt;em&gt;"it's faster, right?"&lt;/em&gt; or &lt;em&gt;"we needed it for streaming."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here's the thing: you weren't wrong. In 2022 that was a solid call. But the ground moved under that line, and now it's quietly costing you — Node APIs you can't reach for, libraries that explode at build time, and that one afternoon you lost to &lt;em&gt;"wait, why isn't &lt;code&gt;crypto&lt;/code&gt; here?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So let me walk you through what changed. Not the changelog version — the version that actually rewires how you think about your backend.&lt;/p&gt;




&lt;h2&gt;
  
  
  First, let's be fair to Edge
&lt;/h2&gt;

&lt;p&gt;I'm not here to tell you past-you was an idiot. Edge Runtime solved two genuinely painful things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;One request, one instance.&lt;/strong&gt; Every concurrent request needed its own container. Traffic spike? Enjoy your wall of cold starts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You paid for waiting.&lt;/strong&gt; Billing was GB-seconds of wall clock. That 900ms your function spent staring at Postgres doing nothing? You paid for it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Edge dodged both by running a stripped-down V8 isolate instead of a real Node process. Isolates boot in single-digit milliseconds. Beautiful.&lt;/p&gt;

&lt;p&gt;The price was Node itself. No &lt;code&gt;fs&lt;/code&gt;. No native modules. Half a &lt;code&gt;crypto&lt;/code&gt;. A long, miserable tail of npm packages that just don't run.&lt;/p&gt;

&lt;p&gt;You took that trade. It was often worth it.&lt;/p&gt;

&lt;p&gt;Then Vercel went and fixed the actual problem instead of routing around it. That fix is &lt;strong&gt;Fluid Compute&lt;/strong&gt;, and it's the default now.&lt;/p&gt;




&lt;h2&gt;
  
  
  The idea that made it click for me
&lt;/h2&gt;

&lt;p&gt;Sit with this one for a second, because everything else falls out of it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your backend spends most of its life waiting.&lt;/strong&gt; Waiting on Postgres. Waiting on Stripe. Waiting four full seconds while an LLM dribbles out tokens one at a time. And during every millisecond of that, the CPU you're paying for is doing absolutely nothing.&lt;/p&gt;

&lt;p&gt;Classic serverless shrugs at that. One request owns one instance, start to finish, idle or not.&lt;/p&gt;

&lt;p&gt;Fluid looks at the same idle CPU and sees &lt;strong&gt;inventory&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5htmsu13x583ok8dz2li.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5htmsu13x583ok8dz2li.png" alt="Figure 1 — Classic serverless runs one request per instance and pays for idle CPU. Fluid Compute reuses warm instances across concurrent requests, filling the I/O wait." width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A Fluid instance takes &lt;strong&gt;multiple concurrent requests&lt;/strong&gt;. Request 2 shows up while request 1 is blocked on I/O, lands on that same warm instance, and burns CPU that you were throwing in the bin.&lt;/p&gt;

&lt;p&gt;Two things follow immediately:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your cold starts mostly go away.&lt;/strong&gt; Instances get reused instead of provisioned per request. You get the thing you wanted from Edge — without handing back Node to get it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your in-memory state survives.&lt;/strong&gt; Database pool, cached JWKS, compiled regexes — they persist now, like on a normal server. Flip side, and I'd genuinely watch for this one: module-scope mutable state is now &lt;em&gt;actually shared&lt;/em&gt; between concurrent requests. Treat it the way you'd treat state on any long-lived server, because that's what you have now.&lt;/p&gt;

&lt;p&gt;If you take one sentence out of this post, take this one: &lt;strong&gt;it's a concurrency model change, not a speed trick.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  "But we need Edge for streaming"
&lt;/h2&gt;

&lt;p&gt;This is the one I hear most, and it's the expensive one — because it's exactly why Edge ends up on the routes that need Node the most.&lt;/p&gt;

&lt;p&gt;Streaming was never an Edge thing. &lt;code&gt;ReadableStream&lt;/code&gt;, Server-Sent Events, AI token streaming — all of it runs on the default Node.js runtime. Zero config. Watch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/api/chat/route.ts — no `runtime` export. Node.js. Streams beautifully.&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;streamText&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ai&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;streamText&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;anthropic/claude-sonnet-5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// via AI Gateway&lt;/span&gt;
    &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toUIMessageStreamResponse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prefer it raw, no framework? Same story:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ReadableStream&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chunk&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getChunks&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TextEncoder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`data: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n\n`&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/event-stream&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Cache-Control&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;no-cache&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keep-alive&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now flip it around. Your AI route is the &lt;strong&gt;worst&lt;/strong&gt; thing you could put on Edge, not the best. It runs long. It's almost pure I/O wait. It wants SDKs, tracing, a database driver — the whole Node ecosystem.&lt;/p&gt;

&lt;p&gt;That's not an edge case for Fluid. That's the exact shape it was built for.&lt;/p&gt;




&lt;h2&gt;
  
  
  "Edge is cheaper though"
&lt;/h2&gt;

&lt;p&gt;Not anymore, and this is the part I think most people missed: Fluid changed the &lt;strong&gt;billing model&lt;/strong&gt;, not just the runtime.&lt;/p&gt;

&lt;p&gt;Vercel Functions now bill on &lt;strong&gt;Active CPU time + provisioned memory + invocations&lt;/strong&gt;. Not GB-seconds of wall clock.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3lc19xor7bx81r3df3qi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3lc19xor7bx81r3df3qi.png" alt="Figure 2 — A 2-second request that mostly waits on an LLM and a database only bills for the slices where the CPU is actually working." width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If your function is CPU-bound, this barely moves. If it's I/O-bound — so, most of your functions, and &lt;em&gt;every single&lt;/em&gt; AI function you've ever written — the gap between wall clock and active CPU is huge. And you've stopped paying for it.&lt;/p&gt;

&lt;p&gt;Then instance reuse compounds it. Three concurrent requests on one warm instance is one block of provisioned memory, not three.&lt;/p&gt;




&lt;h2&gt;
  
  
  "Middleware has to be Edge"
&lt;/h2&gt;

&lt;p&gt;Two things to untangle here, and they trip people up separately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next.js middleware runs full Node.js now.&lt;/strong&gt; That edge-only constraint is gone. Middleware and Edge Functions are both Vercel Functions under the hood these days.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Routing Middleware is a different product.&lt;/strong&gt; Framework-agnostic, runs before the cache, works with SvelteKit, Nuxt, Astro, or a pile of static files. It is &lt;em&gt;not&lt;/em&gt; Next.js middleware. Keep them separate in your head when you're reading docs, it'll save you an hour.&lt;/p&gt;

&lt;p&gt;And while I have you: &lt;strong&gt;ISR isn't Next-only either.&lt;/strong&gt; SvelteKit, Nuxt, and Astro all get it on Vercel.&lt;/p&gt;




&lt;h2&gt;
  
  
  The limits you're still designing around
&lt;/h2&gt;

&lt;p&gt;This is my favorite part, because I keep finding architecture decisions that are load-bearing on constraints that stopped existing.&lt;/p&gt;

&lt;p&gt;If any of these shaped a design of yours, go reopen it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm51xb23vsyezti0edc10.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm51xb23vsyezti0edc10.png" alt="Figure 3 — 300s max duration on every plan, 5 GB package size, 100 MB request bodies, Node 24 LTS, WebSockets, plus Bun and Rust runtimes." width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two of them trigger a redesign more often than the rest:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5 GB package size.&lt;/strong&gt; Up from 250 MB. That's a 20× jump, and it means Playwright, Puppeteer, Python data and ML libraries, heavy image processing. If you've got a "we'll need a separate container for this" conversation on the calendar, you might be able to cancel it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;100 MB request bodies.&lt;/strong&gt; Up from 4.5 MB. Uploads, fat webhook payloads, document intake — straight into a Function. You can stop doing the signed-URL dance you only ever did to dodge a body limit.&lt;/p&gt;

&lt;p&gt;And WebSockets work now. So if your reflex is "we'll need Pusher for this one feature," give it a second look first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;experimental_upgradeWebSocket&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@vercel/functions&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;experimental_upgradeWebSocket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`echo: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Needs Fluid Compute — which, again, you already have. Plain &lt;code&gt;ws&lt;/code&gt; and Socket.IO work too.&lt;/p&gt;




&lt;h2&gt;
  
  
  Do this Monday morning
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Find your Edge exports.&lt;/strong&gt; Run this right now, seriously:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; &lt;span class="s2"&gt;"runtime = ['&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;]edge['&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;]"&lt;/span&gt; &lt;span class="nt"&gt;--include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"*.ts"&lt;/span&gt; &lt;span class="nt"&gt;--include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"*.tsx"&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For every hit, ask yourself one question: what is this buying me? If the answer is "streaming" or "it felt faster" — delete the line. Test it, obviously. But expect it to just work, with more available to it than it had before.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Check your Node version.&lt;/strong&gt; Node 24 is the LTS default. Node 18 is deprecated. If you're pinned to 18, that's a ticket, write it now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Go find your workarounds.&lt;/strong&gt; Anything you built to dodge a 4.5 MB body, a 250 MB bundle, or a 60-second timeout deserves a fresh look.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Try &lt;code&gt;vercel.ts&lt;/code&gt; instead of &lt;code&gt;vercel.json&lt;/code&gt;.&lt;/strong&gt; Typed config, real logic, env access:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// vercel.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;VercelConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@vercel/config/v1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;VercelConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;framework&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nextjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cacheControl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/static/(.*)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;public&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;maxAge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1 week&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;immutable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;crons&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/cleanup&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0 0 * * *&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  When I'd still use Edge
&lt;/h2&gt;

&lt;p&gt;I'm not telling you it's dead. I still reach for it on genuinely trivial, latency-critical work right at the boundary: a header rewrite, a geo redirect, an A/B bucket assignment, a feature flag lookup. Small, CPU-light, no Node dependencies, runs before anything else touches the request.&lt;/p&gt;

&lt;p&gt;That's a narrow band, though. Anything that touches a database, an SDK, a file, or a model? That's Fluid.&lt;/p&gt;

&lt;p&gt;Here's the heuristic I'd give you: &lt;strong&gt;Edge is a specialist tool for the request boundary. It is not the default for your application code.&lt;/strong&gt; Somewhere along the way we all flipped that around, and a lot of us are still carrying the flip.&lt;/p&gt;




&lt;h2&gt;
  
  
  The bit I actually want you to remember
&lt;/h2&gt;

&lt;p&gt;Fluid Compute isn't a Vercel feature to file away. It's a category shift.&lt;/p&gt;

&lt;p&gt;We spent years accepting that serverless &lt;em&gt;meant&lt;/em&gt; one-request-per-instance, cold starts, and paying for idle time. Then we built elaborate, clever workarounds on top of those assumptions — and got good at maintaining them.&lt;/p&gt;

&lt;p&gt;The assumptions changed. The workarounds didn't. A lot of what you're maintaining right now is complexity you're paying for out of habit.&lt;/p&gt;

&lt;p&gt;Go delete a line of code. Tell me what breaks.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by Jesús García at &lt;a href="https://xpectrelabs.com" rel="noopener noreferrer"&gt;XpectreLabs&lt;/a&gt;. Run that &lt;code&gt;grep&lt;/code&gt; and drop what you find in the comments — I'm genuinely curious how many of you have that line sitting on an AI route.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>vercel</category>
      <category>serverless</category>
      <category>nextjs</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
