Skip to main content

Live Disk Capacity

Limited preview

Live disk capacity is available to organizations enabled by Morph, on instances created from a supported image. Existing instances are not converted automatically. Contact Morph for access and use Python SDK / CLI version 0.1.116 or later.

python -m pip install "morphcloud>=0.1.116"

Live disk resize changes a supported native instance's usable ext4 root filesystem capacity without rebooting. Use the same operation to increase or decrease capacity. The instance pauses while the resize is prepared, then resumes its saved process and memory state with the new capacity. Open files remain open. Network peers and clients may time out during the pause, so applications should use their normal connection recovery.

disk_size is the absolute target in MiB, not an amount to add or remove. For example, 32768 means a total capacity of 32 GiB. CPU and memory changes still use configurable reboot.

Eligibility and limits​

  • The instance must be a supported native instance with live capacity enabled. The snapshot-transform profile reports disk_capacity_mode: "static_ext4_v1". Updating the SDK does not make an older instance eligible.
  • The target must be an integer from 256 through 1,048,576 MiB, subject to the instance's supported limits and your organization's quota. Accepted targets are not rounded.
  • A decrease must leave enough room for existing filesystem usage, outstanding allocations, and required headroom. Free space reported before the request is only an estimate: concurrent writers can change the minimum.
  • Conflicting lifecycle operations must finish first. Wait for an active resize before taking a snapshot, branching, pausing, rebooting, or stopping the instance.

For Morph EFS, install client version 0.3.7 or later before mounting. Use morphcloud plugin install efs for a new installation or morphcloud plugin upgrade efs to update it. Existing mounts keep the client version they started with; updating the package alone does not make an older running mount compatible with a resize pause. Plan any necessary remount with the applications using it before resizing.

Recently deleted data may continue to count toward filesystem usage until those filesystem changes commit. Before retrying a rejected decrease, inspect reported free space and minimum_target_mib when supplied.

An unsupported instance returns managed_capacity_unsupported or a more specific eligibility error. Resize never falls back to a reboot. Devbox capacity changes and TypeScript SDK methods are outside this API.

Increase or decrease capacity​

Supply a unique idempotency key for each intended change and retain it until that change is resolved. Reuse the same key and target when retrying that change after a connection failure. The examples below assume a supported instance currently has 16 GiB of capacity.

# Increase the total capacity to 32 GiB and wait for completion.
morphcloud instance resize-disk inst_123 \
--disk-size 32768 --idempotency-key workspace-grow-001 --timeout 1200

# After deleting temporary files, decrease the total to 24 GiB.
morphcloud instance resize-disk inst_123 \
--disk-size 24576 --idempotency-key workspace-reduce-001 --timeout 1200

Both commands wait for the resize operation. The default waiting deadline is five minutes; these examples allow twenty minutes for larger resizes. Use --no-wait --json to return the accepted operation for later inspection. A no-wait response does not mean the resize has completed.

Observe completion and recover a disconnected wait​

Track the resize operation, not the instance's READY status. The instance normally stays ready throughout resize, and its committed disk_size changes only when resize succeeds.

morphcloud instance get-disk-resize inst_123 OPERATION_ID --json
morphcloud instance wait-disk-resize inst_123 OPERATION_ID \
--timeout 1200 --json
from morphcloud.api import MorphCloudClient

client = MorphCloudClient()
operation = client.instances.get_disk_resize("inst_123", "OPERATION_ID")
print(operation.id, operation.status)

# For a pending or running operation, resume waiting on the same ID.
completed = client.instances.wait_disk_resize(
"inst_123", "OPERATION_ID", timeout=1200
)

REST clients inspect GET /api/instance/{instance_id}/disk-resize/{operation_id} using the same authentication and organization context as the original request. Async Python provides aget_disk_resize and await_disk_resize.

