Skip to main content

Vercel Now Deploys Your Dockerfile — and Admits Functions Weren't Enough

12 min readDora NodaDora Noda
Share
On this page

For a decade, Vercel's answer to "where does my backend run?" was some flavor of you don't need one — a serverless function here, a Postgres integration there, and if your stack didn't fit, that was your problem. In the summer of 2026, Vercel shipped the opposite answer: bring your Dockerfile, bring your Rails monolith, bring your second and third framework, and wire them together over a private network. It is the most interesting platform reversal of the year, because it concedes the exact thing Render, Railway, and Fly.io have argued all along — that a team whose stack grows past "frontend plus a database" needs services, not functions.

This post reads the mid-2026 Vercel Services release line by line: what actually shipped, what the concession means, and — the part that decides whether you can use it — what still doesn't come with it. The short version, up front:

  • Now fits on Vercel: a Next.js frontend plus request/response backends (FastAPI, Rails, Go, Django) talking over private service bindings, with per-push preview environments for the whole stack.
  • Fits with caveats: bursty APIs and short jobs that tolerate function ceilings — capped duration, scale-to-zero after five idle minutes, no local disk.
  • Still doesn't fit: always-on workers, long-lived connections, stateful singletons, and anything needing a static egress IP or a box you can SSH into.

Everything below is the evidence for those three bullets.

The news in 60 seconds​

Four changelog lines, dated, in the order they landed:

WhenWhat shippedThe concrete terms
Jun 16, 2026Functions run up to 30 minutes on Pro and EnterpriseNode.js and Python runtimes, requires Fluid compute plus a maxDuration opt-in; Fluid's Active CPU pricing bills active CPU time and pauses during I/O. (changelog)
Jun 17, 2026Vercel Services announced at ShipOne project deploys frontends, backends, and other services together with private inter-service communication; launch customers OpenAI and Octopus Energy run Next.js frontends with Python backends entirely on Vercel. (announcement)
Jun 30 – Jul 1, 2026Multiple frameworks per project, then Service BindingsServices declared in config; bindings inject deployment-scoped private URLs (Vercel handles the internal rewrite, routing, authentication, and TLS). (changelog, changelog)
Early Jul 2026Any Dockerfile deploysAdd a Dockerfile.vercel; Vercel builds the image, deploys it, and autoscales it. The only requirement: your server speaks HTTP and listens on PORT (default 80). (coverage)

Read as one story, this is a platform growing a backend story in six weeks that its competitors spent years building. Read skeptically — as this post will — it is Vercel bolting a service model onto a function substrate, and the bolts show.

What Vercel actually shipped, piece by piece​

Four primitives, each doing one job:

1. Services in configuration. A project can now declare multiple independently built components — a Next.js frontend, a FastAPI API, a Go worker-ish thing — that deploy together with shared public routing. vercel dev runs all of them locally, which matters more than it sounds: multi-service local parity is the unglamorous part every platform gets wrong first.

2. Service Bindings for private networking. One service declares a binding on another, and Vercel injects a deployment-scoped URL (say, RESERVATIONS_SERVICE_URL) that resolves privately within that deployment. A backend with no public rewrite has no public route at all — reachable only by its bound callers. Note the fine print from Vercel's own reference architecture: a binding is reachability, not authentication. If the private service does anything sensitive, you still need application-level authorization. Private networking that stops at the network layer is table stakes, not a security model. (reference)

3. Dockerfiles running as Functions. This is the mechanism the headline features bury: custom containers don't run as standalone containers — they run as OCI images on top of Vercel Functions and Fluid compute. They inherit function limits (capped size, memory, and duration), scale to zero after five minutes idle, and are stateless by design. "If your server speaks HTTP and listens on a port, it can run on Vercel now" is true only inside the serverless function model, not in the lift-and-shift sense.

4. Active CPU billing. Fluid compute charges for CPU actually burned and pauses the meter during I/O waits — a handler that spends minutes awaiting an LLM stream stays cheap. This is genuinely good pricing design for the AI-workload era, and it is also the tell: billing that pauses on I/O is billing for invocations, not for processes. Nothing here prices an always-on box, because there still isn't one.

