When is a Sprite actually cold? Reported-cold Sprite woke with its original process running

I’m testing Sprites for per-user dev environments and hit something confusing about cold.

My test Sprite ran a tiny Service that writes two files: a counter of how many times the Service has started, and a heartbeat that resets to zero on every start. I created ten more Sprites to fill the org’s warm limit and let everything go idle. The API then reported:

Running: 0, Warm: 0, Cold: 11

Every Sprite, including mine, was counted cold. But when I woke it, the start counter was still 1 and the heartbeat continued from where it left off (598 → 1207). The original process had survived. That’s a warm resume, not the documented cold behavior (“in-memory state is dropped”).

I’m rerunning now with per-Sprite checks: three fresh Sprites each individually report status: "cold" and have for many hours. I’ll wake them one at a time and post whether their processes survived.

Questions:

  1. Can cold (the org counters or the per-Sprite status field) include Sprites whose memory is still intact, or should cold always mean memory is gone?
  2. Is there a documented signal that memory was really discarded — boot ID change, last_started_at bump, anything machine-readable?
  3. Is there a supported way to force a Sprite cold, for testing?
  4. Is per-Sprite usage (CPU/RAM/storage) available via API or export, and with what delay?

Thanks!

Edited for brevity and to add exact counter values and the follow-up run.

Update: Three fresh Sprites sat idle, and all three showed status: "cold" the whole time (since 2026-07-14 17:37 UTC). I checked again seconds before each wake.

I woke one after 13 hours cold and another after 28 hours. Both times the original process was still there:

  • boot ID unchanged
  • Service start count still 1
  • heartbeat continued where it left off, not reset

So even after a day of reporting cold, memory was never dropped. I’ll wake the third Sprite at the 48-hour mark and post that too.

One more detail: updated_at never changes after creation, so it doesn’t show lifecycle transitions either.

Which leaves the main question: does cold mean “scheduled for eviction” rather than “memory is gone”? And if so, what tells me when the memory is actually gone?

The true meaning of “cold” is pretty broad. In most cases, “cold” Sprites are suspended. This is to optimize start-up time, but has the side effect of keeping your processes alive. Cold Sprites are eligible to move between hosts for load-balancing, and if your Sprite is moved, the memory is discarded. Since we can’t make any guarantees about when these moves happen, assume your processes will be lost unless you have an ongoing task.

To answer your questions:

  1. Yes, but this is not something we suggest relying on. We can only promise that your workload keeps running if you register it as a service.
  2. Not officially, but Linux has several mechanisms (/proc/stat (btime) btime is updated on resume, /proc/sys/kernel/random/boot_id).
  3. Unfortunately, no. We don’t want people to rely on the warm/cold behavior. You can simulate a cold start by restarting your registered services.
  4. We only provide usage for the whole organization. You can view it in your Fly.io dashboard at Billing > Invoices > Cost Explorer.