Operation statusMeaning and next action
pending / runningAccepted work is still in progress. Inspect or wait on the same operation.
succeededThe requested capacity is verified and committed. A new change can use a new key.
failedInspect the structured error. Correct a rejected target or prerequisite before requesting a new change.
recovery_requiredThe result needs reconciliation. Keep the operation ID, inspect its observations, and contact support if it persists. Do not assume the old or new size is authoritative from the requested target alone.

A timeout is a limit on how long the client waits. It does not cancel, undo, or resubmit the operation. If the original POST response was lost before you received an operation ID, replay the same target with the original idempotency key to discover the original operation. Starting a replacement with a new key is not a recovery procedure.

Python wait methods raise DiskResizeFailed, DiskResizeRecoveryRequired, or DiskResizeTimeout. These exceptions carry operation_id, the last known operation, and idempotency_key when known. A create timeout may have only the key, so persist it before submitting. JSON CLI output retains operation details for automation; inspect the command's exit status as well as its output.

DiskResizeRequestError retains the recovery context and any available HTTP status, error code, and response body when submission or inspection fails. If instance.resize_disk(...) succeeds remotely but cannot refresh the local Instance, DiskResizeRefreshError.operation preserves the successful result. Retrieve the instance again; do not repeat the resize merely to refresh it. Async cancellation raises the standard asyncio.CancelledError; persist your idempotency key before starting an async request so you can safely replay if cancellation happens before its response arrives.

Capacity seen inside the instance​

After success, native filesystem reporting shows the requested capacity:

df -B1 --output=size,used,avail,target /

For a 24 GiB target, the Size column is 25769803776 bytes. Applications using statvfs observe the same total. Existing data remains accessible after a decrease, and new allocations obey the new capacity, including writes made as root. Filesystem metadata, reserved space, and application usage affect how much of the total is available for new files.

Raw block-device tools such as lsblk or blockdev may still show a larger device. Use filesystem reporting and the completed operation to understand the usable capacity; a larger raw device does not provide extra writable filesystem space. Do not manually truncate the device to match df or run filesystem resize tools as part of this workflow.

EFS and other separately mounted storage retain their own capacity. Changing the instance root does not resize an EFS filesystem or its dashboard. EFS client caches, container layers, and logs stored on the root still consume root space; leave headroom for them before decreasing capacity. See FUSE support for mount requirements.

Quota, charging, and snapshots​

An increase reserves its positive capacity difference while the operation is pending. A decrease frees organization capacity only after successful completion. An unresolved decrease therefore does not immediately make room for another instance.

The old committed capacity remains the basis for compute charging until resize completes. At completion, charging uses the new capacity from that timestamp onward. A no-op, a failed request that made no change, or repeating the same operation does not introduce a second charge transition.

For supported instances, compute MCU usage is:

max(1, vCPUs, ceil(memory_MiB / 4096), ceil(disk_size_MiB / 16384))

Decreasing disk capacity may leave the rate unchanged when CPU or memory already determines the maximum, or when both capacities fall in the same disk billing band. A smaller filesystem capacity does not promise immediate physical storage reclamation or change existing snapshot storage charges.

Wait for resize success before saving a snapshot or branching. New snapshots capture the completed capacity; older snapshots keep their original capacity. Restoring or branching a snapshot preserves the capacity it captured. A later resize of the original instance does not alter that snapshot.

Request errors​

ResponseAction
400 invalid target or keySend an integer absolute MiB target and a valid idempotency key.
401 / 403 / 404Check credentials, organization context, and access to this instance and operation.
422 managed_capacity_unsupportedUse an eligible instance. Resize will not reboot or convert the existing instance automatically.
422 target_below_usageInspect minimum_target_mib when supplied; delete unnecessary files or choose a larger target with headroom. Concurrent allocations may also cause an accepted operation to fail with this code.
409 conflictInspect the error for a conflicting operation, lifecycle change, quota, or reused key with a different target. Resolve that cause before retrying.
503 unavailableNew requests cannot currently be accepted. Previously accepted operations remain inspectable and recoverable.

Operation observations can be incomplete during recovery. An unknown value is null, not zero. Retain the instance ID, operation ID, idempotency key, and structured error when asking support to investigate.