Home / OCI

OCIHow-toIntermediate

Optimization: using OCI preemptible instances for batch, CI and OKE workers

Preemptible instances run on spare OCI capacity at a discount but can be reclaimed at any time. Pick workloads that tolerate interruption, launch preemptible VMs and OKE node pools, design for restarts with checkpoints and retries, and keep a non-preemptible baseline for critical work.

Deepak Bhardwaj3 min read

Applies toOCI Compute preemptible capacity (VM shapes), OKE managed node pools with preemptible nodes, instance pools

What preemptible means

  • Billed at a discount compared with on-demand. Check current pricing for your shape.
  • OCI can reclaim (terminate) the instance at any time when it needs the capacity, without a long warning.
  • You choose whether the boot volume is kept or deleted on preemption.

So preemptible capacity suits work that can stop and resume.

Good and bad fits

Good fit Not a fit
Batch processing with checkpoints Single-instance databases
CI/CD build agents Stateful services without replicas
Rendering, simulations, test environments Anything where interruption breaks a customer flow
Stateless OKE workers with multiple replicas Licence servers, domain controllers, jump hosts

1. Launch a preemptible VM

oci compute instance launch --compartment-id $C --availability-domain "$AD" \
  --shape VM.Standard.E5.Flex --shape-config '{"ocpus": 4, "memoryInGBs": 32}' \
  --subnet-id $SUBNET --image-id $IMAGE --display-name batch-worker-01 \
  --preemptible-instance-config '{"preemptionAction": {"type": "TERMINATE", "preserveBootVolume": false}}'

Capacity may not be available for every shape or availability domain at every moment. Allow several shapes or ADs in your automation, and handle "out of capacity" responses with a retry.

2. OKE node pools with preemptible nodes

Create a separate node pool with preemptible capacity (node configuration → capacity type preemptible, in console, Terraform or CLI), and taint it so only tolerant workloads land there:

kubectl taint nodes -l pool=preemptible capacity=preemptible:NoSchedule
tolerations:
- key: capacity
  operator: Equal
  value: preemptible
  effect: NoSchedule
nodeSelector:
  pool: preemptible

Set taints and labels through the node pool's initial node labels / cloud-init so new nodes get them automatically. Keep system add-ons and critical services on a regular node pool.

3. Design for interruption

Practice How
Checkpoint progress Write state to Object Storage or a database every few minutes
Idempotent tasks Re-running a task gives the same result
Work queues Workers pull from a queue (OCI Queue, Streaming); unacknowledged work returns to the queue
Replicas and PDBs Several replicas spread across nodes; PDBs that still allow movement
Short job units Many small jobs instead of one 10-hour job

4. Detect preemption

  • OCI Events: instance termination events, routed to Notifications or a Function that logs and reschedules work.
  • Kubernetes: node disappears; pods are rescheduled by controllers. Watch pending pods if regular capacity is tight.

5. Mix capacity

A common pattern for batch platforms:

Regular capacity:     minimum workers needed for SLA
Preemptible capacity: everything above that, scaled by queue depth

If preemptible capacity isn't available, the job still completes on regular capacity, just more slowly.

6. Measure

Track cost per job (or per build), job completion time, and the number of preemptions. If preemptions make jobs re-run so often that total cost rises, use shorter tasks or more checkpoints.

Warning

Never set preserveBootVolume: false on an instance whose boot volume holds data you need. Keep all state off the preemptible instance's boot volume.

Checklist

  • Interruption-tolerant workloads identified
  • Preemptible VMs / OKE node pool with taints
  • Checkpoints, idempotency and queue-based work
  • Preemption events captured
  • Regular baseline + preemptible burst
  • Cost per job and preemption rate tracked