← Siddhant Goswami

Where Code Runs

Seven easy pieces on servers, the cloud, serverless, and the art of choosing where to run things

A first-principles guide that builds the entire idea of deployment from the physics of a running machine upward: through the process that holds your program in memory, the always-on server, the rented computer we call the cloud, the machine that appears only when a request arrives, the special weight of models that need GPUs, and the engineering judgment of choosing where each thing should live and on whose hardware.

For builders, founders, engineers, and technical leaders

June 2026 · Reading time: about one hour

This handbook is the deployment companion to Where Data Lives in the same series. That handbook asks where your data should live. This one asks where your code should run.

How to read this

The seven pieces are in order on purpose. Each one starts from a problem you can feel, derives the idea from that problem, and only then gives it a name. Read them in sequence the first time, because every piece stands on the one before it. Come back to Pieces Six and Seven on their own later, as a checklist, when you are actually choosing a provider or splitting development from production. Nothing here asks you to memorise a rule. The whole point is that once you can derive where something should run, you never have to.

The seven pieces

  • One. What “running” actually means. A process, memory, a CPU, and a machine: what really happens when you hit run, and why your laptop is already a server.
  • Two. The always-on machine. What production demands of a computer, how those demands define a server, and the fork between owning one and renting one.
  • Three. Deterministic work and hungry work. The two axes that decide everything: how predictable a workload is, and how heavy, including why a model must live in GPU memory.
  • Four. Rent or own. Cloud, on-prem, and your laptop weighed lever by lever, plus the third path a model gives you: calling an API instead of holding the weights.
  • Five. The machine that appears on demand. Serverless functions: the three costs they trade away, and how to choose between Vercel, Supabase, Cloudflare, Lambda, and the rest, with current prices.
  • Six. Choosing a provider. Not a brand war but a scorecard: the axes to rate any provider on, and the habit of writing your constraints down before you look.
  • Seven. Two worlds: development and production. Why the machine you build on and the machine users touch want opposite things, and how to keep them the same shape at different sizes.

Contents

PIECE ONE

What “running” actually means

What actually happens when you hit run, and why your laptop is already a server.

You write a program. You hit run. Something happens: a window opens, a number prints, a web page appears at localhost. You close the laptop lid and it all stops. A friend in another city cannot see any of it. Before we say a single word about cloud or servers, we should be honest about what actually happened when you hit run, because every later decision in this handbook is built on it.

The three things a running program needs

Strip it down and a running program is asking for exactly three things from the world.

  • A processor to do the work. Code is a list of instructions. Something physical has to carry them out, one after another. That something is the CPU, the chip that executes instructions. Without it, code is just text sitting in a file.
  • Memory to hold the work in progress. While the program runs it has to remember things: the current value of each variable, where it is in the list of instructions, the half-built web page. This live scratchpad is RAM, fast temporary memory. RAM is quick and forgetful. Cut the power and it is wiped clean.
  • A program actually in motion. The file on disk is not running. When you hit run, the machine loads that file into RAM and the CPU starts executing it. That live, executing instance is a process. The file is the recipe. The process is the cooking.

So “running” is not mysterious. It means a process, living in RAM, driven by a CPU, on some physical machine. And now name the obvious truth that follows: that machine is your laptop. Your laptop, right now, is a server. It serves your program to exactly one user, you, and only while it happens to be awake.

Why only one user, and only while awake

Two more problems you can feel, each pointing straight at a missing piece.

  • Your friend cannot reach it. The program lives at localhost, which means “this machine, talking to itself.” For anyone else to reach it, the machine needs an address on the network that the outside world can dial, and a name pointed at that address. The address is an IP address, the human-friendly name is a domain. Your laptop usually has neither in a stable, reachable form.
  • Close the lid and it dies. RAM is wiped, the process ends, the CPU stops. A program that only runs while you are watching it is a demo, not a service.

The shape of every later question

We now have the vocabulary, derived rather than memorised: process, RAM, CPU, machine, address.

THE MACHINE

Every question in the rest of this handbook is a question about that machine. Whose machine is it? Is it always awake? Is it reachable? Is it big enough? Is it the right kind of machine for this kind of work? Hold that frame and the cloud stops being weather. Deployment is just the practice of putting your process on a machine that is awake, reachable, and the right size, and then keeping it that way.

THE ONE IDEA

Running code means a process holding memory on a powered, addressable machine. Your laptop already is that machine. Everything that follows is just about choosing a better one and deciding whose it should be.

PIECE TWO

The always-on machine

What production demands of a computer, and the fork those demands force: own it, or rent it.

The problem, in one line: you want other people to use the thing you built, at any hour, without you holding the lid open. From Piece One we already know exactly what that requires. So let us just list the requirements honestly and then notice that we have quietly described a new kind of machine.

What “in production” actually demands

  • Always awake. It cannot sleep when you sleep. It runs twenty-four hours a day, seven days a week, whether or not anyone is looking.
  • Always reachable. It holds a stable public address so a stranger’s browser can find it, and keep finding it tomorrow.
  • Survives small disasters. A power flicker, a network blip, a crashed process: it should come back without you standing over it.
  • Somebody’s responsibility. Disks die. Software needs patching. The building needs power and cooling. Keeping this machine healthy is a real, ongoing job that belongs to someone.

