Fly.io Free Tier Cold Start Latency: Real Node.js Benchmarks

Cold starts on Fly.io’s free tier aren’t theoretical. They’re killing real user sessions, and the numbers are worse than most developers expect.
The free tier’s machine suspension behavior means your Node.js app goes completely dark after roughly 5 minutes of inactivity. When the next request hits, you’re not waiting 200ms for a warm response. You’re waiting for a full VM boot cycle. Measured across community benchmarks and production monitoring reports from early 2026, that gap sits between 1.5 and 4 seconds — sometimes higher depending on your app’s initialization complexity.
That’s the context. If you’re evaluating Fly.io’s free tier for a Node.js side project, hobby API, or low-traffic internal tool, the cold start latency data should be the first thing you examine — not the last.
Key Takeaways
- Fly.io free tier machines suspend after approximately 5 minutes of inactivity, triggering cold starts that community benchmarks place between 1.5 and 4 seconds for typical Node.js applications.
- Fly.io’s
auto_stop_machines = "suspend"setting (the free tier default) differs from a fullstop— suspend is faster to resume, but still adds observable latency under real traffic conditions.- Applications with heavy
require()chains, large dependency trees, or database connection initialization at startup consistently show the highest cold start penalties.- Paid tier machines with
auto_stop_machines = "off"eliminate cold starts entirely, but cost roughly $1.94/month minimum for a shared-cpu-1x 256MB instance.
How Fly.io Free Tier Actually Works in 2026
Fly.io launched its updated free tier structure in 2024, offering three shared-CPU VMs with 256MB RAM at no cost. The catch — and it’s a meaningful one — is machine lifecycle management.
By default, free tier machines use auto_stop_machines = "suspend" in fly.toml. Suspend differs from a full shutdown: the machine’s memory state is preserved, which means resume is faster than a cold boot from zero. According to Kuberns’ 2026 Fly.io guide, the free tier doesn’t provision dedicated resources, so resume times fluctuate based on host load.
The relevant timeline:
- 2023: Fly.io introduced machine-level auto-stop/start, replacing the older Nomad-based scheduler
- 2024: Free tier restructured to three always-available VMs, previously more restrictive
- Early 2026: Fly.io’s Anycast network now spans 37+ regions, but free tier deployments are locked to a single region
That single-region constraint matters. If your users are geographically distributed and your free machine lives in iad (Virginia), users in Sydney already face baseline latency before a cold start compounds the problem.
The Node.js ecosystem has also changed the equation. Modern Express or Fastify apps with Prisma, heavy middleware stacks, or TypeScript compiled builds can take 800ms–1.2 seconds just in require() resolution before the HTTP server is ready to accept connections.
The Suspend vs. Stop Distinction — Why It Matters for Benchmarks
Most community benchmarks conflate “suspend” and “stop” behavior. They’re not the same. A suspended machine retains memory state; Fly.io resumes it by signaling the hypervisor rather than re-executing the entire boot process. According to AppSignal’s March 2026 monitoring report on Fly.io Node.js apps, suspend-based cold starts typically measure 1.5–2.5 seconds for a minimal Express app — under 50MB image, no database connection pooling at startup.
Stop-based restarts — which occur after longer idle periods or explicit machine stops — run 3–4+ seconds for the same app profile.
The practical difference: if your app gets sporadic traffic (one request every 3–4 minutes), you’ll mostly hit suspend behavior. Let it sit idle overnight and you’re getting a full stop restart at the next morning’s first request.
Node.js Initialization Cost: The Hidden Multiplier
VM resume time is only half the equation. Node.js startup cost is the other half, and it scales badly with app complexity.
Measured initialization times for common Node.js setups on Fly.io free tier (shared-cpu-1x, 256MB):
| App Profile | Node.js Init Time | Total Cold Start |
|---|---|---|
| Minimal Express (hello world) | ~180ms | ~1.7s |
| Express + Prisma + PostgreSQL pool | ~650ms | ~2.9s |
| Fastify + TypeScript build + Redis | ~820ms | ~3.3s |
| Next.js API routes (standalone mode) | ~1.1s | ~3.8s |
| NestJS with DI container | ~950ms | ~3.6s |
Estimates derived from community benchmarks and AppSignal’s 2026 monitoring data. Your numbers will vary based on image size and dependency tree.
NestJS’s dependency injection container is the worst offender. The metadata reflection pass at startup adds 300–500ms before your first route is even registered.
Mitigation Strategies That Actually Work
Three approaches consistently reduce perceived cold start latency without upgrading to a paid plan.
Lazy initialization. Don’t connect to your database at startup. Connect on first request, cache the client. This doesn’t reduce VM resume time, but it gets your HTTP server accepting connections ~400–600ms faster.
Keep-alive pinging. A free external service like UptimeRobot or Better Uptime can ping your app every 4 minutes, preventing the 5-minute suspend trigger. Vibe Coding With Fred’s Fly.io guide specifically recommends this pattern for hobby apps. It’s inelegant. It works.
Minimize image size. A 400MB Docker image takes longer to load into memory than a 90MB one. Multi-stage Docker builds with node:alpine base images routinely cut image size by 60–70%.
This approach can fail when your app has unavoidable startup costs — database migration checks, certificate loading, or complex DI wiring that can’t be deferred. In those cases, the only real fix is keeping the machine warm or paying for always-on.
Fly.io Free Tier vs. Alternatives: Cold Start Comparison
| Platform | Free Tier Cold Start | Machine Type | Node.js Support |
|---|---|---|---|
| Fly.io (suspend) | 1.5–2.5s | Shared VM | Native |
| Render (free) | 50s+ (full restart) | Container | Native |
| Railway (trial) | No cold starts (no auto-stop) | Container | Native |
| Vercel (serverless) | 200–800ms | Serverless function | Via Edge/Lambda |
| Koyeb (free) | 3–6s (full restart) | Container | Native |
Render’s free tier is notably worse — it fully stops containers after 15 minutes of inactivity, producing 50-second-plus cold starts that feel like an outage. Fly.io’s suspend model is genuinely better than full-restart competitors for low-traffic apps.
Vercel’s cold start advantage comes from the serverless model, but that’s a different deployment paradigm entirely. You’re not running a persistent Node.js process — you’re running ephemeral functions. That matters the moment you need WebSocket support, background jobs, or stateful in-memory caching. None of those work on Vercel’s serverless runtime.
Matching Deployment Choice to Traffic Pattern
Scenario 1 — Hobbyist API with sporadic traffic (under 50 requests/day)
Fly.io free tier with UptimeRobot keep-alive is a reasonable choice. Cold starts will still happen overnight and on weekends, but daily active usage stays warm. Use lazy DB initialization and keep your image under 100MB. Acceptable total cold start: under 2.5 seconds.
Scenario 2 — Portfolio project or demo app shown to recruiters
Don’t risk it. A 3-second blank response during a live demo is a bad look. Either keep the app warm with a cron-based ping service or spend the $1.94/month on a paid Fly.io machine with auto_stop_machines = "off". The cost of a bad impression is higher than $2.
Scenario 3 — Internal tool with predictable office-hours traffic
Fly.io free tier works well here. Traffic naturally keeps the machine warm during business hours. Configure fly.toml with min_machines_running = 0 and auto_stop_machines = "suspend" — Fly’s defaults. Off-hours cold starts are acceptable when no one’s watching.
What to watch next: Fly.io’s engineering blog hinted at smarter suspend scheduling in Q1 2026 — predictive warm-up based on historical traffic patterns. If that ships, free tier cold starts could drop to sub-second for apps with consistent daily rhythms. No release date confirmed as of March 2026.
Conclusion
The Fly.io free tier cold start picture for Node.js in 2025–2026 is this: 1.5–4 seconds, depending on app complexity and whether you hit a suspend or stop restart. That’s measurable and manageable with the right setup.
The summary:
- Suspend behavior (the free tier default) is meaningfully faster than full-stop competitors like Render
- Node.js initialization cost adds 180ms–1.1s on top of VM resume time
- Keep-alive pinging and lazy initialization eliminate most real-world cold start pain for hobby apps
- For anything user-facing or demo-critical, $1.94/month removes the problem entirely
Over the next 6–12 months, expect Fly.io to improve free tier performance as their hardware footprint expands. Anycast network improvements in late 2025 already cut baseline latency by roughly 15% in European regions, according to Fly.io’s public status history.
The honest question is simple: is 2 seconds acceptable for your use case? If yes, Fly.io’s free tier is one of the better free Docker hosting options available right now. If not, budget $2/month and move on.
References: Vibe Coding With Fred — Fly.io Free Tier Guide | AppSignal — Monitoring Node.js on Fly.io (March 2026) | Kuberns — What Is Fly.io (2026)
References
- Why Fly.io Is the Best Free Docker Hosting You’re Not Using | Vibe Coding With Fred
- Monitoring Your Node.js App Health on Fly.io | AppSignal Blog
- What Is Fly.io? Complete Guide to Deployment, Pricing, and Limitations in 2026 • Kuberns


