•
6 min read

Why i26g Runs on VMs, Not Kubernetes

Table of Contents

I have designed and run Kubernetes platforms for organizations that needed them: a cloud-agnostic application platform for a SaaS product running around the clock in more than 30 languages, and a global platform serving both legacy and modern applications. So this is not a post about Kubernetes being bad.

It is about fit. The i26g Platform needs reliable process supervision and predictable recovery, and one person has to operate the whole of it. Measured against that, a virtual machine (VM) is the better primitive: it gives the workload what it needs, with less for its operator to understand, maintain, and recover.

A glass box on a plinth holding three connected blocks above a stack of storage disks, with an orange signal line passing straight through it from one side to the other.

The Shape of the Workload

Kubernetes is at its best when there are many services, many teams, and workloads that come and go: it schedules containers across a pool of nodes, scales them, and replaces them when they fail.

A systematic trading operation for one independent trader looks different. It is a small number of long-running processes — data ingestion, strategy runners, order management, risk checks, and a human interface — that must start in the right order and keep running through a session. There is little to schedule and, in the current design, nothing to scale horizontally, but every process matters.

On a VM, those processes are supervised by systemd: restarted when they fail, logged to the journal, and run on timers where they should. That is the supervision the workload needs, and it comes with the operating system.

Fewer Moving Parts to Diagnose

When something fails during a trading session, the question is how much infrastructure I have to understand to explain it.

Kubernetes adds a container runtime, an overlay network, a storage abstraction, and a scheduler that determines where workloads run. Each is valuable where its job is needed. For this workload, systemd provides the process supervision I need. The cluster’s additional networking, storage, and scheduling mechanisms would each add something to configure and diagnose — another place to look when an order goes out late or a process restarts mid-session. On a VM, the path is the process, the operating system, the network interface, and the disk.

Operating It Alone

A Kubernetes cluster has to be operated: its control plane upgraded, its networking and storage plugins kept compatible, its own state backed up, and its certificates renewed. In an organization, a platform team does that. For an independent trader, it would be a second system to run before the first one trades anything.

A VM’s maintenance is the operating system’s maintenance: patches, a reboot, a rebuilt VM — a smaller maintenance surface for me to manage. Provisioning and configuration are declared rather than done by hand. Inside its boundary, the i26g Control Plane uses OpenTofu to create the VMs, networks, and storage, and Ansible to configure them: packages, hardening, systemd units, and the platform’s own processes. Both read from Git, so the environment can be rebuilt from its declared configuration the same way every time.

State and Recovery

A trading operation is stateful: market data, positions, orders, and the record of what the system decided and why. The platform keeps that state in files, as described in Designing a File-First Storage Architecture for Market Analysis, on the same VM as the processes that use it.

That gives infrastructure recovery one unit to restore. The VM can be snapshotted and restored whole, and its files backed up with ordinary tools such as restic. A restore is a VM coming back up with its processes, configuration, and data together.

The application still needs a consistent backup and a defined restart procedure. For a trading operation, that includes checking restored order and position records against the broker before the system acts on potentially stale state.

In a cluster, recovery has to account for both the application’s persistent data and the Kubernetes configuration that connects it to its workloads. Recovering the cluster itself adds another procedure to maintain and test.

A Portable Deployment and Isolation Boundary

The i26g Control Plane is handed a boundary: a resource pool, a network zone, storage, and scoped credentials. Across the infrastructure I target, VMs come in that shape — Proxmox at home, a VPS provider, or a cloud project — so the same operating model fits all of them. A cluster would have to be built inside the boundary; a managed cluster would instead make the platform depend on that provider’s Kubernetes service and operating constraints.

The VM is also the unit of isolation. The trading operation gets its own kernel, separate from everything else on the host — the boundary I chose for development in Code Isolation: Choosing a Development Setup, and one that suits a system trusted with live capital even more.

What I Give Up

Choosing VMs has costs:

  • No scheduler. If the platform outgrows one VM, deciding what runs where is the i26g Control Plane’s job, not a cluster’s.
  • Continuous reconciliation is mine to build. OpenTofu and Ansible rebuild the environment from Git, but keeping running infrastructure aligned with it, continuously, is work the i26g Control Plane has to do itself. Argo CD and Flux provide that out of the box, for Kubernetes.
  • Less standard packaging. Installing the platform as systemd units through Ansible roles is less standardized than deploying a container to a cluster.

For a single trader running a focused set of strategies, those are acceptable. If i26g ever serves many traders on shared infrastructure, a cluster may become the right primitive. The application processes could remain, while deployment configuration, packaging, and reconciliation would need adapting.

The Choice

Infrastructure earns its place by reducing the total work of running and recovering the trading operation. For i26g, today, a VM does that better than a cluster.


💬

Do you run long-lived, stateful workloads on Kubernetes, or have you kept them on VMs? Leave a comment below, or reach out through another channel if you would rather keep the conversation private. Follow the RSS feed for more.