A machine set up to meet those four demands has a name: a server. Notice we did not start from the word. We started from what production needs and arrived at the word. A server is not a special breed of computer. It is an ordinary computer handed a job: stay awake, stay reachable, stay healthy, and serve many people at once.

The fork the whole handbook turns on

You need an always-on machine. There are exactly two ways to have one.

  • You can buy the machine and run it yourself. You own the box. It sits in your office, or in a rack in a data centre whose space you rent. You plug it in, connect it, install everything on it, and you are the one who drives to it at 3am when a disk fails. This is running on your own premises, on-prem for short, and at small scale it can be as literal as an old desktop in the corner that you simply never switch off.
  • You can rent a machine from someone who owns thousands of them. You never see the box. You ask for a computer of a certain size and it appears in a few minutes, already powered, networked, and cooled, in a building you will never visit. You pay by the hour for as long as you keep it. This is the cloud. The cloud is not a metaphor and it is not the sky. It is other people’s computers, in other people’s buildings, rented to you by the hour.

The first real tradeoff, seen plainly

Owning means a large payment up front to buy the hardware, then small running costs after that. Renting means nothing up front, but a meter that ticks for every hour you keep the machine. The money words for this are capital expenditure (capex, the big upfront purchase that you then own) and operating expenditure (opex, the ongoing pay-as-you-go cost). We are not choosing between them yet. We are only naming the lever, because almost every later argument in this handbook, for a web app or for a language model, in development or in production, turns out to be this one lever pulled under different conditions.

A quick note on words people blur. “Hosting,” “deploying,” “putting it on a server,” and “running it in the cloud” all point at the very same act from Piece One: getting your process onto an always-on, reachable machine. The only thing that changes between them is whose machine it is and how you pay for it.

THE ONE IDEA

A server is an ordinary computer handed the job of staying awake, reachable, and healthy for many users at once. You can own that computer (on-prem) or rent it by the hour (cloud). That single own-or-rent choice is the seed of everything that follows.

PIECE THREE

Deterministic work and hungry work

The two axes that decide everything: how predictable a workload is, and how heavy, including why a model must live in GPU memory.

Take two programs. The first is an ordinary web app: a user submits a form, the server checks a rule, writes a row to a database, and sends back a page. The second is a large language model answering a question. Both are “a process on a server.” But they behave so differently that lumping them together is the single most expensive mistake people make when they choose where to run things. The difference lives on two axes. Learn to read any workload on these two axes and most of the deployment decision makes itself.

Axis one: is the work deterministic?

A piece of work is deterministic when the same input always produces the same output, through fixed and known steps, at a predictable cost. Add two numbers, look up a user by ID, validate an email, charge a card: same input, same result, every time, and you can predict almost exactly how much CPU and memory one request will burn. The opposite is probabilistic work: the output is a judgment rather than a lookup, and it can differ from one run to the next. A model deciding what to say next is the clearest example there is. This is the same boundary that decides what you let a computer judge and what you pin to a hard rule, and here it does a second job: it tells you how predictable your machine’s load will be.

Axis two: how heavy is one unit of work?

Heaviness is simply how much hardware a single request consumes: how much CPU time, how much memory, and, crucially, whether it needs a special kind of chip at all. Our web app is light. One request is a pinch of CPU and a few megabytes of memory, and a modest machine serves hundreds of users at once. A large language model is heavy in a way that is hard to overstate, and to see why, we have to look at what the model physically is.

Why a model is so heavy: the weights

A trained model is, underneath, a giant grid of numbers called weights (also called parameters). When people say a model is “7B” or “70B,” they mean seven billion or seventy billion of those numbers. To answer even one question, the machine has to hold all of those numbers in fast memory and do arithmetic across them. A rough floor: each parameter takes about two bytes in a common precision, so a 7B model needs roughly 14 GB of fast memory just to sit there ready, and a 70B model needs on the order of 140 GB, before you count the extra working memory each request adds on top. That is not a little more than a web app. It is thousands of times more.

Why an ordinary chip is the wrong chip

A CPU is a brilliant generalist: a few powerful cores that handle varied tasks one after another, very fast. A model’s work is the opposite shape: the same simple arithmetic repeated across billions of numbers, all at once. The chip built for that shape is the GPU, a processor with thousands of small cores that do the same operation in parallel, and its on-board fast memory is called VRAM.

FIRST PRINCIPLE

A model wants to live in GPU memory. If the weights do not fit in VRAM, the system spills over to slower memory and throughput collapses. So the first practical question for any model is blunt: does it fit in the VRAM you actually have?

Two honest ways to make a model fit, named so they stay un-mysterious. You can shrink the numbers, called quantization, storing each weight in fewer bits (say one byte or less instead of two), trading a little quality for a large drop in memory. Or you can split one model across several GPUs. Both carry costs. The point for now is only that “will it run” is a memory question first.

Training versus inference, so the words do not trip you

Two very different jobs share the word “running.” Inference is using a trained model to answer, which is what happens when a user chats with it. Training is building or adjusting the model in the first place. Training is far heavier and far longer, needing many GPUs for hours or weeks. Most teams never train anything; they run inference on a model that someone else trained. Whenever this handbook talks about running an LLM in production, it means inference unless it says otherwise.

