> ## Documentation Index
> Fetch the complete documentation index at: https://namespace.so/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Create or Reuse an Instance

> Make instance creation idempotent with a unique tag, and carry a warm cache across instance lifetimes.

A worker that should exist exactly once is awkward to build on top of plain `CreateInstance`, because a retry creates a second machine.
`experimental.uniqueTag` solves that: the platform claims the tag for the instance, and a later request carrying the same tag returns the running instance instead of creating another one.

Pairing the tag with a `CACHE` volume gives the replacement instance a warm cache when the previous one is gone, so a restart does not start from scratch.

<Info>
  `uniqueTag` lives under `experimental`. Fields there can change or be removed at any time.
</Info>

<Steps titleSize="h3">
  <Step title="Claim a unique tag at creation">
    Repeating this request with the same tag is safe. The response describes the existing instance if one is already running under the tag.

    <CodeGroup>
      ```typescript TypeScript theme={null}
      const created = await computeClient.compute.createInstance({
        shape: {
          virtualCpu: 2,
          memoryMegabytes: 4096,
          machineArch: "amd64",
          os: "linux",
        },
        documentedPurpose: "ensure with cache example",
        deadline: timestampFromDate(new Date(Date.now() + 60 * 60 * 1000)),
        experimental: { uniqueTag: "ensure-with-cache" },
        containers: [/* see the next step */],
      });
      ```

      ```go Go theme={null}
      resp, err := computeClient.Compute.CreateInstance(ctx, &computepb.CreateInstanceRequest{
      	Shape: &computepb.InstanceShape{
      		VirtualCpu:      2,
      		MemoryMegabytes: 4 * 1024,
      		MachineArch:     "amd64",
      		Os:              "linux",
      	},
      	DocumentedPurpose: "ensurewithcache example",
      	Deadline:          timestamppb.New(time.Now().Add(1 * time.Hour)),
      	Experimental: &computepb.CreateInstanceRequest_ExperimentalFeatures{
      		UniqueTag: "ensure-with-cache",
      	},
      	Containers: []*computepb.ContainerRequest{{
      		// see the next step
      	}},
      })
      ```
    </CodeGroup>
  </Step>

  <Step title="Mount a cache volume under a tag">
    A volume with `persistencyKind: CACHE` is restored on a best-effort basis from the most recent volume carrying the same `tag`.
    The container below writes an index file on first boot only, so a restart that restores the cache keeps the original file.

    <CodeGroup>
      ```typescript TypeScript theme={null}
      import { VolumeRequest_PersistencyKind } from "@namespacelabs/sdk/proto/namespace/cloud/compute/v1beta/compute_pb";
      import { ContainerPort_Proto } from "@namespacelabs/sdk/proto/namespace/cloud/compute/v1beta/compute_pb";

      containers: [
        {
          name: "server",
          imageRef: "busybox:1.37",
          entrypoint: ["/bin/sh", "-c"],
          args: [
            `if [ ! -f /cache/index.html ]; then
        printf 'cache initialized at %s\\n' "$(date -u +%FT%TZ)" > /cache/index.html
      fi
      exec httpd -f -p 8080 -h /cache`,
          ],
          volumes: [
            {
              mountPoint: "/cache",
              tag: "ensure-with-cache-data",
              sizeMb: 1024,
              persistencyKind: VolumeRequest_PersistencyKind.CACHE,
            },
          ],
          exportPorts: [
            { name: "http", containerPort: 8080, proto: ContainerPort_Proto.HTTP },
          ],
        },
      ]
      ```

      ```go Go theme={null}
      Containers: []*computepb.ContainerRequest{{
      	Name:       "server",
      	ImageRef:   "busybox:1.37",
      	Entrypoint: []string{"/bin/sh", "-c"},
      	Args: []string{`if [ ! -f /cache/index.html ]; then
        printf 'cache initialized at %s\n' "$(date -u +%FT%TZ)" > /cache/index.html
      fi
      exec httpd -f -p 8080 -h /cache`},
      	// A later instance can best-effort restore the latest committed volume carrying this tag.
      	Volumes: []*computepb.VolumeRequest{{
      		MountPoint:      "/cache",
      		Tag:             "ensure-with-cache-data",
      		SizeMb:          1024,
      		PersistencyKind: computepb.VolumeRequest_CACHE,
      	}},
      	ExportPorts: []*computepb.ContainerPort{{
      		Name:          "http",
      		ContainerPort: 8080,
      		Proto:         computepb.ContainerPort_HTTP,
      	}},
      }},
      ```
    </CodeGroup>
  </Step>

  <Step title="Read the allocated endpoint">
    The create response lists each container with the endpoint allocated for every exported port. A reused instance returns the endpoint it already has.

    <CodeGroup>
      ```typescript TypeScript theme={null}
      const server = created.containers.find((c) => c.name === "server");
      const http = server?.exportedPort.find((p) => p.containerPort === 8080);

      if (!http) {
        throw new Error("HTTP endpoint was not allocated");
      }

      console.log(`https://${http.endpoint}`);
      ```

      ```go Go theme={null}
      for _, container := range resp.Containers {
      	if container.Name != "server" {
      		continue
      	}
      	for _, port := range container.ExportedPort {
      		if port.ContainerPort == 8080 {
      			fmt.Printf("https://%s\n", port.Endpoint)
      		}
      	}
      }
      ```
    </CodeGroup>

    HTTP endpoints require Namespace authentication by default. See [access controls](/docs/platform/networking/ingress#access-controls).
  </Step>

  <Step title="Release the tag when you are done">
    `ReleaseUniqueTag` gives up the claim so the next request creates a fresh instance. It accepts an optional `ifInstanceId` matcher, which makes the release safe to call from a worker that may have already been replaced.

    <CodeGroup>
      ```typescript TypeScript theme={null}
      await computeClient.compute.releaseUniqueTag({ uniqueTag: "ensure-with-cache" });
      ```

      ```go Go theme={null}
      _, err = computeClient.Compute.ReleaseUniqueTag(ctx, &computepb.ReleaseUniqueTagRequest{
      	UniqueTag: "ensure-with-cache",
      })
      ```
    </CodeGroup>
  </Step>
</Steps>

## Source

`go/ensurewithcache` in [github.com/namespacelabs/examples](https://github.com/namespacelabs/examples).
The TypeScript version above follows the same request fields; only the Go example ships in the repository.

See [cache volumes](/docs/platform/storage/cache-volumes) for how volume tags and reuse work, and [instance configuration](/docs/platform/instances/configuration) for the rest of `CreateInstanceRequest`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.