Back to articles
Technology Insight

How We Ran 30 Internal SaaS Applications on a Single 2GB RAM VPS Using Unikraft MicroVMs

June 3, 2026

The DevOps Dilemma: The Hidden Cost of Microservices

In modern enterprise software development, the shift toward microservices and isolated internal SaaS applications has drastically improved modularity and deployment velocity. However, this architectural freedom introduces a steep financial and operational tax: resource bloat. Traditionally, running an application required wrapping it in a Docker container or a full-fledged Virtual Machine (VM). When scaling this approach to dozens of internal tools—such as identity providers, monitoring dashboards, inventory trackers, and staging environments—the overhead of the underlying operating systems quickly consumes available hardware resources.

Consider a standard Linux-based Docker setup. Even a minimal Alpine Linux container running a lightweight Node.js or Python API carries the memory footprint of the Linux kernel, system libraries, and the container runtime environment. When multiplied by 30 isolated applications, a standard 2GB RAM Virtual Private Server (VPS) quickly succumbs to Out-Of-Memory (OOM) crashes. Engineers are then forced to scale up their cloud infrastructure, paying for underutilized CPU and RAM just to sustain operating system overhead.

To solve this inefficiency, forward-thinking infrastructure teams are turning to a paradigm shift in virtualization: Unikernels and MicroVMs. By utilizing Unikraft, an open-source unikernel compile-time framework, we successfully consolidated 30 distinct, internal SaaS applications onto a single, cost-effective 2GB RAM VPS without compromising performance, isolation, or security.


Understanding the Architecture: Containers vs. Traditional VMs vs. Unikernels

To appreciate how Unikraft achieves this level of density, we must examine the architectural differences between traditional virtualization, containerization, and unikernels.

1. Traditional Virtual Machines (VMs)

Traditional VMs provide excellent isolation because each VM runs a complete guest operating system (OS) on top of a hypervisor. However, this means duplicating the entire OS kernel, drivers, and system services for every single application. This results in heavy memory consumption (often hundreds of megabytes per instance) and slow boot times measured in seconds or minutes.

2. Containers (Docker/Podman)

Containers optimized this by sharing the host OS kernel, allowing multiple applications to run in isolated user spaces. While containers drastically reduced memory overhead compared to VMs, they still suffer from two major drawbacks:

  • Security Vulnerabilities: A shared kernel means that a kernel-level exploit in one container can potentially compromise the entire host system.
  • Memory Floors: The containerized application still requires a full user-space stack, language runtimes, and dependencies, keeping the minimum memory floor higher than necessary.

3. Unikernels via Unikraft

Unikernels represent a radical simplification. A unikernel is a single-purpose, bootable disk image obtained by compiling the application code directly with only the specific operating system primitives it requires to run. There is no multi-user support, no shell, no unnecessary drivers, and no shared kernel.

“Unikernels remove the traditional boundary between the application and the operating system, baking them into a single, hyper-specialized immutable binary.”

Unikraft takes this a step further by providing a highly modular framework. If your Go application does not require a complex file system, Unikraft excludes file system libraries from the final compilation. The result is a highly secure, lightning-fast MicroVM that boots in milliseconds and consumes a mere fraction of the memory a Docker container would demand.


The Setup: 30 Applications, One 2GB VPS

To demonstrate the real-world viability of this technology, we migrated a suite of 30 internal business applications to Unikraft MicroVMs. The application stack consisted of a diverse mix of technologies common in business environments:

  • 10x Node.js / Express APIs (Internal microservices for data processing)
  • 8x Go (Golang) Services (High-performance routing and authentication helpers)
  • 7x Python / FastAPI Daemons (Data synchronization and internal report generation)
  • 5x Static Frontend Applications (Served via specialized minimalist web servers)

The Baseline Resource Challenge

Initially, attempting to run these 30 applications via standard Docker containers on a 2GB RAM VPS led to immediate system instability. Docker's base overhead, combined with the runtime memory footprints of Node.js and Python within standard Linux user spaces, pushed idle memory consumption well past 2.2GB, triggering the Linux OOM killer.

The Unikraft Transformation