The map this gives you

Put any workload on the two axes and the implication is immediate.

  • Deterministic and light (the web app, the billing service, the form handler): predictable load, ordinary hardware, runs almost anywhere, cheaply. You will barely think about the machine at all.
  • Probabilistic and heavy (the LLM): spiky and unpredictable load, special and expensive hardware, and the machine becomes the entire problem. Where it runs, on what chip, at what cost per answer: those questions now dominate every decision.

Here is the same contrast laid side by side.

Ordinary web app Large language model
Determinism Deterministic: same input, same output, fixed steps Probabilistic: output is a judgment, varies run to run
Weight per request Light: a little CPU, a few megabytes of RAM Heavy: billions of numbers held in memory at once
Chip it wants An ordinary CPU is plenty A GPU, with the weights fitting inside VRAM
Load shape Steady and easy to predict Spiky and hard to predict
Where the hard decision lives Barely matters; runs almost anywhere The machine is the whole decision

The two axes made concrete: a deterministic, light workload against a probabilistic, heavy one.

That gap is why the next three pieces exist. Choosing where to run a light, deterministic app is easy. Choosing where to run a heavy, probabilistic one is the real subject, and it is mostly a fight over GPUs and what they cost.

THE ONE IDEA

Read every workload on two axes: how predictable it is, and how heavy one request is. Light and predictable runs anywhere. Heavy and unpredictable, like an LLM that must fit inside GPU memory, makes the machine the whole decision.

PIECE FOUR

Rent or own

Cloud, on-prem, and your laptop weighed lever by lever, plus the third path a model gives you.

Now we choose. We have the fork from Piece Two (own the machine, or rent it) and the two axes from Piece Three (how predictable, how heavy). Put them together and the choice stops being a matter of taste and starts being a matter of your actual conditions. Here are the levers, each one a concrete pain rather than a slogan.

Lever one: do you know tomorrow’s load?

Traffic is rarely flat. A launch, a festival sale, a post that travels, an enterprise pilot: demand jumps and falls. If you own the machine, you must buy for the highest peak you expect, then watch that expensive hardware sit nearly idle the rest of the time. If you rent, you can ask for ten machines for the sale and hand nine of them back the next morning, paying only for the hours you actually used. The name for this is elasticity, the ability to grow and shrink capacity quickly, and it is the single strongest argument for renting when demand is uncertain.

Lever two: steady high use, or bursty low use?

Now flip the same lever the other way. If your load is large and steady, running flat out month after month, the rental meter never stops, and the per-hour price you are paying starts to look expensive next to simply owning the box. Owned hardware is a large cost once and then cheap to keep running. Rented hardware is nothing up front and then a bill every hour, forever. Steady and heavy favours owning. Spiky and uncertain favours renting. This is the capex-versus-opex lever from Piece Two, now with a condition attached to each side.

Lever three: who fixes it at 3am?

A machine you own is a machine you maintain: failed disks, security patches, cooling, power, networking, the physical building. At small scale that is a weekend lost. At large scale it is a team and a facility. When you rent from a cloud, that entire burden becomes the provider’s job, and part of what you are paying for is the right to never think about a dead disk again. The more you would rather build your product than run a data centre, the more renting earns its premium.

Lever four: where must the data live, and can it leave?

Some data is bound by law or contract to stay inside a country, inside a company, or off the public internet entirely. A hospital’s records, a bank’s core ledger, a defence system: these can carry hard rules about where they may sit and who may touch them. If your data cannot leave your building, a public cloud may simply be off the table for that workload, and owning the hardware is not a preference but a requirement. The pull that heavy, sensitive data exerts on where the rest of the system must sit has a useful name: data gravity. Heavy, regulated, immovable data drags compute toward it.

Lever five: how close to the user must it be?

Every request travels a physical distance, and distance is time. If your users are in India and your server is in Virginia, every interaction pays a tax in milliseconds for the round trip. For many apps that tax is invisible. For a live, chatty experience it is felt in the body. The lever is latency, and it usually argues for running near your users, which a large cloud makes easy (pick a nearby region) and a single owned office makes hard.

The synthesis: a crossover, not a winner

Lay the levers side by side and a shape appears. Renting (cloud) wins when demand is uncertain or spiky, when you are early and want to move fast, when you would rather not run hardware at all, and when your users are spread across the world. Owning (on-prem) wins when load is large and steady, when the per-hour math has clearly crossed over, when data cannot leave, and when you have the people to run it.

FIRST PRINCIPLE

Steady and heavy favours owning. Spiky and uncertain favours renting. Most teams begin on the rent side, because at the start everything is small and uncertain and the value of moving fast dwarfs the hourly premium. Some workloads cross over to owning as they grow large, steady, and sensitive. The skill is knowing which conditions move you across the line.

The LLM has a third option, and it is usually the right one

