You need more (or fewer) OCPUs or memory on an OCI VM, or you want to move from an older fixed shape to a flex shape. OCI does this in place with change shape. Attached volumes, VNICs, and private and public IPs are kept, but a running instance is rebooted as part of the change. Plan it as a short outage.
Before you start
| Check | Why it matters |
|---|---|
| Change window agreed | A running instance reboots during the change |
| Service limit and capacity available for the target shape | Without enough limit, the instance keeps its original shape |
| Image compatible with the target shape | The guest may not boot on an incompatible shape |
| Target shape is editable | Some shapes, such as VM.Standard.E2.1.Micro, DenseIO flex shapes and the VM.GPU2 series, can't be changed |
| Boot volume backup taken | Gives you a clean rollback if the guest doesn't come back |
| Load balancer or cluster can drain this node | Avoids failed requests during the reboot |
Note
Oracle's documented limitations change. Today they include: Windows Server 2019 on
VM.Standard2can only move within that series, Ampere (Arm) shapes don't support Windows, some Marketplace images can't be resized for licensing reasons, and you may have to detach extra VNICs (and, in some cases, block volumes) first. Read the "Changing the Shape of an Instance" page for your shape before a production change.
Step 1: Record the current state
INST=ocid1.instance.oc1..xxxx
oci compute instance get --instance-id $INST \
--query 'data.{name:"display-name",shape:shape,state:"lifecycle-state",ad:"availability-domain",fd:"fault-domain",config:"shape-config"}'
Save this output in the change ticket. The shape-config block shows ocpus, memory-in-gbs and, for burstable instances, baseline-ocpu-utilization.
Step 2: Confirm the target shape fits
List the shapes the instance's image supports in this compartment, with the flex OCPU and memory ranges:
C=ocid1.compartment.oc1..xxxx
IMAGE=$(oci compute instance get --instance-id $INST --query 'data."image-id"' --raw-output)
oci compute shape list --compartment-id $C --image-id $IMAGE \
--query 'data[?contains(shape, `Flex`)].{shape:shape,ocpus:"ocpu-options",memory:"memory-options"}'
memory-options shows the minimum and maximum memory per OCPU. A request outside that ratio is rejected.
Check you have limit headroom for the new core count. Limit names vary by shape family; list them first:
oci limits value list --compartment-id <tenancy-ocid> --service-name compute --all \
--query 'data[?contains(name, `e5`)].{name:name,ad:"availability-domain",value:value}' --output table
oci limits resource-availability get --compartment-id $C --service-name compute \
--limit-name standard-e5-core-count --availability-domain "Uocm:EU-FRANKFURT-1-AD-1"
If the limit or capacity isn't there, see OCI launch failures: Out of host capacity, LimitExceeded and QuotaExceeded.
Step 3: Back up the boot volume
AD=$(oci compute instance get --instance-id $INST --query 'data."availability-domain"' --raw-output)
BV=$(oci compute boot-volume-attachment list --compartment-id $C --availability-domain "$AD" \
--instance-id $INST --query 'data[0]."boot-volume-id"' --raw-output)
oci bv boot-volume-backup create --boot-volume-id $BV \
--display-name "pre-resize-$(date +%Y%m%d)" --type INCREMENTAL \
--wait-for-state AVAILABLE
More detail on backups and restores is in Backing up and restoring OCI boot and block volumes.
Step 4: Drain and stop the application
Remove the instance from its load balancer backend set (or set it to drain), then stop the application cleanly. Oracle recommends shutting down applications inside the OS before changing shape, so a long OS shutdown doesn't corrupt data.
# Example: mark the backend as drained on an OCI load balancer
oci lb backend update --load-balancer-id $LB --backend-set-name app-bs \
--backend-name 10.0.1.15:8080 --weight 1 --backup false --drain true --offline false
# Inside the guest (Linux example)
sudo systemctl stop myapp
Warning
Database servers must be shut down cleanly inside the guest before the change. The platform reboot is graceful, but don't rely on it to flush a busy database.
Step 5: Change the shape
Flex shape, new OCPU and memory values:
oci compute instance update --instance-id $INST \
--shape VM.Standard.E5.Flex \
--shape-config '{"ocpus": 4, "memoryInGBs": 64}' \
--wait-for-state RUNNING --max-wait-seconds 1800
Only OCPU and memory on the same flex shape: omit --shape and pass only --shape-config.
Burstable instance (lower baseline, lower cost): add "baselineOcpuUtilization": "BASELINE_1_2" (or BASELINE_1_8, BASELINE_1_1) to the shape config. Moving an SR-IOV instance to burstable also needs the networking type changed to paravirtualized.
The CLI may prompt to confirm because the update changes the instance. Add --force in scripts once you're sure of the values.
Step 6: Verify
oci compute instance get --instance-id $INST \
--query 'data.{shape:shape,state:"lifecycle-state",config:"shape-config"}'
Inside the guest:
nproc
free -g
ip -br addr # interface names can change after a shape change
systemctl --failed
On Windows:
Get-CimInstance Win32_Processor | Select-Object NumberOfLogicalProcessors
[math]::Round((Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory/1GB)
Get-NetAdapter | Select-Object Name, Status, MacAddress
nproc shows vCPUs, not OCPUs. On x86 shapes one OCPU is normally two vCPUs; on Ampere shapes it is one. Check the shape documentation if the number looks wrong.
Then start the application, check its health endpoint, and put the backend back into service:
oci lb backend update --load-balancer-id $LB --backend-set-name app-bs \
--backend-name 10.0.1.15:8080 --weight 1 --backup false --drain false --offline false
oci lb backend-health get --load-balancer-id $LB --backend-set-name app-bs --backend-name 10.0.1.15:8080
Troubleshooting and rollback
| Symptom | Likely cause | Action |
|---|---|---|
Update fails with LimitExceeded | No core or memory limit for the new shape | Raise the limit or choose another shape |
Update fails with Out of host capacity | No capacity in that AD/fault domain | Retry later, try another flex shape |
| Instance shows the old shape after the update | Not enough service limit | Check limits and rerun |
| Request rejected for memory value | Outside the shape's memory-per-OCPU range | Use a value inside memory-options |
| Guest doesn't boot | Image or drivers not compatible with the new shape | Change back to the original shape |
| No network after boot | Interface name changed; secondary VNIC config stale | Fix it via the serial console, reconfigure secondary VNICs |
Rollback is the same command with the values you saved in step 1:
oci compute instance update --instance-id $INST \
--shape VM.Standard.E4.Flex --shape-config '{"ocpus": 2, "memoryInGBs": 32}' \
--wait-for-state RUNNING
Caution
If the guest still won't boot on the original shape, restore the boot volume from the step 3 backup and attach it as the instance's boot volume. Don't delete that backup until the instance has been stable for a few days.
Prevent it next time
- Use flex shapes for new instances so later resizes are an OCPU/memory change, not a family move.
- Keep 20–30% spare in your compute limits for the shape families you use, and review them with the cost and governance foundation quotas.
- Run production behind a load balancer with at least two instances in different fault domains, so a resize is a rolling change with no user impact.
- Alarm on sustained CPU and memory use so you resize in a window, not during an incident.
- Record the shape and shape config in Terraform and change it there, so the resize is reviewed and the state doesn't drift.