By compiling these applications using Unikraft, we fundamentally altered the resource equations:

  1. Eliminating the OS Overhead: The Linux kernel overhead was completely stripped away. Each MicroVM contained only the bare minimum code needed to interact with the hypervisor (such as KVM or Firecracker).
  2. Drastic Memory Reduction: Instead of requiring 50MB to 150MB of idle memory per container, the Unikraft-compiled Go and Node.js applications operated with an idle memory footprint of just 5MB to 15MB per MicroVM.
  3. Aggregated Resource Allocation: With an average footprint of 12MB per instance, all 30 applications combined consumed roughly 360MB of RAM at idle. This left over 1.5GB of the VPS’s 2GB memory pool completely free to handle transactional peak loads and traffic spikes.

Step-by-Step Implementation Strategy

Transitioning from standard applications to Unikraft MicroVMs involves a structured compilation and deployment pipeline. Here is the high-level workflow used during our migration project:

Step 1: Application Profiling

Before compilation, each application’s system dependencies must be mapped. Unikraft relies on a configuration file (similar to a Linux kernel .config file) where developers specify exactly which libraries (e.g., libunwind, lwip for networking, musl for C standard library compatibility) are required.

Step 2: Compiling with KraftKit

Unikraft provides a command-line tool suite called KraftKit, which simplifies the build process. Using a Kraftfile (analogous to a Dockerfile), we define the base application runtime and target architecture.

# Example Kraftfile concept
targets:
  - architecture: x86_64
    platform: kvm
cmd: ["/app/bin/server"]

Running the compilation command instructs Unikraft to fetch the necessary architecture-specific modules, link them with the application code, and output a highly compact .img binary file.

Step 3: MicroVM Orchestration via Firecracker or KVM

Once the images are built, they are managed by a lightweight hypervisor. For our setup, we utilized native KVM (Kernel-based Virtual Machine) managed via KraftKit’s internal runtime tools. Each microVM is assigned a dedicated virtual network interface and a strict memory ceiling (e.g., max 32MB for small Go services, max 64MB for larger Node.js services).


Key Benefits of the Unikraft MicroVM Architecture

Beyond the raw financial savings of avoiding expensive VPS upgrades, adopting Unikraft provided several enterprise-grade operational advantages:

1. Unparalleled Security and Reduced Attack Surface

Internal SaaS applications often contain sensitive company data, making them prime targets for internal lateral movement attacks. In a standard container environment, a compromised application could exploit a kernel vulnerability to break out to the host. With Unikraft, there is no shell (sh/bash), no SSH daemon, and no package manager inside the running image. Even if an attacker executes a remote code execution (RCE) exploit, there are no system utilities available to leverage, and the hypervisor boundary strictly isolates the breach.

2. Sub-Millisecond Boot Times

Traditional VMs take minutes to boot, and Docker containers take seconds. Because Unikraft MicroVM binaries are highly optimized and only a few megabytes in size, they can boot from cold storage to active network listening in under 10 milliseconds. This unlock options for instantaneous "scale-to-zero" setups, where an internal application is completely shut down when idle and spins up instantly upon receiving an HTTP request.

3. Maximum Hardware Efficiency

By eliminating layers of abstraction, the application code runs directly on the virtualized hardware interface. CPU cache misses are reduced, and context-switching overhead between user space and kernel space disappears entirely, allowing the VPS to process more requests per second compared to an identical setup running on Docker.


Conclusion: The Future of Lean Cloud Infrastructure

Running 30 internal SaaS applications on a single 2GB RAM VPS is not just a theoretical optimization exercise; it is a testament to the efficiency of modern unikernel architectures. By discarding decades of legacy multi-user operating system assumptions that are irrelevant to isolated cloud applications, Unikraft enables businesses to extract maximum utility out of minimal hardware investments.

For enterprise DevOps teams, this approach offers a clear blueprint for reducing cloud expenditure, hardening internal security posture, and achieving unmatched application density. As cloud infrastructure costs continue to face scrutiny, adopting specialized microVM technologies like Unikraft is no longer an experimental luxury—it is a strategic competitive advantage.