Skip to content

Plan the move to Sandbox SDK 1.0

Last updated View as MarkdownAgent setup

This page compares the two ways to move sandboxes from Sandbox SDK 0.12 to 1.0, and then moves every sandbox in one deploy. You cannot undo the deploy that switches your sandboxes to 1.0.

Before you start

  • Your application runs @cloudflare/sandbox 0.12.10.
  • Your 1.0 class is written. For the class, refer to Replace the Sandbox class.
  • You have a staging copy of the Worker with its own Wrangler configuration file. Set a different Worker name and a different name for each container in that file, because the --name option of wrangler deploy does not rename container applications.

Choose a path

You can move in one of two ways:

Path What happens Suits
In place One deploy moves every sandbox to 1.0. Commands that run in 0.12 containers end, and files in those containers do not carry over. Sandboxes that are short-lived or cheap to create again
Side by side A 1.0 class runs next to the 0.12 class in the same Worker. Your code moves each sandbox, and you delete the 0.12 class when none remain. Long-lived sandboxes that users return to

Neither path can split traffic with a gradual deployment. Wrangler rejects a deployment that mixes the two versions with this error:

All Worker Versions in a multi-version deployment must declare identical Durable Object-managed Container applications.

Rehearse your path on the staging Worker, with sandboxes running in it, before you follow it in production. The rest of this page moves in place. For the other path, refer to Move sandboxes side by side.

What the switch does to live sandboxes

The switch happens when the deploy that moves your class to scheduling_policy: "durable_object" goes live. Each part of a 0.12 sandbox changes as follows:

Part At the switch
Running containers Keep running in the old container application. For a short time after the deploy, your Durable Object still reports running as true, and exec() and getTcpPort() reach the 0.12 container. After that, running is false, and your code starts a 1.0 container.
Files Stay in the old containers. New containers start without them.
Running commands End shortly after. A command that returns its result when it finishes fails with HTTP 500. Streamed output stops with HTTP 200 and no error.
WebSockets Stop delivering data. Clients receive no close frame.
Pending alarms Call your 1.0 alarm() handler once for each sandbox that was active.
schedule() callbacks Never run.
0.12 storage keys Stay in Durable Object storage, unused.

Move every sandbox in one deploy

  1. Make your alarm() handler check its own state before it acts. 0.12 keeps an alarm set while a container runs, and after the switch that alarm calls your handler. If the handler throws, the platform retries it with backoff. In this example, the handler returns unless its nextCheckpoint time has passed:

    src/index.tsts
    export class MySandbox extends DurableObject<Env> {
    	// ...
    
    	async alarm(): Promise<void> {
    		// A 0.12 alarm can call this handler once after the switch.
    		const due = await this.ctx.storage.get<number>("nextCheckpoint");
    
    		if (due === undefined || due > Date.now()) {
    			return;
    		}
    
    		await this.checkpoint();
    	}
    }

    If your class has no alarm() handler, each pending alarm fails once with an internal error in your logs and then clears.

  2. Replace schedule() calls. 0.12 stores scheduled callbacks in a table that 1.0 does not read. Set the next run with this.ctx.storage.setAlarm() from your class, and do the work in alarm(). A Durable Object has one alarm, so this is the handler from step 1. To replace several schedules, store the time of each, set the alarm to the earliest, and run every task that is due in alarm(). For more information, refer to Alarms.

  3. Prepare clients for sockets that go silent. Open terminals and preview WebSockets stop receiving data at the switch, and the browser does not see them close. Have your client reconnect when a socket receives nothing for a set time, or tell users to reload after the deploy.

  4. Save the files that users need. No 1.0 sandbox can read the files in a 0.12 container. Before you deploy, save the files with 0.12 createBackup(). After the switch, restore them as Move backups describes.

  5. Rehearse on the staging Worker first. With sandboxes running there and a client connected, upload and deploy the 1.0 version to the staging Worker as steps 6 and 7 describe. Check that requests from your application work after the switch.

  6. Upload the 1.0 version:

    npx wrangler versions upload

    The upload builds the 1.0 image and creates the new container application. The version that serves traffic does not change. Note the version ID that Wrangler prints.

  7. Deploy the version when no long commands run.

    Replace <VERSION_ID> with the ID from the upload:

    npx wrangler versions deploy <VERSION_ID>@100% -y

Check the move

Send requests from your application to a sandbox, such as a command and a file read. Each Durable Object starts a 1.0 container on its first request. List the container applications in your account:

npx wrangler containers list

The list shows the new application with the name you set. The old application is still there. Wrangler named it from your Worker and class names, such as my-worker-sandbox.

Clean up

Delete the old container application. Replace <OLD_APPLICATION_ID> with its ID from the list:

npx wrangler containers delete <OLD_APPLICATION_ID>

The old application runs its containers, and bills for them, until you delete it. Deleting it stops the containers that 0.12 started and deletes their files. Durable Objects and their storage stay.

The keys that 0.12 wrote stay in the storage of each Durable Object and do nothing. If you delete them, name each key in a delete() call. Do not call deleteAll(), which also deletes your own keys and any 0.12 backup handles that you still need to convert.

Was this helpful?