Sleeping and waking

Services can sleep when nobody uses them, and asleep their size costs nothing. A volume is billed by its size either way, awake, asleep or stopped, since its disk is kept. Asleep is paused: the app's virtual machine is frozen where it was, for as long as it sleeps. The next request lets it go on, and it answers almost at once. Nothing asleep is ever stopped; only you stop a service (see Switching a service off).

For its first half hour asleep, an app keeps everything in memory. After that it sleeps deeply: its memory moves to the server's disk (swap) and comes back as the app touches it, so the first answers after waking take a little longer: a small app's first answer took about a tenth of a second instead of a few hundredths. That's what lets a server keep many apps asleep without holding their memory. A server short of memory (it keeps a quarter free) does the same sooner, for the apps paused longest.

A service is awake while it answers requests, billed at its size. After 10 minutes without a request (you choose how long) it's asleep: paused, frozen where it was with its memory kept, its size not billed. After half an hour it's deeply asleep: its memory moved to the server's disk. The next request wakes it from either and is held until it answers, in about 40 ms when paused and about a tenth of a second for a small app deeply asleep; calls from the project's other services wake it too. Only Stop switches it off, and then no request wakes it until Start.

The first request after a deployment starts the new version instead. While it starts it gets two cores, whatever its own size, so it's up sooner; the extra cores aren't charged.

Either way the request is held, not dropped, and answered once the app is up. If the app opens its port before it can serve (many frameworks do), give it a health check path: the request is then held until that answers, instead of reaching an app that isn't ready.

Choosing

In the service's Scaling tab, When nobody is using it:

Private services

A private service always runs, unless you ask it to sleep: Sleep — a call from inside the project wakes it in its Scaling tab, or sleep = "10m" beside public = false in alf.toml. It then sleeps like a public one, and a call from the project's other services wakes it (see below). A database never sleeps.

Only calls wake it, so keep these running:

alf doctor warns about a private service that sleeps and that nothing in its project has called for a week: most likely one of these.

Calls from inside the project

A sleeping service wakes for the project's other services too, not only for visitors: when another service calls it by name (web:3000), the call is held while the app wakes, then answered. Calls from inside also count as use, so a service that's only ever called by your own backend doesn't fall asleep in the middle of it.

How: every app has a stable address inside the project, held by its server (its front), and its name resolves there. The server wakes the app if needed and passes the call on; HTTP and gRPC calls are kept with the service's requests, saying which service made them. Databases are reached at their containers directly, as they're always there.

Good to know:

Switching a service off

Sleeping is the service's own idea and the next request undoes it. Switching it off is yours, and nothing undoes it: Stop on the service's page keeps it down until you press Start.

While it's off:

Agents can do the same with the stop_service and start_service tools, and the API with POST /services/{id}/stop and /start.

Good to know