# Containers or virtual machines: what to run where

*Cloud & Edge · 6 min read · Updated 2026-10-07 · https://www.jbrichardson.com/resources/containers-vs-virtual-machines*

**Short answer:** Use virtual machines for legacy software and strict isolation, and containers for modern, repeatable services. Choose a managed container service such as ECS on Fargate before Kubernetes. Adopt Kubernetes when many teams run many services, need portability or heavy autoscaling, and can afford its operating cost.

Virtual machines and containers solve different problems. A VM virtualizes a whole machine; a container packages an application and its libraries and shares the host's operating system kernel. Neither is better in general, and plenty of healthy environments run both.

|  | Virtual machine | Container |
| --- | --- | --- |
| Isolation | Strong, separate operating system | Process-level, shares the host kernel |
| Start-up time | Minutes | Seconds or less |
| Density | Lower: each VM carries a full OS | Higher: many per host |
| Best for | Legacy software, Windows servers, strict isolation | Modern services, microservices, repeatable deployments |
| Operating cost | Patching each OS | Image builds, registry, orchestration |

## When Kubernetes is overkill

Kubernetes is powerful and also a lot to run. If you have a handful of services and one team, a managed container service such as Amazon ECS on Fargate or AWS App Runner gives you containers without cluster administration. Many small teams spend more time maintaining a cluster than shipping product.

## When Kubernetes earns its keep

- Many services owned by several teams, each deploying on its own schedule.
- A need for portability across clouds or on-site and cloud together.
- Heavy autoscaling or batch workloads that benefit from bin-packing.
- An ecosystem need: service mesh, operators or tooling that assumes Kubernetes.

## Container habits that pay off

- Containerize first with Docker, then choose where to run it. The image is the portable part.
- Use small base images, run as a non-root user and scan images in the pipeline.
- One process per container, with configuration from environment variables or a secrets service.
- Pin image versions (ideally by digest) so a rebuild never changes what you deploy.
- Keep stateful systems, such as databases, on a managed service unless you have a strong reason not to.

---
Published by JBRichardson LLC, 1603 North Olden Ave, Ewing, NJ 08638. Phone (609)-564-3016. https://www.jbrichardson.com/contact
