Welcome to Morph Cloud
Morph Cloud's Infinibranch technology lets you snapshot, branch, and restore entire computational environments in under 250ms. With this technology, you can now parallelize and time travel between VM states, unlocking entirely new patterns for developing, testing, and debugging. The age of linear computing is behind us.
You can create a free account and get started with Morph Cloud at cloud.morph.so.
How are we different?
Feature | Traditional VM Infrastructure | Infinibranch |
---|---|---|
Startup Times | 2-3 minutes for typical VMs | <250ms |
Copying | Full clone required, consuming equal resources | Near-zero overhead branching |
Branching | Not natively supported | Native support for unlimited parallel branches |
State Management | Manual snapshots and restores | Instant snapshots and restores at any point |
Remote Desktop | No built-in support | Built-in browser-based access |
Quick Start (5 minutes)
This guide will walk you through creating your first Morph environment and experiencing the magic of perfect state preservation.
Prerequisites
First, set up your environment:
# Python developers
pip install morphcloud # For Python
# TypeScript developers
npm install morphcloud # For TypeScript
# Set your API key (get it from cloud.morph.so)
export MORPH_API_KEY='your-api-key-here'
Step 1: Create Your First Snapshot
Start by creating a snapshot from our minimal Linux image:
- Python
- CLI (bash)
- TypeScript
from morphcloud.api import MorphCloudClient
client = MorphCloudClient()
snapshot = client.snapshots.create(
image_id="morphvm-minimal",
vcpus=1,
memory=128,
disk_size=700
)
print(f"Created snapshot: {snapshot.id}")
# Using the morphcloud CLI
SNAPSHOT=$(morphcloud snapshot create --image-id=morphvm-minimal --vcpus=1 --memory=128 --disk-size=700)
echo "Created snapshot: $SNAPSHOT"
import { MorphCloudClient } from 'morphcloud';
const client = new MorphCloudClient();
const snapshot = await client.snapshots.create({
imageId: "morphvm-minimal",
vcpus: 1,
memory: 128,
diskSize: 700
});
console.log(`Created snapshot: ${snapshot.id}`);
Step 2: Start an Instance
Next, start an instance from your snapshot:
- Python
- CLI (bash)
- TypeScript
instance = client.instances.start(snapshot.id)
print(f"Started instance: {instance.id}")
INSTANCE=$(morphcloud instance start $SNAPSHOT)
echo "Started instance: $INSTANCE"
const instance = await client.instances.start({
snapshotId: snapshot.id
});
console.log(`Started instance: ${instance.id}`);
Step 3: Create a Background Process
Let's create a script that runs in the background and increments a counter every 5 seconds:
- Python
- CLI (bash)
- TypeScript
# Create counter script
counter_script = """#!/bin/bash
count=1
echo $count > /root/counter.txt
while [ $count -le 100 ]; do
sleep 5
count=$((count + 1))
echo $count > /root/counter.txt
done
"""
instance.exec(f"cat > /root/counter_script.sh << 'EOF'\n{counter_script}\nEOF")
instance.exec("chmod +x /root/counter_script.sh")
instance.exec("nohup /root/counter_script.sh > /dev/null 2>&1 &")
# Check initial counter value
import time
time.sleep(2)
initial_counter = instance.exec("cat /root/counter.txt").stdout
print(f"Initial counter: {initial_counter}")
# Wait for counter to increment
print("Waiting for counter to increment...")
time.sleep(10)
incremented_counter = instance.exec("cat /root/counter.txt").stdout
print(f"Counter after waiting: {incremented_counter}")
# Create counter script
morphcloud instance exec $INSTANCE "cat > /root/counter_script.sh << 'EOF'
#!/bin/bash
count=1
echo \$count > /root/counter.txt
while [ \$count -le 100 ]; do
sleep 5
count=\$((count + 1))
echo \$count > /root/counter.txt
done
EOF"
morphcloud instance exec $INSTANCE "chmod +x /root/counter_script.sh"
morphcloud instance exec $INSTANCE "nohup /root/counter_script.sh > /dev/null 2>&1 &"
# Check initial counter value
sleep 2
INITIAL_COUNTER=$(morphcloud instance exec $INSTANCE "cat /root/counter.txt")
echo "Initial counter: $INITIAL_COUNTER"
# Wait for counter to increment
echo "Waiting for counter to increment..."
sleep 10
INCREMENTED_COUNTER=$(morphcloud instance exec $INSTANCE "cat /root/counter.txt")
echo "Counter after waiting: $INCREMENTED_COUNTER"
// Create counter script
const counterScript = `#!/bin/bash
count=1
echo $count > /root/counter.txt
while [ $count -le 100 ]; do
sleep 5
count=$((count + 1))
echo $count > /root/counter.txt
done
`;
await instance.exec(`cat > /root/counter_script.sh << 'EOF'\n${counterScript}\nEOF`);
await instance.exec("chmod +x /root/counter_script.sh");
await instance.exec("nohup /root/counter_script.sh > /dev/null 2>&1 &");
// Check initial counter value
await new Promise(resolve => setTimeout(resolve, 2000));
const initialCounter = (await instance.exec("cat /root/counter.txt")).stdout;
console.log(`Initial counter: ${initialCounter}`);
// Wait for counter to increment
console.log("Waiting for counter to increment...");
await new Promise(resolve => setTimeout(resolve, 10000));
const incrementedCounter = (await instance.exec("cat /root/counter.txt")).stdout;
console.log(`Counter after waiting: ${incrementedCounter}`);
Step 4: Create a Snapshot of the Running Instance
Now for the magic part - take a snapshot of the instance with the counter process running:
- Python
- CLI (bash)
- TypeScript
# Create snapshot of running instance
print("Creating snapshot of running instance...")
new_snapshot = instance.snapshot()
print(f"Created snapshot: {new_snapshot.id}")
# Create snapshot of running instance
echo "Creating snapshot of running instance..."
NEW_SNAPSHOT=$(morphcloud instance snapshot $INSTANCE)
echo "Created snapshot: $NEW_SNAPSHOT"
// Create snapshot of running instance
console.log("Creating snapshot of running instance...");
const newSnapshot = await instance.snapshot();
console.log(`Created snapshot: ${newSnapshot.id}`);
Step 5: Start a New Instance from the Snapshot
Start a new instance from the snapshot with the running process:
- Python
- CLI (bash)
- TypeScript
# Start new instance from snapshot
new_instance = client.instances.start(new_snapshot.id)
print(f"Started new instance: {new_instance.id}")
# Start new instance from snapshot
NEW_INSTANCE=$(morphcloud instance start $NEW_SNAPSHOT)
echo "Started new instance: $NEW_INSTANCE"
// Start new instance from snapshot
const newInstance = await client.instances.start({
snapshotId: newSnapshot.id
});
console.log(`Started new instance: ${newInstance.id}`);
Step 6: Verify State Preservation
Finally, check if the counter continues from where it left off in the new instance:
- Python
- CLI (bash)
- TypeScript
# Check counter in new instance
new_counter = new_instance.exec("cat /root/counter.txt").stdout
print(f"Counter in new instance: {new_counter}")
# Wait to verify counter continues incrementing
print("Waiting to verify counter continues in new instance...")
time.sleep(10)
final_counter = new_instance.exec("cat /root/counter.txt").stdout
print(f"Counter after waiting in new instance: {final_counter}")
print("\n✨ Success! The background process continued exactly where it left off.")
print(f"Original instance counter: {incremented_counter} → New instance counter: {final_counter}")
# Check counter in new instance
NEW_COUNTER=$(morphcloud instance exec $NEW_INSTANCE "cat /root/counter.txt")
echo "Counter in new instance: $NEW_COUNTER"
# Wait to verify counter continues incrementing
echo "Waiting to verify counter continues in new instance..."
sleep 10
FINAL_COUNTER=$(morphcloud instance exec $NEW_INSTANCE "cat /root/counter.txt")
echo "Counter after waiting in new instance: $FINAL_COUNTER"
echo -e "\n✨ Success! The background process continued exactly where it left off."
echo "Original instance counter: $INCREMENTED_COUNTER → New instance counter: $FINAL_COUNTER"
// Check counter in new instance
const newCounter = (await newInstance.exec("cat /root/counter.txt")).stdout;
console.log(`Counter in new instance: ${newCounter}`);
// Wait to verify counter continues incrementing
console.log("Waiting to verify counter continues in new instance...");
await new Promise(resolve => setTimeout(resolve, 10000));
const finalCounter = (await newInstance.exec("cat /root/counter.txt")).stdout;
console.log(`Counter after waiting in new instance: ${finalCounter}`);
console.log("\n✨ Success! The background process continued exactly where it left off.");
console.log(`Original instance counter: ${incrementedCounter} → New instance counter: ${finalCounter}`);
Understanding What Just Happened
You've just experienced the core magic of Morph Cloud:
- Perfect Process Preservation: The counter process continued running exactly where it left off, with no restarting or loss of state
- Sub-Second Boot Times: The new instance started in milliseconds, not minutes
- Complete Environment Capture: The entire system state, including running processes, was preserved
This is what makes Infinibranch technology revolutionary - you can take a snapshot of a running computation at any point, and instantly create multiple copies that all continue from exactly the same point.
Complete Scripts
Here are the complete scripts for each language:
- Python
- CLI (bash)
- TypeScript
# tutorial.py
from morphcloud.api import MorphCloudClient
import time
# Demonstrate perfect state preservation with Morph Cloud
client = MorphCloudClient()
print("Creating snapshot and starting instance...")
snapshot = client.snapshots.create(image_id="morphvm-minimal", vcpus=1, memory=128, disk_size=700)
instance = client.instances.start(snapshot.id)
print(f"Started instance: {instance.id}")
# Create and start counter script
counter_script = """#!/bin/bash
count=1
echo $count > /root/counter.txt
while [ $count -le 100 ]; do
sleep 5
count=$((count + 1))
echo $count > /root/counter.txt
done
"""
instance.exec(f"cat > /root/counter_script.sh << 'EOF'\n{counter_script}\nEOF")
instance.exec("chmod +x /root/counter_script.sh")
instance.exec("nohup /root/counter_script.sh > /dev/null 2>&1 &")
# Check initial counter value and wait for increment
time.sleep(2)
initial_counter = instance.exec("cat /root/counter.txt").stdout
print(f"Initial counter: {initial_counter}")
print("Waiting for counter to increment...")
time.sleep(10)
incremented_counter = instance.exec("cat /root/counter.txt").stdout
print(f"Counter after waiting: {incremented_counter}")
# Create snapshot and start new instance
print("Creating snapshot of running instance...")
new_snapshot = instance.snapshot()
new_instance = client.instances.start(new_snapshot.id)
print(f"Started new instance: {new_instance.id}")
# Check counter in new instance
new_counter = new_instance.exec("cat /root/counter.txt").stdout
print(f"Counter in new instance: {new_counter}")
# Wait to verify counter continues incrementing
print("Waiting to verify counter continues in new instance...")
time.sleep(10)
final_counter = new_instance.exec("cat /root/counter.txt").stdout
print(f"Counter after waiting in new instance: {final_counter}")
print("\n✨ Success! The background process continued exactly where it left off.")
print(f"Original instance counter: {incremented_counter} → New instance counter: {final_counter}")
#!/bin/bash
# Note: The morphcloud CLI is provided through the Python package.
# Run with: python -m morphcloud.cli
# tutorial_fixed.sh - Demonstrate perfect state preservation with Morph Cloud
# Define the CLI command
MORPH_CMD="python -m morphcloud.cli"
# Check for required dependencies
if [ -z "$MORPH_API_KEY" ]; then
echo "Error: MORPH_API_KEY environment variable must be set"
exit 1
fi
# Create snapshot and start instance
echo "Creating snapshot and starting instance..."
SNAPSHOT_OUTPUT=$($MORPH_CMD snapshot create --image-id=morphvm-minimal --vcpus=1 --memory=128 --disk-size=700 2>&1)
SNAPSHOT=$(echo "$SNAPSHOT_OUTPUT" | grep -o 'snapshot_[a-zA-Z0-9]*' | tail -1)
INSTANCE_OUTPUT=$($MORPH_CMD instance start $SNAPSHOT 2>&1)
INSTANCE=$(echo "$INSTANCE_OUTPUT" | grep -o 'morphvm_[a-zA-Z0-9]*' | tail -1)
echo "Started instance: $INSTANCE"
# Create and start counter script
echo "Creating counter script..."
$MORPH_CMD instance exec $INSTANCE "bash -c 'cat > /root/counter_script.sh << \"EOF\"
#!/bin/bash
count=1
echo \$count > /root/counter.txt
while [ \$count -le 100 ]; do
sleep 5
count=\$((count + 1))
echo \$count > /root/counter.txt
done
EOF'" > /dev/null 2>&1
$MORPH_CMD instance exec $INSTANCE "chmod +x /root/counter_script.sh" > /dev/null 2>&1
$MORPH_CMD instance exec $INSTANCE "nohup /root/counter_script.sh > /dev/null 2>&1 &" > /dev/null 2>&1
# Check initial counter value and wait for increment
sleep 2
INITIAL_COUNTER=$($MORPH_CMD instance exec $INSTANCE "cat /root/counter.txt" 2>/dev/null | grep -v "Executing" | grep -v "Command execution")
echo "Initial counter: $INITIAL_COUNTER"
echo "Waiting for counter to increment..."
sleep 10
INCREMENTED_COUNTER=$($MORPH_CMD instance exec $INSTANCE "cat /root/counter.txt" 2>/dev/null | grep -v "Executing" | grep -v "Command execution")
echo "Counter after waiting: $INCREMENTED_COUNTER"
# Create snapshot and start new instance
echo "Creating snapshot of running instance..."
NEW_SNAPSHOT_OUTPUT=$($MORPH_CMD instance snapshot $INSTANCE 2>&1)
NEW_SNAPSHOT=$(echo "$NEW_SNAPSHOT_OUTPUT" | grep -o 'snapshot_[a-zA-Z0-9]*' | tail -1)
NEW_INSTANCE_OUTPUT=$($MORPH_CMD instance start $NEW_SNAPSHOT 2>&1)
NEW_INSTANCE=$(echo "$NEW_INSTANCE_OUTPUT" | grep -o 'morphvm_[a-zA-Z0-9]*' | tail -1)
echo "Started new instance: $NEW_INSTANCE"
# Check counter in new instance
NEW_COUNTER=$($MORPH_CMD instance exec $NEW_INSTANCE "cat /root/counter.txt" 2>/dev/null | grep -v "Executing" | grep -v "Command execution")
echo "Counter in new instance: $NEW_COUNTER"
# Wait to verify counter continues incrementing
echo "Waiting to verify counter continues in new instance..."
sleep 10
FINAL_COUNTER=$($MORPH_CMD instance exec $NEW_INSTANCE "cat /root/counter.txt" 2>/dev/null | grep -v "Executing" | grep -v "Command execution")
echo "Counter after waiting in new instance: $FINAL_COUNTER"
echo "✨ Success! The background process continued exactly where it left off."
echo "Original instance counter: $INCREMENTED_COUNTER → New instance counter: $FINAL_COUNTER"
echo "Instances running: $INSTANCE and $NEW_INSTANCE"
// tutorial.ts
import { MorphCloudClient } from 'morphcloud';
async function main() {
const client = new MorphCloudClient();
console.log("Creating snapshot and starting instance...");
const snapshot = await client.snapshots.create({
imageId: "morphvm-minimal", vcpus: 1, memory: 128, diskSize: 700
});
const instance = await client.instances.start({ snapshotId: snapshot.id });
console.log(`Started instance: ${instance.id}`);
// Create and start counter script
const counterScript = `#!/bin/bash
count=1
echo $count > /root/counter.txt
while [ $count -le 100 ]; do
sleep 5
count=$((count + 1))
echo $count > /root/counter.txt
done
`;
await instance.exec(`cat > /root/counter_script.sh << 'EOF'\n${counterScript}\nEOF`);
await instance.exec("chmod +x /root/counter_script.sh");
await instance.exec("nohup /root/counter_script.sh > /dev/null 2>&1 &");
// Check initial counter value and wait for increment
await new Promise(resolve => setTimeout(resolve, 2000));
const initialCounter = (await instance.exec("cat /root/counter.txt")).stdout;
console.log(`Initial counter: ${initialCounter}`);
console.log("Waiting for counter to increment...");
await new Promise(resolve => setTimeout(resolve, 10000));
const incrementedCounter = (await instance.exec("cat /root/counter.txt")).stdout;
console.log(`Counter after waiting: ${incrementedCounter}`);
// Create snapshot and start new instance
console.log("Creating snapshot of running instance...");
const newSnapshot = await instance.snapshot();
const newInstance = await client.instances.start({ snapshotId: newSnapshot.id });
console.log(`Started new instance: ${newInstance.id}`);
// Check counter in new instance
const newCounter = (await newInstance.exec("cat /root/counter.txt")).stdout;
console.log(`Counter in new instance: ${newCounter}`);
// Wait to verify counter continues incrementing
console.log("Waiting to verify counter continues in new instance...");
await new Promise(resolve => setTimeout(resolve, 10000));
const finalCounter = (await newInstance.exec("cat /root/counter.txt")).stdout;
console.log(`Counter after waiting in new instance: ${finalCounter}`);
console.log("\n✨ Success! The background process continued exactly where it left off.");
console.log(`Original instance counter: ${incrementedCounter} → New instance counter: ${finalCounter}`);
}
main().catch(error => console.error('Error:', error));
Next Steps
See what Morph Cloud can do:
- Never Lose a CI Bug Again - Transform CI debugging with instant state capture
- 50x Faster AI Agent Evaluations - Accelerate AI agent development
- The Next Evolution in Computing - Our vision for cloud infrastructure
Real-World Applications
- CI/CD Debugging: Access the exact state of any failure instantly
- Agent Development: Enable agents to explore thousands of parallel paths with minimal overhead
- Development Environments: Create staging environments that mirror production perfectly
- Testing at Scale: Generate and validate thousands of test cases efficiently
Start Building
Check out our API documentation
Explore our SDKs (Python • TypeScript) and repositories
Read our blog
Follow us on Twitter/X to stay up to date with our latest releases