For an ordinary app, rent-or-own covers it. For a model, there is a prior question that often dissolves the whole debate: do you need to hold the model at all? Three choices, in rising order of how much you take on.

  • Call someone else’s model over an API. A provider holds the weights on their GPUs. You send text and get text back, paying per use. You own no GPUs, fit nothing into VRAM, and skip the entire hardware problem from Piece Three. This is the fastest path, and for most teams most of the time, it is the right one.
  • Rent GPUs and run the model yourself on them. You take open model weights, place them on rented cloud GPUs, and serve the inference. You now own the VRAM-fitting problem and the bill, but you control the model, the data path, and any tuning.
  • Own the GPUs and run the model on your own hardware. The on-prem case from above, applied to a model. Justified mainly by the same forces: very high steady volume, data that cannot leave, or strict latency.

Here are the three, side by side.

Option What you run Cost shape Best when
Hosted API Nothing; you send text, you get text Pay per token; starts near zero, rises smoothly with use Low or spiky volume, early stage, you want speed and no ops
Rented GPUs The model, on cloud GPUs you rent Large fixed cost per hour, busy or idle High steady volume, or you need control and privacy without owning iron
Owned GPUs The model, on your own hardware Big upfront purchase, then cheap to keep running Very high steady load, strict data residency, or hard latency

Three ways to run a model, from holding nothing to owning the hardware.

How to actually decide between API and self-hosting

Make it a calculation, not a feeling. Hosted APIs price per unit of text, per token, so your cost rises smoothly with use and begins at almost nothing. Self-hosting, whether on rented or owned GPUs, costs a large and mostly fixed amount per hour whether the GPU is busy or idle, so your cost starts high and only becomes cheap if you keep that GPU genuinely busy. The crossover question is therefore one question: is your volume high and steady enough to keep an expensive GPU saturated? If yes, self-hosting can win on price and hands you control and privacy as well. If no, meaning low, spiky, or just starting out, the API is both cheaper and far less work. Two forces can override the math entirely: privacy (data that may not leave your environment pushes you toward self-hosting) and the need to deeply customise or fine-tune a model you fully control.

THE ONE IDEA

Cloud wins on uncertainty, speed, and spread; on-prem wins on steady scale, control, and data that cannot move. For models, first ask whether you can just call an API: pay-per-token starts cheap and stays simplest, while self-hosted GPUs only pay off when you can keep them busy, or when privacy and control force your hand.

PIECE FIVE

The machine that appears on demand

What serverless really is, the three costs it trades away, and how to choose a runtime, with current prices.

In Piece Two we built the always-on server, and in Piece Four we decided whether to rent it or own it. Either way you are left with a machine that runs around the clock, and two costs come with that. You pay for the machine whether or not anyone is using it, and most machines sit mostly idle. And you carry the operational weight: scaling under load, restarting on a crash, keeping it alive. There is a way to run code that removes both. Start, as always, from the problem and not the label.

What you actually want

You have a chunk of code that needs to run only sometimes: handle a request, process a webhook, call a model. What you want is for someone else to own a single sentence: make a machine appear when a request arrives, run my code, tear it down, and bill me only for the time it actually ran. That is the whole idea. The machines still exist. You simply stop managing them. The name the industry settled on is serverless, and it is slightly dishonest, because there is still a server. What is gone is your relationship with it.

FIRST PRINCIPLE

Serverless does not remove the server. It removes your ownership of it. You write the function; the platform makes a machine appear per request, runs it, and bills only for the time your code ran. The reward is no idle cost, automatic scaling, and no operations.

The three costs you trade for that

That trade is not free. It costs exactly three things, and every limitation you will ever hit on any serverless platform is one of these three.

  • Cold starts. If no machine is already warm, one has to be created before your code can run. The first request after a quiet spell pays that startup tax.
  • Execution limits. The platform will not let one invocation run forever. There is a ceiling on how long a single call may take.
  • Statelessness. Nothing survives in memory between invocations. Any state you need, a session or a counter or a file, has to live in a database or a cache, never in the function.

Hold those three. Cold-start speed, how long a job may run, and where state lives are the only things that ever really differ between the products below.

Two questions that explain the whole landscape

Every serverless product, whether from Vercel, Supabase, Cloudflare, or AWS, is just a set of answers to two questions.

  • Where does it run? In one region near your data, or in many locations near your users (the edge)?
  • What runtime executes it? A full container or microVM with a complete operating system and the entire package ecosystem, or a lightweight isolate that boots instantly but exposes only web-standard APIs and a slice of CPU?

Those two axes decide everything downstream: cold-start speed, which packages run, latency, and cost. They also split the runtimes into two families.

Runtime family How it runs Cold start The catch
Container or microVM (AWS Lambda, Vercel) A real operating system boots: full Node or Python, any package, big memory, long runs Roughly 100 ms to a few seconds while the sandbox boots Startup latency is the price of the power
V8 isolate (Cloudflare, Deno, Supabase) A fresh JavaScript context inside a process that is already running, with no boot Single-digit milliseconds Web APIs only, limited CPU and memory, not every package runs

The two runtime families. Almost every difference in cold-start speed, package support, and cost traces back to this split.

THE MACHINE

Serverless is the same machine from Piece One, now invisible. A process still holds memory on a CPU somewhere. You have simply handed the whole question of whose machine it is, and whether it stays awake, to the platform. The three costs are what that machine charges you for never having to think about it.

Vercel Functions: the backend of the app it already hosts

