crun vs runc Container Runtime 2026
Compare crun vs runc container runtimes for Kubernetes. Performance benchmarks, memory usage, cgroup v2 support, and migration from runc to crun guide.
π‘ Quick Answer: Use crun for faster container startup (50% faster cold start) and lower memory usage (10x less RSS). Use runc for maximum compatibility and when running on cgroup v1. Both are OCI-compliant β switching is a one-line config change in containerd or CRI-O.
The Problem
Teams assume all container runtimes are equal, but crun (written in C) starts containers 50% faster and uses 10x less memory than runc (written in Go). For Kubernetes nodes running 100+ pods, the difference in node overhead is significant.
The Solution
Performance Comparison
| Feature | runc | crun |
|---|---|---|
| Language | Go | C |
| Cold start | ~100ms | ~50ms |
| Memory per container | ~10MB RSS | ~1MB RSS |
| cgroup v2 native | Partial | Full |
| Rootless containers | Yes | Yes |
| WASM support | No | Yes (wasmedge) |
| OCI compliant | Yes | Yes |
| Default in containerd | Yes | No |
| Default in Podman/CRI-O | No | Yes (RHEL 9+) |
Configure containerd to use crun
# /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.crun]
runtime_type = "io.containerd.runc.v2"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.crun.options]
BinaryName = "/usr/bin/crun"Configure CRI-O to use crun
# /etc/crio/crio.conf.d/01-crun.conf
[crio.runtime]
default_runtime = "crun"
[crio.runtime.runtimes.crun]
runtime_path = "/usr/bin/crun"
runtime_type = "oci"Install crun
# Fedora / RHEL 9+
sudo dnf install crun
# Ubuntu / Debian
sudo apt install crun
# Verify
crun --version
# crun version 1.14
# spec: 1.0.0
# +SYSTEMD +SELINUX +CAP +SECCOMP +EBPF +CRIU +LIBKRUN +WASM:wasmedgeKubernetes RuntimeClass
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: crun
handler: crun
---
apiVersion: v1
kind: Pod
metadata:
name: fast-start
spec:
runtimeClassName: crun
containers:
- name: app
image: registry.example.com/app:v1graph TD
subgraph runc - Go Runtime
R_START[Container Start<br/>~100ms] --> R_MEM[Memory<br/>~10MB RSS per container]
R_MEM --> R_COMPAT[Maximum compatibility<br/>Default everywhere]
end
subgraph crun - C Runtime
C_START[Container Start<br/>~50ms β‘] --> C_MEM[Memory<br/>~1MB RSS per container]
C_MEM --> C_FEAT[WASM support<br/>cgroup v2 native]
endCommon Issues
crun not found after install: Verify path: which crun. containerd needs the full path in config. Restart containerd after config changes.
Pods failing with crun: Check crun supports your seccomp profile. Some older seccomp profiles reference syscalls not handled by crun.
Best Practices
- crun for performance β 50% faster starts, 10x less memory
- runc for compatibility β default everywhere, battle-tested
- Both OCI-compliant β same container images, same behavior
- RuntimeClass for mixed β run both on the same cluster
- RHEL 9+ defaults to crun β Red Hat already made this choice
Key Takeaways
- crun is 50% faster and 10x lighter than runc β written in C vs Go
- Both are fully OCI-compliant β switching requires only a config change
- crun is default on RHEL 9+, Fedora, and Podman
- Use RuntimeClass to run both runtimes on the same Kubernetes cluster
- crun adds WASM support via wasmedge β runc doesnβt support WASM

Recommended
Kubernetes Recipes β The Complete Book100+ production-ready patterns with detailed explanations, best practices, and copy-paste YAML. Everything in one place.
Get the Book βLearn by Doing
CopyPasteLearn β Hands-on Cloud & DevOps CoursesMaster Kubernetes, Ansible, Terraform, and MLOps with interactive, copy-paste-run lessons. Start free.
Browse Courses βπ Deepen Your Skills β Hands-on Courses
Courses by CopyPasteLearn.com β Learn IT by Doing
