Skip to content

Cloud sleep and wake

When a cloud-hosted application has no active connections for a while, Edgible can stop the tenant microVM. The next request brings it back. Persistent storage stays attached across sleep cycles.

This guide shows how to enable sleep, what the request-on-sleep behavior looks like, and how to tune it.

Sleep is useful when:

  • The service has bursty traffic — most of the time it sees nothing, occasionally it sees real load.
  • You don’t want to pay for compute that isn’t doing anything.
  • It’s OK for the first request after an idle period to take a few extra seconds.

Don’t use sleep when:

  • The service does background work that has to keep running (cron jobs, queue consumers, long-lived websockets).
  • The first request after idle has a hard latency budget that a wake can’t meet.

Sleep only applies to cloud placement. On serving-device, the workload runs continuously — sleep settings on a serving-device application are rejected by validation.

Add a spec.cloud.sleep block:

app.yml
apiVersion: v3
kind: Application
metadata:
name: bursty-api
organization: <your-org-id>
spec:
placement:
strategy: cloud
region: us-east-1
workloads:
- name: web
type: compose
composeFile: ./docker-compose.yml
ports:
- { name: http, containerPort: 8080, protocol: tcp }
access:
- name: public
type: https
target: { workload: web, port: http }
hostname: { generated: true }
tls: { managedBy: edgible }
policies: { auth: { mode: none } }
cloud:
sleep:
enabled: true
idleAfter: 5m
wake: sync
minActive: 0
FieldWhat it does
sleep.enabledMaster switch. true lets the platform stop the tenant when idle.
sleep.idleAfterHow long to wait without active connections. 30s, 5m, 1h.
sleep.wakeWhat happens to the request that arrives while asleep. sync blocks the request until the workload is up; async returns 202 immediately and replays the request when ready.
minActiveMinimum tenants kept running. 0 allows full sleep; 1 keeps one always-on.

Deploy as usual:

Terminal window
edgible stack deploy -f app.yml

Tail logs while you exercise the application:

Terminal window
edgible application logs bursty-api --follow

Then:

  1. curl https://<hostname>/ — first hit, the tenant is already up.
  2. Wait idleAfter plus a few seconds.
  3. You’ll see a tenant stopped line in the logs.
  4. curl https://<hostname>/ again. The request hangs briefly while the tenant boots, then succeeds.
  5. The logs show a tenant started line followed by your application’s startup output.

For a 5m idle period plus a typical 10–20 second cold start, this is invisible to most consumers. Tune idleAfter shorter if you want aggressive sleep, longer if you want to absorb more bursts before stopping.

  • sync — the gateway holds the public TCP connection while the platform brings the tenant back. Good for browsers and most HTTP clients; the user just sees a slightly slower response.
  • async — the gateway returns 202 Accepted immediately and replays the request once the tenant is ready. Useful when the caller can poll, queue, or retry.

Pick based on the consumer. If you’re not sure, start with sync.

Persistent storage stays attached across sleep cycles — the tenant microVM stops, but its disk image isn’t discarded. When the tenant boots back up on wake, it sees the same filesystem state.

This is true for mobility: cloud-only and mobility: movable volumes. Ephemeral storage (type: ephemeral) is recreated on wake, so don’t put anything you need persisted there.

  • Stop-start sleep only. The platform stops and restarts the tenant microVM. Pause/resume snapshot/restore would let wakes return in milliseconds rather than seconds; it’s on the roadmap, not in the box today.
  • Background work doesn’t prevent sleep. Sleep is gated on inbound connections, not on what the workload is doing internally. If your workload runs scheduled tasks, set minActive: 1 to keep it always-on.
  • WebSocket and long-poll connections do prevent sleep. Anything that holds a TCP connection through the gateway counts as active.