Vercel runs the function next to the frontend it is already hosting. A Vercel function is a Node function that runs in a single region (Washington DC by default) and scales automatically. The older standalone Edge Functions product has been wound down; today Vercel steers you to the Node runtime, with the edge runtime surviving mainly for routing middleware. The shift that matters is Fluid Compute, now the default: one warm instance handles many concurrent requests, and billing moved to Active CPU, so the seconds a function spends waiting on a database query or a model call are not charged for CPU (though provisioned memory is billed while the instance is alive). A typical use is the API routes, server-rendering, form handlers, and model-proxy endpoints of a Next.js app, in one repository, with a preview URL for every pull request. Functions run to 300 seconds by default and up to 13 minutes on paid plans, with the full Node ecosystem and large memory available.

Pricing (mid-2026). Hobby is free for non-commercial use: about 100 GB of transfer, 1 million invocations, and 4 hours of Active CPU a month, with a 60-second function ceiling. Pro is $20 per seat per month and includes a $20 usage credit, 1 TB of transfer, and the 13-minute ceiling. Beyond the credit, Active CPU is about $0.128 per hour, provisioned memory about $0.0106 per GB-hour, and bandwidth $0.15 per GB over the first terabyte.

  • Strengths. Best-in-class framework integration, especially Next.js; instant preview deploys; the full Node ecosystem and large memory; and Active CPU billing that does not charge for I/O wait.
  • Watch out for. It runs in one region, not at the edge; bandwidth, Active CPU, and provisioned memory are separate meters that surprise teams; and the Hobby tier forbids commercial use.
  • Choose it when. Your frontend is on Vercel, you want the backend in the same repository, and the function needs the full Node ecosystem or longer runs.

Supabase Edge Functions: server logic next to your data

Supabase runs TypeScript functions on a Deno runtime, as V8 isolates, inside your Supabase project’s own region, right next to your Postgres, Auth, and Storage. (This is a recent and important shift: these functions used to be globally distributed, and they now run in your project’s region so they sit next to the data they touch.) Cold starts are in the few-hundred-millisecond range. The constraints are real and tight: 2 seconds of actual CPU time per request, a 150-second wall-clock timeout before a 504, and a 20 MB bundle after the CLI packs it. They are open-source and portable: the same code runs locally and on any Deno-compatible host, including a self-hosted Supabase. A typical use is a Stripe or GitHub webhook receiver, an authenticated endpoint that must hold a secret off the browser, on-demand image generation, or lightweight model inference.

Pricing (mid-2026). Included in every plan and billed only on invocations. The free plan includes 500,000 invocations a month; Pro, at $25 a month, includes 2 million; beyond that it is $2 per additional million. Failed and cold-started invocations both count.

  • Strengths. First-class access to your Postgres, Auth, and Storage; it trivially holds secrets off the client; and the open Deno runtime means no lock-in and local-first development.
  • Watch out for. The 2-second CPU wall is a hard ceiling; this is not for heavy compute, long runs, or Node-only libraries; and on the free plan the whole project pauses after a week idle.
  • Choose it when. Supabase is already your database, and you want trusted server logic and webhooks sitting next to that data.

Cloudflare Workers: the strongest general-purpose edge

Workers is the one to reach for first on a greenfield edge API. It uses the same V8-isolate model as Supabase’s runtime, but runs in more than 300 locations worldwide, global by default, with cold starts under 5 milliseconds and CPU-time billing so idle and I/O wait cost nothing. The real reason to choose it is the platform around it: D1 (serverless SQLite), Workers KV, Durable Objects for stateful coordination at the edge, R2 object storage with zero egress fees, and Workers AI for inference at the edge. A typical use is a global low-latency API or proxy, an auth and caching layer in front of a heavier backend, or serving media without paying egress. Each isolate has 128 MB of memory, CPU time is configurable up to 5 minutes on the paid plan, and the runtime is constrained: JavaScript, TypeScript, and WebAssembly first, with Node-specific APIs like the file system or child processes unavailable, though Node compatibility has improved a great deal.

Pricing (mid-2026). The free plan gives 100,000 requests a day. The paid plan is $5 a month and includes 10 million requests and 30 million CPU-milliseconds; beyond that it is $0.30 per additional million requests and $0.02 per additional million CPU-milliseconds. Bandwidth and R2 egress are free, which at media scale is the headline saving over Vercel and most others.

  • Strengths. The fastest cold starts, true global distribution, zero egress fees, and an unusually complete edge platform (SQLite, key-value, stateful objects, storage, and AI) from one vendor.
  • Watch out for. A constrained V8 runtime: not every Node package runs, CPU per request is limited, and heavy or long compute does not belong here.
  • Choose it when. Latency is a product metric, you want edge compute and storage from one vendor, or egress fees on media are bleeding you. Supabase itself recommends pairing the two: Workers at the front, Supabase functions for the database logic.

AWS Lambda: the call once you outgrow the edge

Lambda is the right tool when the edge constraints become the problem. It offers up to 10 GB of memory and a 15-minute ceiling, runtimes across Node, Python, Java, Go, .NET, and Ruby, and the deepest cloud integration of any option here: private-network (VPC) access, queue and event triggers (SQS, SNS, EventBridge), and database streams. A typical use is heavy or long-running compute (model inference, video or PDF processing, data pipelines), an event-driven backend, or anything already living inside an AWS account. The cost is operational weight and cold starts of roughly 1 to 5 seconds on heavier runtimes; and since August 2025, AWS bills the cold-start initialisation phase too, though SnapStart removes it for Java, Python, and .NET at no extra charge.