The concession, stated plainly​

Before this summer, Vercel's architecture was frontend-and-functions-first while Render, Railway, and Fly.io sold multi-service container platforms with private networking between persistent services. Vercel just shipped the second architecture's feature list — multiple frameworks, container support, internal service networking — on top of the first architecture's runtime.

Why now? Because the functions-only ceiling kept ending the same conversations. Every team whose stack grew past "frontend plus a database" hit the same wall: a duration cap measured in seconds-to-minutes (300 seconds on Hobby; up to 800 seconds on Pro and Enterprise, extendable to 30 minutes only on Fluid with an opt-in — see the Functions limitations docs), no local state, no always-on process. The standard industry answer became the hybrid stack — Vercel for the frontend, Railway or Render for the worker — which one 2026 founder guide describes as "common and fine," i.e., revenue Vercel watched walk to a competitor on every deal. (guide)

The 30-minute Function change is the concession in miniature: raising the ceiling from minutes to half an hour helps document processing, OCR, and LLM reasoning chains, but a ceiling you raise is still a ceiling. Services plus Dockerfiles is Vercel admitting that some workloads are shapes, not sizes — a worker is not a long function, a stateful API is not a big function — while still running every shape on function infrastructure. Whether that counts as a real service model or a function model wearing a service costume is exactly what the next section adjudicates.

The gap table: what still doesn't come with it​

Here is the core artifact of this post: capability by capability, Vercel Services versus a persistent-service PaaS (Render, Railway, Fly.io — or your own cluster), each row with who feels the gap.

