# Lifecycle

Secure Exec runs every VM inside one shared sidecar process. You rarely need to
think about it, except at the start and end of your own process.

## Start it early

The first call starts the sidecar. Call `init()` when your server boots to pay
that cost ahead of time.

secure-exec/examples/quickstart/src/lifecycle.ts:

```ts
// Every VM runs inside one shared sidecar process, which starts on first use.
// Start it when your server boots so the first request does not pay for it.
await init();

const started = performance.now();
await evaluate("1 + 2");
console.log(`first call: ${Math.round(performance.now() - started)}ms`);
```

`init` takes no options and is safe to call more than once.

## Stop it

secure-exec/examples/quickstart/src/lifecycle.ts:

```ts
// Stop the sidecar and every VM still in it. The next call starts a new one.
// Test runners need this in a teardown hook, or the worker will not exit.
await shutdown();
```

- A script that only makes one-shot calls exits on its own. The sidecar never
  keeps your process alive while no VM is running.
- Test runners such as Vitest wait for open handles, so call `shutdown()` in a
  teardown hook.
- `shutdown()` disposes every VM still running, so use it as your last resort
  cleanup on exit.

## Dispose what you create

One-shot calls dispose their VM for you. A [VM](/secure-exec/docs/vms) from
`createVm()` holds memory until you call `vm.dispose()`, and a
[context](/secure-exec/docs/contexts) lives until you dispose it or its VM.
