In plain English
Most AI work needs a GPU — a specialized chip that runs models fast. The old way to get one was to rent a server in the cloud, leave it running, install your code and dependencies on it, and pay for every hour it sits there, busy or idle. A single GPU box can cost a few dollars an hour, so a machine you only use for a 20-minute job each morning still bills you around the clock.

Modal is a serverless cloud built for this. You don't rent or manage servers at all. Instead, you write a normal Python function, add a few lines that describe the environment it needs (its packages, its files, whether it wants a GPU), and Modal runs it on demand. When a request comes in, Modal spins up the right machine, runs your function, returns the result, and then shuts the machine down. When nothing is happening, you have zero servers running and pay nothing.
Think of it like the lights in a modern office with motion sensors. The old model is leaving every light on all night just in case someone walks in. Serverless is a light that snaps on the instant someone enters the room and switches off when they leave. You get full brightness exactly when you need it, and the meter only runs while the room is occupied.
Why it matters
GPU compute is the expensive, awkward part of building AI products. Modal exists to take that pain away, and a few specific problems explain why builders reach for it.
- You stop paying for idle time. A traditional always-on GPU server bills you 24/7 even if real traffic is a few bursts a day. With on-demand scaling, you pay per second of actual work — a batch job that runs for ten minutes costs you ten minutes, not a whole month's rental.
- You don't manage infrastructure. No provisioning machines, installing CUDA drivers, configuring containers, or babysitting a Kubernetes cluster. You describe the environment in Python and the platform builds and runs it for you.
- It scales from zero and back to zero. When one user hits your model, Modal runs one container. When a thousand hit it at once, it can fan out to many containers in parallel, then scale all the way back down to nothing when the rush ends. You never pre-provision for peak.
- It fits AI workloads specifically. On-demand access to modern GPUs, large model weights cached so they don't re-download every run, and the ability to run inference, fine-tuning, and big batch jobs in the same place.
Who cares about this? Anyone who needs a GPU but not all the time. A team serving an open-weight model behind an API. A researcher fine-tuning a model overnight. A startup running a nightly batch job that embeds a million documents. A weekend project that can't justify a $1,500/month always-on GPU. The common thread is spiky or occasional demand: workloads where an always-on server would sit mostly idle, burning money.
There's a subtler reason it matters: it collapses the gap between writing code and running it at scale. The same Python function you tested locally is the thing that runs in the cloud on a GPU — no separate deployment pipeline, container registry dance, or YAML maze in between. That short feedback loop is why Modal shows up so often in modern AI app stacks.
How it works
The core idea: you describe your code and its environment in Python, and Modal turns that description into a container it can run on demand in its cloud. There's no separate Dockerfile or deploy config in another language — the environment definition lives right next to the function.
You define the environment in code
You build up an image (a recipe for a container: base OS, Python version, pip packages, system libraries) using Python method calls. You decorate a function to say "run this on Modal," and you can attach a GPU, a timeout, or a request for many parallel copies right there in the decorator. Modal reads this, builds the image once, caches it, and reuses it on every future run.
import modal
# 1) Describe the container image in Python — no Dockerfile.
image = (
modal.Image.debian_slim()
.pip_install("torch", "transformers")
)
app = modal.App("sentiment")
# 2) Ask for a GPU right in the decorator.
@app.function(image=image, gpu="A10G")
def classify(text: str) -> str:
from transformers import pipeline
clf = pipeline("sentiment-analysis") # loads the model
return clf(text)[0]["label"]
# 3) Call it. Modal spins up a GPU container on demand.
@app.local_entrypoint()
def main():
print(classify.remote("I love how simple this is"))Notice classify.remote(...). That call doesn't run on your laptop — it ships the work to Modal, which starts a container with your image on a GPU, runs the function there, and sends the result back. To your code it looks like an ordinary function call.
What happens on each request
When a call arrives and no container is already warm, Modal does a cold start: it grabs a machine from its pool, loads your cached image, starts your code, and only then runs the function. If a container is already running and free, the call is a warm start and skips straight to running. After a period of no traffic, idle containers shut down so you stop paying.
This is why cold-start speed is the headline metric for serverless GPU platforms. A cold start adds latency before your code even begins: the machine has to boot, the image has to load, and a multi-gigabyte model often has to be read into GPU memory. If that takes 30 seconds, the first user after a quiet spell waits 30 seconds. Modal invests heavily in making cold starts fast — caching images and weights, and keeping the machine-acquisition step quick — so the serverless model stays practical for interactive inference, not just slow background jobs.
Serverless vs. an always-on GPU server
The clearest way to understand Modal is to compare on-demand serverless against the traditional approach of renting a GPU box and leaving it running. They make opposite trade-offs.
- Pay only for seconds of real work
- Scales from zero to many automatically
- No servers to provision or patch
- Cold start adds first-request latency
- Best for spiky or occasional demand
- Pay 24/7, busy or idle
- You size and scale it yourself
- You own drivers, OS, and uptime
- No cold start — always warm
- Best for constant, heavy traffic
Neither wins outright. Serverless shines when demand is uneven: the idle savings dwarf the occasional cold-start cost. An always-on server wins when a GPU is busy nearly all the time — at full, steady utilization a reserved machine can be cheaper per request, and you never pay the cold-start tax. The honest rule of thumb: the lower and spikier your traffic, the more serverless saves you; the higher and flatter it is, the more a dedicated machine makes sense.
| If your workload is… | Lean toward |
|---|---|
| A few bursts of traffic a day | Serverless (scale to zero) |
| A nightly batch job | Serverless (run, then shut down) |
| Unpredictable, spiky demand | Serverless (auto fan-out) |
| Constant high traffic, 24/7 | Always-on / reserved GPU |
| Ultra-low-latency, no cold start allowed | Always-on (keep it warm) |
What people actually build on it
Modal is general-purpose Python compute, but a few AI patterns come up again and again. Seeing them makes the "why" concrete.
- Model inference behind an API. Wrap an open-weight model in a function, expose it as a web endpoint, and let Modal scale containers up and down with traffic. You get a hosted model API without renting a GPU you'd mostly leave idle.
- Fine-tuning and training runs. Kick off a job that grabs a big GPU (or several), trains for a few hours, writes the weights to storage, and releases the hardware. You pay for the training window, not for owning a training rig.
- Batch processing. Embed a million documents, transcribe a backlog of audio, or run a model over a huge dataset by fanning the work out across hundreds of parallel containers, then scaling back to zero when the queue drains.
- Scheduled jobs. Run a nightly report, a periodic re-embedding of your knowledge base, or a recurring evaluation — on a schedule, with a GPU only for the minutes it runs.
All four share the same shape: heavy compute, used in bursts. That's the sweet spot. For comparison, work that is constant and lightweight — a tiny always-on chatbot backend handling a steady trickle of text-only requests to a hosted LLM API — often doesn't need a GPU platform at all, and a small always-on server or edge function may be simpler. Choosing between these is the heart of picking your deployment option.
Going deeper
Once the basics click, the interesting questions are about latency, cost, and where the model fits in a larger system. A few directions worth knowing.
Beating cold starts. Beyond keeping warm containers, the big lever is how fast model weights reach the GPU. Multi-gigabyte weights are slow to download and load, so platforms cache them on fast storage and stream them into memory, and you can structure your function so the model loads once per container and is reused across many calls rather than reloading every request. Understanding this is the difference between a first request that takes seconds and one that takes a minute.
State is the catch. Serverless functions are ephemeral — when a container shuts down, anything it held in memory or wrote to its local disk is gone. So Modal gives you durable building blocks: persistent volumes for files and model weights, key-value-style storage for small state, and ways to mount secrets. Anything you need to survive between runs has to live in one of those, not in a local variable. This is the same reason you keep chat history and API keys in external stores rather than in process memory.
Concurrency and cost control. Two functions can blow up your bill in opposite ways: too little parallelism makes a big batch job crawl, while unbounded fan-out can launch hundreds of GPU containers at once. Serverless platforms let you cap maximum containers, set how many concurrent requests each container handles, and choose GPU types per function — knobs that directly shape both latency and spend. Estimating that spend up front is its own skill; see AI app cost estimation.
Where it sits in the stack. Modal is the compute layer — the place GPU-heavy Python runs. It usually pairs with a hosted LLM API for text generation, a vector store for retrieval, a database for app data, and a front-end somewhere else. A common pattern is using Modal to self-host the one model you need custom (an embedding model, a fine-tuned open model, a speech model) while calling managed APIs for everything else. The skill isn't Modal alone; it's knowing which pieces to self-host on serverless GPUs and which to rent as an API — a recurring theme across the whole AI app stack.
Finally, keep the trade-off honest. Serverless GPU compute is a fantastic fit for spiky, bursty, occasional work, and it removes a mountain of infrastructure toil. But it is not a free lunch for every workload: at constant, very high utilization, a reserved machine can be cheaper, and latency-critical paths may need warm capacity that erodes the scale-to-zero savings. The right answer is workload-shaped — measure your traffic pattern first, then choose.
FAQ
What is Modal used for?
Running Python AI workloads on demand without managing servers — most commonly model inference behind an API, fine-tuning and training jobs, large batch processing, and scheduled jobs. It's a fit whenever you need a GPU in bursts rather than around the clock.
What does serverless mean for GPU workloads?
It means you never rent or manage a GPU machine yourself. You describe a function and its environment in code, and the platform spins up a GPU container on demand, runs your code, returns the result, and shuts the container down. You pay only for the seconds it actually ran, and it scales to zero when idle.
Why does cold-start speed matter on Modal?
A cold start is the time to boot a fresh machine, load your container image, and read model weights into GPU memory before your code even runs. Slow cold starts mean the first user after a quiet period waits — sometimes tens of seconds. Fast cold starts are what make serverless practical for interactive inference, not just background jobs.
Is Modal cheaper than renting a GPU server?
It depends on your traffic. For spiky or occasional demand, paying per second and scaling to zero is usually far cheaper than an always-on box that bills 24/7 while sitting idle. For constant, near-full-utilization workloads, a reserved GPU server can be cheaper per request and avoids cold-start latency.
Do I need a Dockerfile to use Modal?
No. You define the container image in Python by chaining method calls that add a base OS, packages, and files. Modal builds and caches that image for you, so the environment definition lives right next to your function instead of in a separate Dockerfile.
Does serverless keep data between runs?
Not by default — containers are ephemeral, so memory and local disk are wiped when they shut down. To keep data, you store it in durable building blocks like persistent volumes, external storage, or a database, and load it back when a function runs.