Skip to content

Changelog

28 October 202614 changes

Billing 1 · Sandboxes 10 · SDKs and CLI 1 · Platform 2

6 min read

NewerOlderFollow by RSS

Usage export lists every running-disk charge, including amounts written off

In GET /v1/usage/export, each sandbox disk_used row now covers all disk usage since the previous row, and its measurements include carried, the fraction of a microdollar carried in from the previous row. A running-disk charge that your balance, cost cap or spending limits could not cover now appears as a row with chargedMicros of 0 and its written_off_micros. Charges are unchanged.

Woken sandboxes now end at their time limit

A sandbox woken with timeoutSeconds now pauses or stops (as onTimeout specifies) exactly when that time limit ends. Previously, a sandbox woken this way and left to reach its limit could be woken again by Runtime and run, billed, up to one more timeoutSeconds past the limit.

Go, Java and Ruby SDKs: terminals and tunnels stay open when the API restarts

When the API closes a terminal or tunnel WebSocket with code 1012 (Service Restart), the Go, Java and Ruby SDKs now reconnect with the resume token immediately and continue from the exact byte where they stopped, with nothing lost or sent twice; input written during the hand-off is held and sent after the reconnect. Previously, these SDKs ended the terminal or tunnel. See Resuming terminals and tunnels after a restart.

Terminals, SSH sessions and port forwards stay open when the API restarts

Previously, an API release closed every open terminal and tunnel. The API now moves each one to the instance that serves next: the server sends {"type":"restart"}, then a resume token, and closes the WebSocket with code 1012 (Service Restart). The JavaScript and Python SDKs, the CLI and the console reconnect with the token immediately and continue from the exact byte where they stopped, with nothing lost or sent twice. Clients that speak the WebSocket protocol directly can follow the same steps; see Resuming terminals and tunnels after a restart.

A request whose egress secret cannot be added returns 503 instead of sending the placeholder

When a sandbox's server has not heard from Runtime's API within the last minute (for example, in the first seconds after a server update), it holds secret values back. Previously, an HTTPS connection opened during that time went to the destination without the secret, and every request on that connection carried the placeholder for as long as the connection stayed open, even after the server heard from the API again. Connections to a secret's host are now always handled by the step that adds the secret. A request that carries the placeholder while its value is held back returns 503 Service Unavailable with X-Runtime-Egress: secret-not-current and Retry-After: 1, and the connection closes; the value is added again from the first request after the server hears from the API. Server updates also no longer hold secret values back.

Commands keep running while a server prepares to pause a sandbox

When a server paused a busy sandbox on its own (for example, when its disk ran short), it refused every command from the moment it decided to pause, which could be minutes before the sandbox stopped running, and GET /v1/sandboxes/{id} still returned running meanwhile. Commands are now accepted until the sandbox is paused, the pause is reported immediately, and the next command wakes the sandbox. If the server stops running a sandbox without reporting why, exec and file calls now return 503 sandbox_unreachable (retryable, nothing ran) with a hint to restart it with POST /v1/sandboxes/{id}:restart, instead of 409 not_running for a sandbox whose state is running.

The audit log records your account's backup encryption key

Each account's backups, snapshot copies and paused sandboxes stored off the server are encrypted with a key of its own. The audit log now records when Runtime creates that key, rotates it (the old key becomes read-only: it still opens existing backups and encrypts no new ones) and destroys an old key. A key is destroyed only after no backup, copy or replica still uses it. Entries are account.storage_key_created, account.storage_key_rotated and account.storage_key_destroyed.

A command's output stream continues when its server pauses the sandbox

When a server paused a sandbox on its own (to make room for another sandbox, or at the end of the sandbox's time limit) while a streamed exec or a process output read was in progress, the call returned 409 sandbox_paused and the command's output was lost to the caller. The API now wakes the sandbox and resumes the call, and the command runs to its exit. This also applies to an exec sent with an Idempotency-Key (every SDK sends one), which is never run twice. A sandbox with autoWake: false still returns 409 sandbox_paused.

Usage for volumes, backups and snapshots

GET /v2/volumes/{id}:usage, GET /v2/backups/{id}:usage and GET /v2/snapshots/{id}:usage return a resource's storage usage and charge for one calendar month (UTC), as GET /v2/sandboxes/{id}:usage does for a sandbox. The SDKs add the matching usage method to each.

Volumes, backups and snapshots report their measured size

In the v2 API, status.usedBytes on a volume, backup or snapshot is now measured every hour, and the new status.measuredAt field returns when it was measured. For a volume, usedBytes is the bytes written to it; for a backup or a snapshot, it is the bytes only that backup or snapshot stores, which is what its storage is billed on. Prices and billed quantities are unchanged.

Sandboxes paused for more than an hour resume in under a second

A paused sandbox's memory and disk now stay on its server until that server needs the room. Before, they were moved to off-site storage one hour after the pause, and a resume after that took 20 to 50 seconds while they were copied back. A sandbox whose server does need the room still resumes from its off-site copy, with its files and running programs intact.

Stopping a sandbox keeps writes made just before the stop, even when its agent is busy

When a sandbox whose disk is kept (or that has a volume attached read-write) is stopped, Runtime asks the guest to write its pending data to disk before the machine ends. If the guest's agent was briefly unable to take that request, for example while the sandbox was out of memory, the request was not retried, and data written in the last few seconds before the stop could be missing from the disk. The request is now retried until the guest takes it, for up to 12 seconds. The stop itself still returns immediately.

Sites that block by address are paced per outbound address

Each outbound address shared by more than one account now opens at most 150 new connections an hour to Google, Bing, Amazon and the other sites that block by address, for all accounts together, and at most 100 an hour for any one account. This includes the addresses kept for scrapers, which had no limit, so one account's traffic could get such an address blocked for every account sent from it. Past a limit, a connection returns 429 Too Many Requests with X-Runtime-Egress: rate-limited:guarded-site and Retry-After. Before, one account could open 300 an hour from a shared address. A dedicated outbound address is not limited.

A create whose sandbox is deleted while it starts returns 410 deleted

If a sandbox is deleted before its own POST /v1/sandboxes returns, that create now returns 410 deleted with details.sandboxId. It previously returned 404 not_found. A create with getOrCreate: true whose name's holder is deleted while the create waits for it now creates a new sandbox instead of returning 404. See names.

Other days.

Cut your cloud billby 75%.

No card to start. Billed by the second after.

Start free, no card