Pricing (mid-2026). A perpetual free tier of 1 million requests and 400,000 GB-seconds a month. Beyond it, $0.20 per million requests and about $0.0000167 per GB-second on x86, with ARM (Graviton) roughly 20 percent cheaper. Watch the companions: API Gateway, CloudWatch logs, and NAT Gateway egress routinely add more than the Lambda line itself.

  • Strengths. The widest runtime and memory range, 15-minute runs, and the deepest cloud integration of any option here, with a free tier that never expires.
  • Watch out for. Operational weight, cold starts on heavy runtimes, and a bill whose supporting services (gateway, logs, egress) often dwarf the compute.
  • Choose it when. The work is heavy, long, event-driven, or already entangled in AWS, and edge constraints have become the wall you keep hitting.

Two more, briefly: Deno Deploy and containers

Deno Deploy

The managed, globally distributed home for the same Deno and V8-isolate lineage that Supabase functions are built on: web-standard APIs, npm compatibility, and a built-in key-value store (Deno KV). Its free plan is generous: 1 million requests and 100 GB of outbound bandwidth a month, with a 50-millisecond CPU ceiling per request, then usage-based paid tiers. Choose it when you want Deno-native edge compute without adopting the rest of Supabase. The same isolate constraints apply, and the ecosystem and region count are smaller than Cloudflare’s.

When the answer is not serverless: container platforms

Some workloads fight the model itself. A stateful WebSocket server, a background worker that runs for minutes, a queue consumer that should stay alive: these want a persistent process, and no amount of timeout configuration fixes a model designed to tear the machine down between requests. Reach for a container platform, where your code runs as a long-lived process you control. The three common homes are Railway (the fastest path from a Git push to a live URL, usage-based and billed by the second), Render (predictable flat plans, with managed Postgres, cron, and background workers as first-class types), and Fly.io (Firecracker microVMs you can place in many regions, the closest of these to running your own globally distributed infrastructure). All three retired their always-free tiers for new accounts: Railway starts around $5 a month, Render’s web services from $7 a month to stay warm, and Fly.io is usage-based from roughly $5, where a small always-on app with a database typically lands between $10 and $30. The tradeoff is the one serverless removed: you pay for the process whether or not it is serving, and you are back to caring about the machine.

The real insight: app-side or data-side

It is usually not either/or. The honest question is where a given piece of logic belongs: next to your app, or next to your data? The most common production stack puts the framework app and its route handlers on Vercel, uses Supabase for Postgres and Auth, and runs Supabase edge functions for the database-adjacent logic and webhooks. These are complementary layers, not substitutes. And a stale framing to drop: if you are still asking “Vercel edge versus Supabase edge,” note that Vercel has retreated from edge-by-default and now recommends its edge runtime mainly for middleware, while Supabase functions run regionally, next to your data. The accurate 2026 reading is that true global edge is Cloudflare’s, data-adjacency is Supabase’s, and framework integration is Vercel’s.

Platform Where and runtime Pricing entry (mid-2026) Choose it for
Vercel Functions One region, full Node (Fluid Compute) Free (non-commercial); Pro $20/seat plus usage Next.js and framework apps; full Node; longer runs
Supabase Edge Functions Your project region, Deno isolate Free 500K/mo; Pro $25/mo (2M); then $2/M Trusted logic and webhooks next to your data
Cloudflare Workers 300-plus locations, V8 isolate Free 100K/day; Paid $5/mo (10M req, 30M CPU-ms) Global low latency; edge storage; zero egress
AWS Lambda AWS regions, container or microVM Free 1M req plus 400K GB-s; then $0.20/M plus GB-s Heavy, long, event-driven, AWS-native work
Deno Deploy Global edge, Deno isolate Free 1M req plus 100 GB; then usage Deno-native edge without the rest of Supabase
Containers (Fly, Railway, Render) Regions you choose, any container From about $5 to $7/mo; no free tier Always-on or stateful processes

Serverless options and their current entry pricing. Prices move; treat these as mid-2026 reference points and confirm before you budget.

THE ONE IDEA

Do not ask which serverless product is best. Ask where the logic belongs and what it needs. Next to the app or next to the data, on the edge or in a region, in a full runtime or a fast isolate. It is rarely either/or: the common stack uses several of these layers at once.

THE DECISION MAP

Next to your framework app, full Node or longer runs: Vercel. Next to your Supabase data, small and fast, holding a secret: Supabase Edge Functions. Global low latency, edge storage, zero egress: Cloudflare Workers, the strongest greenfield default. Heavy, long, event-driven, or already in AWS: Lambda. Deno-native edge without the rest of Supabase: Deno Deploy. Genuinely always-on or stateful: a container (Railway, Render, Fly.io), not a function. And it is rarely either/or: app on Vercel, data on Supabase, edge functions for the logic in between.

PIECE SIX

Choosing a provider

Not a brand war but a scorecard: the axes to rate any provider on, and the habit of writing your constraints down first.

