Replit Deployments: Choosing Between Autoscale and Reserved VM for Production
Autoscale or Reserved VM? A practical framework for choosing a Replit deployment target based on cold starts, concurrency ceilings, cost models, and workload type.
27 Sept 2025, 10:24 UTC

You've built something in a Replit workspace and it works. Now you need it to stay up, respond fast, and not surprise you on the bill. Replit offers two production deployment targets — Autoscale and Reserved VM — and picking the wrong one usually means either paying for idle compute or shipping cold-start latency to your users.
The short version: Autoscale is for sporadic, request-driven traffic; Reserved VM is for anything latency-sensitive, long-lived, or consistently busy. The rest of this post explains why, with the numbers and limits that actually drive the decision. Note that Replit's platform details change over time, so treat the specific figures here as a starting point and confirm current limits in the Replit docs before committing.
How Autoscale actually behaves
Autoscale deployments scale to zero. When your app sits idle, no container is running, and you pay per request rather than per hour. When a request arrives after an idle period, Replit spins up a fresh container — a cold start that typically lands in the ~200–800 ms range, though repls with heavy Nix dependencies (large Python ML stacks, JVM apps) can exceed a second. Once warm, the container stays alive for roughly five minutes before scaling back down.
There's also a hard ceiling: Autoscale deployments cap out at around 100 concurrent requests. Beyond that, traffic queues and can eventually return 503s. For an internal tool, a webhook receiver, or a low-traffic API, none of this matters. For a user-facing checkout endpoint, it matters a lot.
What Reserved VM buys you
Reserved VM is the opposite trade: a dedicated instance (tiers roughly spanning 0.5–8 vCPU and 1–32 GB RAM) that runs 24/7 at a fixed monthly price. Latency drops to single-digit milliseconds because there's no cold start, ever. Concurrency is limited only by your instance size and how well your app is tuned, not a platform ceiling.
Just as important, Reserved VM supports workloads Autoscale can't: WebSocket connections that stay open for hours, background workers, and long-running processes. If your app holds state in memory or maintains persistent connections, Autoscale's scale-to-zero model will break it by design.
The catch is cost discipline. Reserved VM bills monthly regardless of traffic, and a forgotten staging deployment quietly accumulates charges. Name your deployments clearly and audit them in the billing dashboard periodically.
A concrete decision example
Say you're running a small SaaS webhook processor: it receives Stripe events, updates a database, and occasionally serves an admin dashboard. Traffic is bursty — quiet most of the day, spiky during business hours.
Start on Autoscale. Your cost tracks actual usage, cold starts of a few hundred milliseconds are fine for webhooks (Stripe retries anyway), and you'll never approach 100 concurrent requests. Then measure. A simple check from any machine with curl:
# Run from your local terminal; no special permissions needed.\n# Replace the URL with your deployment's hostname.\ncurl -o /dev/null -s -w \"total: %{time_total}s\\n\" https://your-app.replit.app/healthRun it after 10+ idle minutes to capture a cold start, then again immediately for a warm request. If cold-start p95 latency starts violating a budget — say you're adding a user-facing API with a 300 ms target — that's your signal to flip the deployment target to Reserved VM. The migration is genuinely low-friction: your replit.nix environment, secrets, and code stay identical; only the deployment target changes. You can even run both at once — staging on Autoscale, production on Reserved VM — as named deployments on the same repl.
Environment parity, and one reproducibility gotcha
Both deployment types build from the same Nix environment defined in replit.nix, so dev and prod run identical binaries. That's a real strength — but it has a sharp edge. If your replit.nix references a floating nixpkgs channel, a channel update between deploys can change binary hashes and produce a production build that differs from what you tested. Pin nixpkgs to a specific commit:
{ pkgs ? import (fetchTarball\n \\\"https://github.com/NixOS/nixpkgs/archive/.tar.gz\\\") {} }:\n{\n deps = [ pkgs.nodejs_20 ];\n}Replace with a pinned nixpkgs revision. Verify by rebuilding both deployment types and confirming the builds succeed identically.
Limitations worth knowing upfront
Three constraints catch people off guard:
- Replit DB is not a database. It's a key-value store with a ~50 MB default limit and no secondary indexes. Fine for prototypes; plan a migration path to Postgres before query complexity grows.
- The Reserved VM static IPv4 is shared across all deployments in the same repl. If you need isolated services, use separate repls or put a reverse proxy in front.
- Autoscale cold starts vary with dependency weight. Don't trust the typical range for a heavy stack — measure with your real payload before promising an SLA.
The actionable takeaway
Default to Autoscale for anything request-driven and sporadic. Switch to Reserved VM when one of three triggers fires: a p95 latency budget you can't meet with cold starts, a need for WebSockets or background workers, or sustained concurrency approaching the Autoscale ceiling. Pin your nixpkgs commit either way, and set a monthly reminder to review deployments in the billing dashboard — the most expensive Replit mistake is a forgotten Reserved VM, not a slow cold start.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.