CapabilityVercel Services (mid-2026)Persistent-service PaaSWho feels it
HTTP request/response servicesYes — any framework via Dockerfile, autoscaled on FluidYes — web/private servicesNobody; this is the part Vercel closed
Max single-execution duration30 min (Pro/Enterprise, Fluid + opt-in); 800s standard; 300s HobbyUnbounded process lifetimeTeams with hour-long ETL, video renders, or training-adjacent batch steps
Idle behaviorScales to zero after 5 idle minutes; cold starts on returnAlways-on instances availableLatency-sensitive APIs and anything with expensive warmup (model weights, big caches)
Local disk / durable stateStateless; durable storage attached to a container hasn't shippedPersistent disks for eligible servicesSQLite-backed apps, local queues, on-disk caches, upload spooling
Background workersNo dedicated type — cron, waitUntil, and workflow integrations only (Vercel's own comparison page says "No (use waitUntil)")Dedicated background workers + cron jobsBullMQ/Celery/Dramatiq shops; anyone polling a queue in a loop
WebSockets / long-lived connectionsSupported within Function lifecycle limitsSupported through persistent servicesChat, realtime collab, game servers — anything holding a socket open for hours
Non-HTTP / TCP / arbitrary portsHTTP servers on PORT onlyArbitrary processes and ports (platform permitting)Custom protocols, game netcode, database wire protocols
Static egress IPs / Secure ComputeDon't work with custom containers yetStandard container-platform fareTeams allowlisting egress at a bank, hospital, or enterprise firewall
InspectabilityNo box to look at — logs and traces onlySSH/exec into the running instance (self-hosted: the actual machine)Whoever debugs the 2 a.m. incident the dashboard can't explain

Two patterns jump out. First, every "yet" and "within limits" in the left column is a function-substrate constraint, not a missing feature flag — you cannot bolt process lifetime onto invocations without changing what the thing is. Second, the right column is precisely the feature set Vercel spent years arguing teams didn't need. The market has now voted: Vercel's own roadmap is converging on the multi-service model, one concession at a time. (comparison, Vercel's own guide)

One honest caveat in the other direction: the left column also buys things the right column doesn't. Per-push preview environments for the entire multi-service stack, zero node management, and Active CPU billing that makes bursty workloads genuinely cheap are real operational wins. The gap table is not "Vercel is bad" — it is "Vercel is a function platform with a service interface, and the interface leaks exactly where functions end."

Three workload verdicts​

Apply the table to three concrete stacks a team might actually bring:

1. Fits now: Next.js storefront + FastAPI checkout API. Request/response on both sides, Postgres over a marketplace integration, no local state, traffic bursty enough that scale-to-zero saves money. This is the OpenAI/Octopus Energy shape from the launch announcement, and it is the workload Services was built for. Bind the API privately, ship per-push previews of the whole thing, done.

2. Fits with caveats: bursty API with short background jobs. An image-resize pipeline where uploads land via webhook and each job finishes in under a minute: cron-triggered functions or waitUntil continuations can carry it, and Active CPU billing keeps the invoice small. The caveats are load-bearing, though — a job that occasionally runs 40 minutes will die at the 30-minute ceiling on your worst day, and a queue that needs polling (rather than triggering) has no natural home. If your p99 job duration is within a factor of two of the ceiling, you don't have headroom, you have a countdown.

3. Doesn't fit: the worker-backed SaaS. A Django app with Celery workers draining a Redis queue, websocket notifications held open for hours, and an egress allowlist at an enterprise customer: three separate rows of the gap table say no (no dedicated workers, sockets bounded by function lifetime, no static IPs on custom containers). This stack's natural homes remain Render's workers-plus-disks, Railway's always-on processes, Fly.io's persistent Machines — or a cluster you own. Note this isn't an exotic stack; it is arguably the median B2B SaaS architecture of the last decade.

The decision rule that falls out: if every component of your system can be phrased as "wake up, handle one request, go away," Vercel Services now covers you. The first component you can't phrase that way — the poller, the socket holder, the disk writer — names the platform you actually need.

The self-hoster's read: convergence favors the substrate​

Step back and the industry pattern is hard to miss: every PaaS converges on the same endpoint — containers plus private networking plus per-push deploys — and differs only in which direction it arrived from. Render, Railway, and Fly.io started from persistent processes and added developer experience. Vercel started from developer experience and is now adding processes, one changelog entry at a time, each one re-litigating a constraint its competitors never had.

For a team self-hosting on its own machines, this convergence is the whole argument for owning the substrate. Nobody who runs their own cluster waited six weeks for multi-framework support, because a cluster never had a framework menu — it runs containers, full stop. Nobody files a feature request for a second service type, because a Deployment and a Job were there on day one. The durable-storage "yet," the static-IP "yet," the duration ceiling: each is a vendor's roadmap item that is simply absent where the platform started from containers instead of functions.

That doesn't mean self-hosting is free — node upgrades, CVE patching, and 2 a.m. pages are the invoice, and it arrives in engineer-hours instead of dollars. It means the invoice is legible: you pay in operations for capabilities you hold permanently, rather than paying in architecture for capabilities that arrive, if ever, on someone else's Ship schedule.

Conclusion: durable storage is the next concession to watch​

Vercel's summer of 2026 deserves credit as strategy: Services, bindings, Dockerfiles, and Active CPU billing form a coherent answer for the request/response majority, and per-push previews of a whole multi-service stack genuinely exceed what most persistent PaaS vendors offer today. But the gap table doesn't lie about the substrate. Stateless containers with a five-minute idle fuse and a 30-minute duration ceiling are functions with better marketing, and the workloads that never fit functions — workers, sockets, disks, static IPs — still don't fit.

So watch the changelog the way you'd watch a negotiation. Durable storage attached to containers is the next concession already foreshadowed as unshipped; static egress IPs and Secure Compute for custom containers are queued behind it. Each one that lands moves another row of the table from "within limits" to "yes" — and moves Vercel one step closer to the persistent-service platform it spent a decade insisting nobody needed. Teams choosing today shouldn't bet on that roadmap. They should read the table, find their workload's row, and pick the platform whose current left column already says yes.

Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. Star the repo on GitHub or deploy your first app today.

Related articles

Check your move before you migrate

Free browser tools: check a render.yaml or your Render scripts against bex, or turn a Heroku app or docker-compose.yml into a draft render.yaml. Nothing you paste leaves your browser.

Open the migration tools