BYOC Pinning

Namespace pinning reserves dedicated query nodes for a namespace, so it stays warm on local SSD and gets predictable throughput and latency. On a BYOC cluster, the pinned nodes run in your own cloud account.

Your BYOC kit lists the node types you can pin to. When you pin a namespace, you choose one, and each of its replicas gets a dedicated node of that type. Nodes are created when you pin and removed after you unpin, so you only pay for them while the namespace is pinned.

Enable pinning

Add the node types to the turbopuffer.tfvars of your BYOC kit. For each one, list the SKUs it can run on and the vCPU, memory, and local SSD of one node. Names are lowercase letters, digits, - or ..

query_pinning_node_types = {
  "medium" = {
    # GCP uses whichever of these has capacity
    skus       = ["c4a-highmem-32-lssd", "c4-highmem-32-lssd"]
    cpu        = 32
    memory_gib = 248
    disk_gib   = 1875
  }
  "large" = {
    skus       = ["c4a-highmem-72-lssd"]
    cpu        = 72
    memory_gib = 576
    disk_gib   = 6000
  }
}

Listing more than one SKU lets a node type run on any of them, so pinning still works when one is out of capacity. Set cpu, memory_gib, and disk_gib from the smallest SKU listed.

Check that the region has enough vCPU quota for pinned nodes on top of your regular query and index nodes. Each replica gets its own node, and a sharded namespace pins every shard separately, so a namespace with 4 shards and 2 replicas uses 8 nodes.

Apply the change:

terraform apply -var-file=turbopuffer.tfvars

This regenerates values.yaml and compute_classes.yaml. Apply the compute classes, then roll out values.yaml with helm upgrade as described in Configuration.

kubectl apply -f compute_classes.yaml

Pin a namespace

Pin with the metadata API.

curl -X PATCH "https://<cluster_endpoint>/v1/namespaces/<namespace>/metadata" \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{"pinning": {"node_type": "large", "replicas": 2}}'

Always set node_type to one of the node types you defined. turbopuffer does not choose or change it for you. Once pinned, watch pinning.status.utilization in the namespace metadata. It is the highest of utilization_cpu, utilization_disk, and utilization_disk_io, which are also reported. High utilization values mean the namespace may need more replicas or a larger node type. To resize, send the same PATCH with a new node_type.

If your cloud provider has no capacity for the node type, the pin waits until a node can be created. Queries keep working on the regular query nodes in the meantime. Check progress with GET /v1/namespaces/:namespace/metadata.

To see the pinned pods and the nodes they run on:

kubectl get pods -n turbopuffer -o wide \
  -l turbopuffer-query-pinning-target-node-type=large

See Pinning for replicas and monitoring.