Tell Me When Down
How it worksWhat we checkPricing
Security reportsBlogFree toolsCompareDocs
Log inGet started
All postsWhen your free tier falls asleep

Fly.io machine keeps stopping: auto_stop_machines explained

September 21, 2026·6 min read
A lone hot air balloon hanging still over calm water under a night sky.

Your Fly.io app worked a minute ago. Now the first request hangs for a couple of seconds, or your nightly job simply never ran.

Nothing crashed. Fly Proxy stopped your machine because it looked idle, and that is the default for new apps.

Here's why it happens, and the exact fly.toml settings for the three cases people actually have.

Why Fly.io machines keep stopping

Fly Proxy is the router in front of your app. It sees every inbound request, and it decides when machines should run.

When a region has more running machines than its traffic needs, the proxy stops or suspends one. Its stop loop runs every few minutes and stops at most one machine per region per pass.

When a request arrives and there's no spare capacity, the proxy starts a stopped machine again. It never creates or destroys machines; it only switches the ones you have on and off.

"stop"
default auto_stop_machines for new apps
0
default min_machines_running for new apps
~2 s+
Fly's figure for a common app's cold start
few 100 ms
resume time from a suspended machine

fly.toml auto_stop_machines, auto_start_machines, min_machines_running

Three keys under [http_service] (or [[services]]) control all of this.

  • auto_stop_machines is what the proxy does to an idle machine: "off", "stop" or "suspend". The old false and true mean off and stop.
  • auto_start_machines lets the proxy start a stopped machine when a request comes in.
  • min_machines_running keeps that many machines up, but only in your primary region, and only when auto-stop is on.
The proxy only looks at inbound traffic. It does not look inside your container, so a cron job, queue consumer or long report running in a machine doesn't count as "busy".

How to keep a Fly.io app always on

Turn auto-stop off. The proxy then never stops a machine for being idle.

fly.toml · always on
[http_service]
  internal_port = 8080
  force_https = true
  auto_stop_machines = "off"
  auto_start_machines = true
  min_machines_running = 1

Leaving auto_start_machines on is still useful. If a machine stops for another reason, the next request brings it back.

How to scale to zero but wake fast with suspend

Suspend is the middle ground. Fly snapshots the whole running machine, memory included, and resumes it from that snapshot.

Fly puts a resume at a few hundred milliseconds, against roughly two seconds or more for a cold start of a common app.

fly.toml · scale to zero, wake fast
[http_service]
  internal_port = 8080
  force_https = true
  auto_stop_machines = "suspend"
  auto_start_machines = true
  min_machines_running = 0

Suspend has conditions, all from Fly's docs:

  • The machine needs 2 GB of memory or less.
  • No swap configured, and no schedule configured.
  • Every deploy throws the old snapshot away, so the first wake after a deploy is a full cold start.

How to stop Fly.io from stopping a background worker or cron

This is the case that fails silently. A cron schedule inside a machine that auto-stops just doesn't fire, because the machine isn't running when the time comes.

The clean fix is a separate process group with no [http_service]. Fly Proxy never touches machines it doesn't route traffic to.

fly.toml · web sleeps, worker never stops
[processes]
  web = "node server.js"
  worker = "node worker.js"

[http_service]
  processes = ["web"]
  internal_port = 8080
  auto_stop_machines = "suspend"
  auto_start_machines = true
  min_machines_running = 0

# No [http_service] for "worker": Fly Proxy never stops or starts it.

Run only one copy of the cron process. Fly's own guide warns that four machines running cron means four copies of every email.

Our own check worker runs on Fly and has to probe sites every minute, traffic or not. Its fly.toml sets auto_stop_machines = false and auto_start_machines = false, so nothing ever switches it off.

For rare jobs, Fly also has scheduled machines. They only come in hourly, daily, weekly or monthly buckets, not exact cron times.

What keeping a Fly.io machine running costs

There is no free tier for new accounts. Fly stopped selling plans on 7 October 2024; new orgs get a short trial, then pay as they go.

The trial ends after 2 machine-hours or 7 days, whichever comes first. Older plans that included free machines are still honoured for people who bought them before that date.

The smallest machine, shared-cpu-1x with 256 MB, is listed at about $2.02 a month running full time. Prices vary by region.

A stopped machine is billed only for its disk, at $0.15 per GB per month. So the real choice is a couple of dollars against a slower first request.

For a small web app, suspend usually wins. For anything that runs scheduled or background work, a couple of dollars for an always-on worker is cheaper than one missed job.

Fix your fly.toml with Claude or ChatGPT

Paste your config into this prompt and fill in the two blanks. It asks for the caveats most answers skip.

