gVisor vs Edera: syscall interception vs virtualization

5 min read · Intermediate


Container isolation boils down to a core question: how do you prevent a workload from accessing the host kernel directly?

Two architectures have emerged to solve this:

  1. Syscall interception: intercept every syscall and handle it in user space
  2. Virtualization: give each workload its own kernel running under a hypervisor

gVisor implements the first approach. Edera implements the second through MicroVM isolation—lightweight VMs that give each pod its own kernel. Understanding both helps clarify the tradeoffs in container security.

How syscall interception works

When a Linux process needs something from the kernel (reading a file, opening a network socket, allocating memory) it makes a syscall. In a normal container, that syscall goes directly to the shared host kernel.

gVisor inserts a layer called Sentry between the application and the host kernel:

┌─────────────────────────────────────┐
│           Application               │
├──────────────────┬──────────────────┤
│  Sentry          │  Gofer           │
│  (user-space     │  (file system    │
│   kernel)        │   proxy)         │
│                  │                  │
│  Intercepts all  │  Handles file    │
│  syscalls        │  I/O to host     │
├──────────────────┴──────────────────┤
│          Host Kernel                │
└─────────────────────────────────────┘

Sentry and Gofer run as separate, unprivileged peer processes. The application talks to the Sentry; the Sentry talks to the Gofer when file system access is needed. Neither has direct access to the host kernel beyond a tightly filtered set of syscalls.

The Sentry

Sentry is a user-space re-implementation of the Linux kernel’s syscall interface, written in Go. When your application calls read(), Sentry intercepts it, validates it, and either:

  • Handles it entirely in user space
  • Forwards a filtered version to the host kernel
  • Returns an error if unsupported

This means applications never touch the host kernel directly. The attack surface is reduced to Sentry itself.

The Gofer

File system operations go through a separate process called the Gofer. This isolates file access from the Sentry, adding another layer of separation. The Gofer historically used 9P and then LISAFS to proxy file operations. Current versions default to directfs, where the Gofer donates file descriptors to the Sentry, which then performs file-descriptor-relative syscalls directly—reducing the round-trip overhead of earlier protocols.

Syscall interception benefits

The syscall interception model provides:

  • Reduced host kernel exposure: only Sentry-mediated calls reach the host
  • No hardware requirements: runs anywhere, no virtualization needed
  • Process-level isolation: Sentry runs as an unprivileged user process

Syscall interception tradeoffs

Implementing a kernel in user space has inherent limitations:

Performance overhead: Every syscall passes through Sentry. The translation layer adds latency. A 2019 USENIX study measured syscall operations at 2–11x slower than native depending on the platform and syscall type. gVisor has since introduced the systrap platform (replacing ptrace as the default), which improves syscall interception performance. I/O-heavy and syscall-intensive workloads see the biggest impact. CPU-bound workloads with infrequent syscalls may see minimal overhead.

Compatibility gaps: Sentry implements a subset of Linux syscalls. Some syscalls are fully supported, others partially, and some not at all. Applications using unsupported syscalls fail or behave unexpectedly.

No eBPF support: eBPF programs run inside the kernel. Since Sentry isn’t a real kernel, eBPF-based tooling (Falco, standard observability stacks) doesn’t work.

Different debugging model: Standard host-side kernel tools (perf, ftrace, kprobes) don’t work against Sentry’s user-space implementation. gVisor provides its own built-in --strace flag and Go-based profiling, but these are gVisor-specific tools, not the standard Linux debugging toolchain.

How MicroVM isolation works

MicroVM isolation takes a different approach: instead of intercepting syscalls, give each workload its own Linux kernel running under a hypervisor.

┌─────────────────────────────────────┐
│           Application               │
├─────────────────────────────────────┤
│      Real Linux Kernel              │
├─────────────────────────────────────┤
│          Hypervisor                 │
│   - Manages memory isolation        │
│   - Handles I/O multiplexing        │
│   - Enforces CPU scheduling         │
└─────────────────────────────────────┘

For a deeper dive on how Edera implements this, see What is paravirtualization?

MicroVM benefits

Running a real kernel per workload provides:

  • Linux compatibility: the application talks to a real kernel
  • Near-native performance: no syscall translation layer
  • Standard tooling available: eBPF (with eBPF-capable zone kernel), Falco (via Edera plugin, kernel 6.16+), kernel debug interfaces (debugfs/tracefs in v1.6.0+)

MicroVM tradeoffs

Memory overhead: Each zone (Edera’s term for a lightweight VM—by default, one per pod) needs its own kernel in memory. Zones add approximately 64 MiB of overhead each (kernel, hypervisor, initramfs).

Hypervisor dependency: Requires a hypervisor layer. Edera uses a Xen-derived hypervisor with most components rebuilt in Rust.

Architectural comparison

AspectSyscall interception (gVisor)MicroVM (Edera)
Isolation mechanismUser-space syscall filteringHypervisor-enforced VM boundaries
Kernel per workloadNo (Sentry is not a kernel)Yes (real Linux kernel)
Syscall pathApp → Sentry → Host kernelApp → Zone kernel (hypercalls only for I/O)
Attack surfaceSentry codebaseHypervisor + zone kernel
eBPF supportNoYes (requires eBPF-capable zone kernel)
Kernel toolinggVisor-specific (--strace, Go profiling)Standard Linux tools (perf, ftrace, eBPF)
Performance overheadHistorically 2–11x syscall latency (improving with systrap)Near-native
Memory overhead per workloadLower~64 MiB

When each architecture makes sense

Syscall interception works well when:

  • Workloads are CPU-bound with minimal syscall activity
  • The application uses only well-supported syscalls
  • gVisor’s built-in debugging tools are sufficient
  • Memory overhead must be minimized

MicroVM isolation works well when:

  • Workloads are I/O-intensive or latency-sensitive
  • Full Linux compatibility is required
  • eBPF-based security monitoring is needed
  • Standard kernel debugging tools are expected to work

Neither approach is inherently “better”—they’re different tradeoffs. gVisor optimizes for minimal memory overhead and broad deployment compatibility. Edera optimizes for full Linux compatibility and native performance.

Further reading

Last updated on