Lifecycle and sleep
States, moves, and the one setting that decides when a briq stops on its own.
States
creating → running → stopping → stopped → starting → running
running → stopping → sleeping → starting → running
stopped by a limit → sleeping, once the limit clears
any live state → destroying → destroyed
a failed move → error| State | Meaning | Billed |
|---|---|---|
creating | Image pulling, healthcheck pending | No |
running | Healthcheck passed, or the process is up | Yes |
stopping | Stop on its way | Yes |
sleeping | Machine stopped, disk kept. The next call or visit wakes it | No |
stopped | Machine stopped, disk kept: by briq_stop, by its process exiting, or by a limit not yet cleared. See Other stops | No |
starting | Start on its way | No |
destroying, destroyed | Machine and disk removed | No |
error | The create failed: an image, a healthcheck that never passed, a process that exited before it was ready, or the infrastructure. Reason in error. Destroyed automatically after 7 days (destroysAt); its logs are readable until then | No |
briq_stop, briq_start and briq_destroy return once the move lands (up to 30 seconds), or with
the pending state. They are safe to repeat: stopping a stopped briq returns its state, and asking
again while a move is in flight waits for it. A destroy overtakes any move in flight. Impossible
moves, like starting a destroyed briq, return invalid_state (409).
Moves run in the background: if your client disconnects, the briq is still tracked, still put to sleep on time, and the move completes.
Sleep
Every briq has one setting that decides when it stops on its own: sleep. After that long without
use, the briq goes to sleep. A sleeping briq keeps its disk and is not billed for compute, and the
next use wakes it.
sleep | The briq |
|---|---|
"1h" (default on briq.cloud) | sleeps after 1 hour without use |
"30m", "3h", "7d" | sleeps after that long without use: 5 minutes to 7 days |
"never" | is always on: it runs until someone stops it, its process exits, or a limit stops it. Pro plan and above |
Nothing is deleted because of time. A sleeping briq is still there tomorrow and next month, with
its data, until you briq_destroy it.
The sleep value
A string: a whole number and a unit (m for minutes, h for hours, d for days), or "never".
Never a number. A call that sends one is refused, with the string to send instead:
sleep must be a string: "30m", "3h", "7d" or "never". You sent 30, a number. For 30 minutes, pass "30m"Responses show the shortest exact form: "120m" comes back as "2h". Every response about a
running briq carries sleepsAt, the time it goes to sleep unless it is used before then. Every
use moves it later, so read it as a time, not a deadline. It is null while the briq is not
running, and for an always-on briq.
What counts as use
- Your calls on any briq of its stack:
briq_exec, the file tools,briq_logs,briq_expose. Working on an app is using the database behind it too. - Requests to the URL of any briq in its stack. A request to a private URL counts only when it carries the URL's token.
- On the dashboard, running a command. Watching a briq's page or its logs does not count.
Work that happens only inside the briq is not seen: a long job, a worker reading a queue, a bot
that only opens outgoing connections. Give such a briq a sleep longer than that work, or
"never".
Waking up
The next call that needs the briq running (an exec, a file read or write, an expose) wakes it
first, and the sleeping briqs of its stack with it, each under the agent's own limits (a sibling
past them stays asleep). The agent sees a slower call, not an error. A
visit to its URL wakes the whole stack and waits for it. nano and small resume from a memory
snapshot in about a second; larger sizes start from scratch, and the first visitor waits a few
seconds.
Changing it
Pass sleep to briq_run (with a recipe, every briq it makes gets the same), to briq_fork, or
call briq_set_sleep on an existing briq:
briq_set_sleep({ briq: "bq_7kq2m9x1p4ab", sleep: "3h" })
briq_set_sleep({ briq: "bq_7kq2m9x1p4ab", sleep: "1d", stack: true })A running briq sleeps the new window from now. A sleeping briq stays asleep: the window applies
from its next wake. With stack: true, every briq of its stack gets the same.
Limits
A window must be one the environment and the agent's key allow:
- The longest window is 7 days on briq.cloud.
- A key can set a shorter longest window (
maxSleep, see Keys and policy). "never"needs the Pro plan or above. A team that moves down keeps the always-on briqs it has; only new ones are refused.
A longer window is refused, never shortened behind your back, and the error says what to send:
this fork would sleep after "3d", longer than this key allows ("1d"); pass sleep: "1d" or shorterA fork keeps its source's sleep unless you pass one, so a fork made by a key with a shorter
longest window is refused the same way.
Example: a site that stays reachable for a month
briq_run({ recipe: "node", params: { files: … }, expose: "public", sleep: "30m" })With no visits for 30 minutes it sleeps, and the next visit wakes it. It costs nothing while it sleeps, and stays reachable for as long as you keep it.
Other stops
A briq also stops when:
stoppedReason | What stopped it | What brings it back |
|---|---|---|
cap | Its key's daily spend cap | From the next UTC day, or once the cap is raised, it is asleep: the next use wakes it |
credits | The team ran out of credits | Once the team tops up (or pays as it goes), it is asleep: the next use wakes it |
user | briq_stop, also on a sleeping briq: visits then no longer wake it | briq_start |
exited | Its own process ending | briq_start (see below) |
Until then, a call that needs the briq running fails: quota_exceeded (402) for the cap,
payment_required (402) for credits, invalid_state (409) after a stop or an exit. Its URL
answers 503. A briq the provider stopped on its own (provider) is asleep, like an unused one.
The spend cap and the credits are what bound a briq in use: a briq is never stopped while it is in use because a timer ran out. Briqs made from the dashboard have a daily cap too.
When the process exits
A briq runs one long-lived process: the image's command, or your cmd. When it exits (a crash, a
missing file, a command that simply finishes), the briq stops with stoppedReason: "exited"; a
process that failed (a non-zero exit code) is first restarted up to three times. Its status carries lastExit: the exit code, the
time, and whether it ran out of memory. briq_logs shows what it printed.
An exited briq does not come back on the next call or visit, since that would only repeat the
exit: calls return invalid_state with the exit code. briq_start runs the same command and files
again, which is right when the cause was outside it (a dependency that was down, a spike that ran
it out of memory). A briq's command, files and size cannot be changed in place: to change them,
run a new briq with the fix and briq_destroy this one. The usual cause is a command that needs
files the briq does not have, such as your app's code: pass those in the spec's
files, written before the process starts.
A process that exits before the briq is ready (before its healthcheck passes) fails the create
instead: the briq is in error, and error says how the process exited.
A process that is still up when its healthcheck's timeoutMs runs out is a slow boot, not a
failure: the briq stays creating and the create waits for the healthcheck again, up to three
times in all. Meanwhile error says it is still starting. Only then does the create fail.
A long time awake
A briq awake for 7 days in a row is marked in briq_list and on the dashboard ("awake for 8
days"). It is always on, or something keeps using it: often an uptime check or a crawler on a
public URL. It changes nothing about the briq; it is there so that a briq nobody is watching does
not run unseen.
Forks
briq_fork creates a new briq from a copy of a running, sleeping or stopped
briq's volume, with its own lifecycle. A briq mid-move cannot be forked until the move lands.