paste into Claude or ChatGPT
Here is my fly.toml. Help me fix Fly.io machines auto-stopping.

[paste your fly.toml here]

What the app does: [e.g. "Next.js site" / "API that receives webhooks" / "web app plus a background queue worker" / "cron jobs run inside the app"]
What matters most: [fast first request / lowest bill / jobs must never be interrupted]

Please:
1. Explain what my current auto_stop_machines, auto_start_machines and min_machines_running settings actually do, in plain English.
2. Remember min_machines_running only applies in the primary region, and only when auto_stop_machines is "stop" or "suspend".
3. If any cron, queue or background work runs inside a machine that has an [http_service], warn me: Fly Proxy only counts inbound requests, so it can stop that machine mid-job.
4. Suggest the smallest change that fits what matters most: "off", "suspend" (only if memory is 2 GB or less and no swap), or a separate process group with no [http_service] for the background work.
5. Give me the full corrected fly.toml and the flyctl commands to apply it.

How to know your scheduled job on Fly.io actually ran

Every fix above can quietly undo itself. A deploy resets a setting, a process group loses its machine, or the worker crashes and stays down.

An uptime check on your URL won't catch it, because the web side still answers. The job just stops, and nothing tells you.

A heartbeat flips that around. The job reports "I ran" each time it succeeds, and silence is what raises the alarm.

crontab · heartbeat on success
# In your crontab / supercronic file: only heartbeat if the job succeeded
0 3 * * * node backup.js && curl -s -X POST https://ingest.tellmewhendown.com/api/ingest/heartbeat \
  -H "Authorization: Bearer $TMWD_API_KEY" \
  -H "content-type: application/json" \
  -d '{"type":"nightly-backup"}'

The && matters: a failed backup sends nothing, so it counts as missed. There's more on the pattern in how to know if your cron job actually ran.

The same idle-sleep trap hits other hosts too. See Render spinning down, or the cross-host playbook in how to keep a free backend awake.

Every Fly setting above comes from the Fly.io autostop docs and the suspend and resume reference.

Let your Fly app sleep. Just don't let your jobs.

Join Tell Me When Down free and we'll watch your Fly.io app from outside and listen for your job heartbeats. A machine that never came back, or a cron that quietly stopped firing, and you get an email in minutes, not a message from a user.

Watch my appfree · no card required
more on when your free tier falls asleep
MongoDB Atlas cluster paused: why it happens and how to stop itAtlas pauses a Free cluster after 30 days with no connections, and your app just starts failing. Here's how to resume it, the version catch that can block a resume, and how to keep it from happening again.Upstash Redis database archived: why it happened and how to restore itUpstash archives a free Redis database after a month of no use, and your app's calls start failing. Your data is backed up. Here's how to restore it and keep it from happening again.How to keep a free backend awakeFree tiers sleep when idle: Supabase pauses, Render spins down, Neon scales to zero. Here's the map — how each host sleeps, why keep-alive pings have a catch, and what actually keeps a free app responsive.How to stop Render spinning down your free serviceFifteen idle minutes and your free service is asleep; the next visitor waits through the cold start. Here's why keep-warm pings have a catch, and what actually keeps a free app responsive.How to keep a Railway app awakeRailway retired its free tier and added opt-in App Sleeping. Here's what actually happens to an idle service now, how to keep one awake without cancelling out the savings, and why a keep-alive ping can't warn you when it dies.How to stop Neon autosuspending your databaseNeon scales your compute to zero after a few idle minutes, and the next query wakes it. Here's what Scale to Zero does, why the fix depends on whether latency or a surprise bill is your real problem, and how to keep it warm safely.Why is my website slow the first time I open it?Slow the first time, instant after? Your site probably isn't slow — it was asleep. Free hosting pauses an idle app and takes seconds to wake it. Here's why it happens, which hosts do it, and your three options.Why Supabase pauses your project — and how to stop it happening againThe pause always lands when you've stopped watching. Here's the real mechanic behind it, the 90-day deadline nobody mentions, and why most keep-alive scripts quietly stop working.

spot something wrong or out of date? [email protected] — we'll fix it

Tell Me When Down

Uptime and security monitoring for people who'd rather ship than babysit servers. We watch so you can sleep.

product
How it worksWhat we checkSecurity reportsPricingDocsBlogFAQ
free toolsWebsite security scanSupabase pause checkRender sleep checkMixed content checkerSecurity headers checkCookie security checkSSL expiry check
comparevs UptimeRobotvs Better Stackvs PingdomFor indie hackers
company
StatusAbout our botContactPrivacyTerms
© 2026 TellMeWhenDown · tellmewhendown.com