Virtual Machines
What it is
A virtual machine (VM) is a complete computer that exists as software, running on a provider's hardware. You get an operating system you fully control — you log in, install whatever you want, and run your app exactly as you would on a physical machine. It's the most hands-on of the hosting options.
Strengths
- Total control — full operating system, any software, any configuration.
- Predictable performance; the machine is yours for as long as you rent it.
- No execution-time or runtime limits, unlike serverless or edge.
- Runs anything: databases, legacy software, custom daemons, long jobs.
- Mature, well-understood model with decades of tooling.
Trade-offs
- You manage everything: OS updates, security patches, backups, monitoring.
- You pay for the machine whether it's busy or idle.
- Scaling is manual — you resize or add machines yourself.
- More moving parts means more ways for things to break.
- Slowest to provision compared to functions or containers.
When to use it
Use a VM when you need full control or have requirements that lighter options can't meet: specialized software, persistent state, a self-hosted database, GPU workloads, or migrating an existing app without rewriting it.
Vibe coding fit
VMs give an AI agent the widest canvas, but also the most responsibility, so lean on infrastructure-as-code rather than manual clicking. Have the agent write a provisioning script (a cloud-init file or a shell setup script) so the whole machine is reproducible and reviewable, instead of configuring the server by hand over SSH. Tip: ask the agent to script the setup into a single bootstrap file and to set up automatic security updates — that way you can destroy and recreate the VM at any time without losing your configuration.
#!/usr/bin/env bash
# bootstrap.sh — provision an Ubuntu VM
set -euo pipefail
apt-get update && apt-get upgrade -y
apt-get install -y nginx
systemctl enable --now nginx
# enable unattended security updates
apt-get install -y unattended-upgrades
dpkg-reconfigure -f noninteractive unattended-upgrades
# Run the bootstrap on a fresh server
scp bootstrap.sh user@my-server:/tmp/
ssh user@my-server "sudo bash /tmp/bootstrap.sh"