The moment you decide to rent, someone will ask whether you should use the big three (Amazon Web Services, Google Cloud, Microsoft Azure) or one of the newer specialists, and the conversation usually collapses into loyalty and habit. That is the wrong frame. Providers are not teams to support. They are vendors to evaluate against your requirements. So we will not rank brands here. We will derive the axes that actually decide it, and you will score any provider, named or not, on those.

The axes that actually decide it

Axis one: how much do they manage for you?

In Piece Two a server came with a job: stay awake, healthy, patched, scaled. A provider can hand you that machine at very different heights. At the low end they give you a bare rented computer and you install and run everything yourself: most control, most work. At the high end they run a managed service: you hand over your code or your data and they handle the operating system, the scaling, the backups, and the patching, so you never touch the machine. Least work, less control, usually more cost per unit, and some lock-in. Managed simply means the undifferentiated heavy lifting is done for you. Early and small: lean managed and buy your time back. Large and cost-sensitive, or needing fine control: move down toward the bare machine.

Axis two, decisive for models: can you even get the GPUs?

For an ordinary app, every provider has ample ordinary machines and this barely matters. For an LLM it can be the whole decision. The right GPUs are scarce and expensive, and availability swings: a provider may have none of the chip you need in the region you want, or a long queue for it. So for model work, ask three blunt things. Do they have the specific GPU class your model needs? Can you actually get it now, in the region you need, without a waitlist? And what is the real per-hour price, both on demand and committed? Specialist GPU clouds often beat the hyperscalers on both price and availability for this one job, which is precisely why they exist.

Axis three: the bill you do not see, egress

It is cheap, often free, to move your data into a cloud. It frequently costs real money to move it back out, and to move it between regions. This is egress, the data-transfer-out cost, and it does two things. It inflates bills for data-heavy or multi-cloud designs, and it quietly raises the price of ever leaving. Always check the cost of getting data out, not just the cost of keeping it in.

Axis four: where are their regions, and what does the law say?

A provider is only useful if it has a data centre where you need one, near your users and inside your legal lines. So check two things. Is there a region close enough for the latency you decided you needed in Piece Four? And does it satisfy any data-residency rule your workload carries from the data-gravity lever? A provider with no region in your country can be a non-starter no matter how good the price is.

Axis five: how hard is it to leave?

The more you build on a provider’s proprietary, only-here services, the more switching later means rewriting rather than copying. That cost-of-leaving is lock-in. Some lock-in is a fair price for genuine convenience; the danger is taking it on by accident. The simple test: if this provider doubled your price next year, how painful would moving be? Favour portable building blocks for anything you must be able to move.

Axis six: what does reliability really promise?

Providers advertise uptime, often as a number of nines (99.9 percent, 99.99 percent), backed by a service-level agreement, the SLA, which is a contractual promise with compensation if they miss it. Read it for what it actually guarantees and what it pays when broken, rather than trusting the marketing number on the page. More nines cost more. Match the promise to how much downtime your workload can genuinely tolerate.

Axis seven: how fast can your team move on it?

Real cost is not only the invoice. It is also the hours your engineers spend. Good documentation, clean SDKs, a sane console, and a short path from zero to a first running deploy save more money over a year than a small difference in sticker price, especially for a small team. Weight developer experience honestly. It is a real line in the budget, just an invisible one.

The method, in one move: requirements first, then map

The mistake is to start from the provider. Start from your own constraints, written down, and only then score providers against them. List, for your workload: how predictable and heavy it is (Pieces Three and Four), where your users are, what rules bind your data, whether you need GPUs and which class, how steady your load is, and how large your team is. Then, and only then, open the providers and check each one against that list. The right provider is not the famous one and not the cheapest one. It is the one that best fits the constraints you wrote down before you looked.

The table below scores archetypes rather than brands, on purpose, so it stays true as names and prices change.

Archetype Best at Watch out for Typical fit
Hyperscaler (full-range cloud) Breadth of managed services, global regions, enterprise trust Cost and complexity, accidental lock-in, GPU scarcity at peak A growing product that wants many services in one place
Specialist GPU cloud GPU availability and price for training and inference Narrower service range, fewer regions, you assemble more yourself Self-hosting or fine-tuning where GPUs dominate the bill
Managed platform (app platform) Fastest path from code to live, minimal operations Less control, higher per-unit cost at scale, customisation ceilings Early-stage apps and small teams optimising for speed
Hosted model API Zero hardware, pay per token, instant scale Per-use cost at very high volume, data leaves your environment Most teams adding LLM features, especially at the start
Own hardware (on-prem) Control, data residency, cheap at steady high scale Large upfront cost, you run everything, no quick elasticity Steady heavy load, strict data rules, or hard latency needs

Provider archetypes scored on the axes, written to stay true as names and prices change.

THE ONE IDEA

Do not pick a provider, score one. Write your real constraints first (where your users are, what binds your data, which GPUs you need, the shape of your load, the size of your team), then rate each option on managed depth, GPU access and price, egress cost, regions, lock-in, the SLA, and developer experience. The best provider is the one that fits the list you wrote before you looked.

PIECE SEVEN

Two worlds: development and production

Why the machine you build on and the machine users touch want opposite things, and how to keep them the same shape at different sizes.

