Most of the coverage Cozystack 1.4 got in May 2026 led with fractional GPU sharing — a genuinely useful feature, and the kind of checkbox that makes a release note skimmable. But GPU slicing is the least interesting thing in this release. The more useful story is what the release quietly confirms about Cozystack's architecture: it's the only CNCF project betting on the same substrate bex is — Cluster API, owned bare metal, no managed-cloud abstraction underneath — and it makes a very different choice about what "PaaS" means once you get there.
Here's what actually shipped in v1.4.0, published May 19, 2026 by Ænix:
| Feature | What changed |
|---|---|
| Dashboard | Full rewrite — React 19 / TypeScript talking directly to the Kubernetes API, replacing the old openapi-ui + BFF stack |
| GPU sharing | HAMi v2.8.1 integration — fractional nvidia.com/gpu, gpumem, gpucores allocation across pods on one physical GPU |
| KubeVirt | v1.6.3 → v1.8.2, crossing a QEMU version boundary — every VM running before the upgrade needs a cold restart; live migration of pre-upgrade VMs isn't supported |
| Worker storage | Tenant cluster worker VMs move from ephemeral to PVC-backed disks (ephemeralStorage config field renamed to diskSize) — kubelet state now survives a reboot |
| Resource presets | 40 new instance-type presets across five series (t1/c1/s1/u1/m1) × eight sizes, replacing the old flat naming |
| Backups | Declarative backup strategies for CNPG Postgres, MariaDB, ClickHouse, and FoundationDB, with S3-compatible object store targets |
That's a solid, ops-focused release. None of it is the reason to write about Cozystack for a Bex.co audience, though. The reason is that Cozystack is a CNCF Sandbox project (accepted unanimously in February 2025) built by Ænix to turn bare-metal servers into a self-hosted cloud — Kubernetes clusters, databases, VMs, and PaaS, on hardware you own, no wildcard managed-cloud layer underneath. That's the same bet bex is making. It's worth being precise about where the two designs actually agree and where they don't, because "both use Cluster API" undersells how differently they use it.
How Cozystack actually builds a tenant cluster
Cozystack's root cluster runs on Talos Linux — a minimal, API-managed Linux distribution built for nothing but running Kubernetes — bootstrapped directly via a talosctl-based script, not Cluster API. That root cluster is where Cluster API shows up, and it shows up to do something specific: give every tenant a real, separate Kubernetes cluster, not a namespace.
It does this with two Cluster API providers stacked together:
- Kamaji, acting as a Cluster API control-plane provider, runs each tenant's
kube-apiserver,controller-manager, andscheduleras ordinary pods inside the root cluster. A tenant's control plane is a hosted, multi-tenant-safe object — cheap to spin up, no dedicated control-plane machine per tenant. - cluster-api-provider-kubevirt supplies the worker side: KubeVirt-backed virtual machines that boot, join the tenant's Kamaji-hosted control plane as nodes, and (as of 1.4) keep PVC-backed disks across restarts.
Put together, a Cozystack tenant gets what the docs call Kubernetes-in-Kubernetes: their own kube-apiserver, their own etcd, their own RBAC, running as pods and VMs inside someone else's (the platform operator's) root cluster. From the tenant's side, it's indistinguishable from a dedicated cluster. From the operator's side, it's Cluster API doing what it always does — reconciling declared cluster and machine objects into running infrastructure — just aimed at nested clusters instead of the root layer.
Where bex's Cluster API bet stops short of that — on purpose
bex uses Cluster API too, but scopes it to exactly one layer: provisioning the machines of a single, flat app cluster. There's an infra cluster whose only job is running Cluster API controllers (CAPD locally, CAPH on Hetzner), and an app cluster where the bex operator and every tenant's App pods run side by side, reconciled directly from App custom resources into Deployment/Service/Ingress objects. Swap the Cluster API infrastructure provider from CAPD to CAPH and the picture doesn't change — that's the whole "local mock → Hetzner prod" portability bet.
There's no Kamaji, no per-tenant control plane, no KubeVirt VM layer. A bex tenant's app is a pod on a shared apiserver, isolated by namespace/RBAC/network policy, not by running its own Kubernetes control plane. And the comparison to Cozystack has a precise inversion worth naming: bex's Cluster API usage starts earlier in the stack — CAPH provisions bex's own bare-metal nodes — while Cozystack's root cluster is bootstrapped by hand via Talos, and Cluster API only enters once you're building tenant clusters on top of that already-running root. Two different answers to "where does Cluster API start doing work," both legitimate, both worth knowing before you pick one.
What "also runs VMs" actually buys you
This is the part of the Cozystack pitch that's a genuine differentiator, not a checkbox. KubeVirt runs guests under real hardware virtualization (KVM/QEMU), not a shared-kernel container boundary. That difference cashes out concretely:
- A stronger tenant-isolation boundary. A hostile or buggy workload in a Cozystack tenant VM is contained by the hypervisor, not just by
seccomp/cgroups/namespaces. For a platform selling isolated compute to other companies — banks, medtech, SaaS resellers, which is exactly who Cozystack names as its target users — that's the difference between "we trust our container runtime" and "we trust hardware-enforced memory isolation." - Workloads a container simply can't run. Legacy lift-and-shift apps that need a specific kernel, Windows guests, or anything that assumes it owns the machine below it — none of that fits in a container, all of it fits in a VM.
- GPU sharing at the VM boundary, not just the pod boundary. HAMi's fractional GPU allocation in 1.4 works because Cozystack already has KubeVirt VMs as a scheduling unit; a container-only platform wanting the same GPU-slicing story has to either bolt on the NVIDIA GPU Operator's own device-plugin path or bring in KubeVirt itself, at which point it's rebuilding a piece of what Cozystack ships out of the box.
Neither bex, nor Coolify, nor Dokploy — the container-first self-hosted PaaS category — has an answer to any of these three today. That's not a knock; it's a scope decision. But it means "Cozystack also runs VMs" isn't marketing color, it's a specific set of workloads and a specific isolation guarantee that a flat, container-only Cluster API design has to explicitly decide it doesn't need.
What the nested-cluster model costs
The honest other half of this trade shows up in 1.4's own release notes. The KubeVirt jump from v1.6.3 to v1.8.2 crosses a QEMU version boundary, which means every VM running before the upgrade needs a cold restart — live migration of pre-upgrade VMs isn't supported across that gap. That's not a hypothetical operational cost; it's a breaking change Cozystack's own operators had to plan around in this exact release.
More structurally: a Kamaji-hosted control plane is a real kube-apiserver + etcd instance running as pods, per tenant, whether that tenant is running one workload or a hundred. That's a meaningfully heavier resource floor than bex's model, where every tenant's app is just another pod on one shared apiserver — no dedicated control-plane pods to keep warm, patch, and upgrade per tenant. Running Kamaji + KubeVirt + Talos + HAMi as a stack is also a wider operational surface than "Cluster API provisions machines, an operator reconciles CRs into Deployments" — more components, more upgrade sequencing (Talos, then Cilium, then cert-manager, then KubeVirt, in this release's case, each with its own compatibility notes), more that can break in a way that's specific to the nested-cluster design rather than to Kubernetes itself.
Choosing between them: what actually matters besides "which one is CNCF-blessed"
CNCF Sandbox status is a governance signal, not an architecture recommendation — plenty of teams will pick the wrong tool for their workload by defaulting to "the one with the foundation logo." The actual decision comes down to two questions:
- Do you need to sell isolated Kubernetes clusters or VM-class workloads to other tenants? If you're a hosting provider, a bank standing up managed Kubernetes for internal teams, or anyone whose product is "here's your own cluster/VM," Cozystack's nested Kamaji+KubeVirt model is buying you a real capability — hard multi-tenancy and VM support — that you'd otherwise have to build yourself on top of bare Cluster API.
- Are you deploying your own containerized product and don't need per-tenant Kubernetes clusters at all? If the thing you're operating is "git push, get a running HTTPS service" — the Render/Heroku shape — a flat Cluster-API-first design gets you the same owned-hardware economics (no managed-cloud markup, no vendor lock-in) without paying the resource and upgrade-surface cost of a
kube-apiserverper tenant you'll never use as a full cluster.
Bex.co is built for the second answer on purpose: one operator, one flat app cluster, Cluster API doing exactly one job — turning declared machines into Hetzner servers — so a single team can self-host a git-push PaaS without also becoming the operator of a fleet of nested Kubernetes control planes. If your workload is containers, not tenant clusters or VMs, that's the whole platform you actually need.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. Star the repo on GitHub or deploy your first app today.
Sources:
- Cozystack 1.4: New Dashboard UI, Persistent Tenant Workers, Backup Strategies, and Fractional GPU Sharing — Ænix blog
- Cozystack v1.4.0 release notes — GitHub
- GPU Sharing with HAMi — Cozystack docs
- Open Source PaaS Cozystack Becomes a CNCF Sandbox Project — CNCF blog
- Kamaji Cluster API Control Plane Provider — kamaji.clastix.io
- Key Concepts — Cozystack docs.