Until now we have spoken as if a workload has one place to live. It has at least two, and they want opposite things. The machine where you build and the machine where real users arrive are judged by different scorecards, and confusing the two wastes either money or trust. This is the development-versus-production split, and getting it right is the last piece of choosing well.

What development optimises for

Development, and its sibling, a shared staging environment that mimics production, is where you and your team build, break, and try things. Its priorities, in order:

  • Speed of iteration. You change code constantly and want to see the result in seconds.
  • Low cost. It is fine, even correct, to run small and cheap here.
  • Safety to break. Nothing real depends on it, so a crash is a shrug, not an incident.
  • Disposability. You want to spin a fresh environment up and tear it down at will.

It is perfectly acceptable for a development environment to be slow, occasionally down, and tiny. Spending production-grade money to make development fast and bulletproof is a common and expensive mistake.

What production optimises for

Production is the machine real users actually touch. Its priorities are almost the exact inverse:

  • Reliability. It must not fall over, and when part of it fails it should recover on its own.
  • Performance. It must be fast for users, near them, sized for real load. The latency and elasticity levers from Piece Four are now non-negotiable.
  • Security. It holds real user data and real secrets, so it must be locked down.
  • Observability. It must tell you when it is sick, through logs, metrics, and alerts, because you cannot watch it by hand.
  • Cost at scale. Now the per-hour and per-token math from Pieces Four, Five, and Six bites for real, because this is the bill that runs forever.

The two-sided trap

The mistake runs both ways, and both directions are expensive. Build your development environment on full production-grade infrastructure and you burn money and time making throwaway work bulletproof. Ship to production on development-grade infrastructure, the cheap, tiny, sometimes-down setup that was perfect for building, and it falls over the moment real users arrive, taking your credibility with it. Right-size each world to its own scorecard. The two are not supposed to match in size or in cost. They are supposed to match in shape.

The path from laptop to live, and why each step exists

  • Your laptop (Piece One). The fastest possible loop, just for you. Perfect for building, useless for serving anyone else.
  • A shared development or staging environment. An always-on machine that looks like production but is small and safe, where the team integrates work and tests changes before users ever see them. It exists to catch what only appears once code leaves your laptop.
  • Production. The real, right-sized, locked-down, watched environment that users touch. Changes arrive here only after they have survived staging.

Skipping straight from laptop to production is exactly how surprises reach your users first. The middle step is cheap insurance.

The same split for an LLM, made concrete

  • In development, use the smallest thing that lets you build: a small or quantized model, or the cheapest tier of a hosted API. You are testing whether your prompts, your flow, and your code work, not buying top-end quality. This keeps the GPU and token bills near zero while you iterate.
  • In production, move to what users deserve: the full-size model, or the production API tier, sized for real and possibly spiky load. Now you apply the Piece Four decision (API or self-hosted) and the Piece Six scoring in earnest, because the cost and the reliability are real.

The thread that ties both worlds together: reproducibility

The deepest reason development and production cause pain is drift: it works on my machine but not in production, because the two environments have quietly come to differ. The discipline that kills this is reproducibility, building every environment the same way from the same written definition, so that development, staging, and production differ only in size and never in nature. Writing your environment down as configuration, rather than setting it up by hand by clicking around, which is the idea behind infrastructure as code, is what lets you stamp out identical worlds at different scales. You do not need the tools by name yet. You need the principle: same shape everywhere, different scale, defined in writing so it can be rebuilt exactly.

THE ONE IDEA

Development and production are two homes for one app, judged by opposite scorecards. Development wants cheap, fast, and disposable; production wants reliable, fast for users, secure, observable, and cost-aware at scale. Keep them the same shape and different sizes by writing the environment down so it can be rebuilt exactly.

Choosing well

We started at the physics of a running program and ended at the discipline of running it in two worlds at once. Every piece was one question about the machine.

THE MACHINE

What does running mean (One). What must an always-on machine do (Two). How heavy and how predictable is the work (Three). Should you rent it or own it (Four). Should you even hold a machine, or let one appear on demand (Five). Which provider fits your real constraints (Six). How do development and production differ (Seven). Notice that not once was there a single right answer. There is no best place to run things, no best provider, no universal yes to the cloud or to owning hardware. There is only the right match for this workload, at this stage, under these constraints. That is the whole art.

THE WHOLE FRAMEWORK

Read the workload. Two axes: how predictable (deterministic or probabilistic) and how heavy (an ordinary CPU, or a model that must fit in VRAM).

Rent or own. Cloud for uncertainty, speed, and spread; on-prem for steady scale, control, and data that cannot move.

Or skip the machine. For code that runs only sometimes, serverless makes a machine appear per request and bills only for the run, trading cold starts, time limits, and no memory between calls; app-side Vercel, data-side Supabase, global edge Cloudflare, heavy or long Lambda, always-on a container.

For a model, ask first: can you just call an API? Pay-per-token starts cheapest; self-host only when you can keep a GPU busy, or when privacy forces it.

Score the provider, do not pick one: managed depth, GPU access and price, egress, regions, lock-in, the SLA, developer experience.

Split the worlds: development cheap, fast, disposable; production reliable, fast, secure, observed, cost-aware; same shape, different size.

The whole art: there is no best place to run things, only the right fit for this workload, this stage, these constraints.