# Performance Benefits of Using bpftime: 10× Faster eBPF Execution Explained

> Discover how bpftime achieves 10× faster eBPF execution by bypassing the kernel, using a JIT AOT compiler, and zero-copy shared-memory. Explore the performance benefits today.

- Repository: [eunomia-bpf/bpftime](https://github.com/eunomia-bpf/bpftime)
- Tags: performance
- Published: 2026-03-01

---

**bpftime delivers up to 10× faster eBPF execution compared to traditional kernel-based eBPF by bypassing the kernel entirely, leveraging a high-performance LLVM-based JIT/AOT compiler, and utilizing zero-copy shared-memory maps with lock-free data structures.**

The **eunomia-bpf/bpftime** repository provides a userspace eBPF runtime designed specifically for high-performance observability and extensibility. By reimplementing the eBPF virtual machine and map infrastructure outside the kernel, bpftime eliminates the primary sources of overhead that limit traditional eBPF deployments.

## Kernel Bypass Eliminates Context Switch Overhead

Running eBPF programs in userspace removes the costly kernel traps and context switches inherent to kernel-based eBPF. In [`runtime/src/handler/handler_manager.hpp`](https://github.com/eunomia-bpf/bpftime/blob/main/runtime/src/handler/handler_manager.hpp), the central registry stores all eBPF objects (programs, maps, links) in a **Boost-interprocess shared memory segment**, enabling direct userspace access without system call transitions.

This architecture is particularly effective for high-frequency probes such as `uprobes` and `syscalls`, where kernel entry/exit overhead often dominates execution time.

## LLVM JIT/AOT Compiler Optimization

The **LLVM-based JIT/AOT compiler** in [`vm/llvm-jit/llvm_bpf_jit.hpp`](https://github.com/eunomia-bpf/bpftime/blob/main/vm/llvm-jit/llvm_bpf_jit.hpp) generates native machine code from eBPF bytecode with aggressive optimization passes. Key performance features include:

- **Helper function inlining**: The compiler eliminates call overhead for frequently used helpers by inlining them directly into the generated code.
- **Production-grade optimizations**: Standard LLVM passes including instruction combining, loop unrolling, and dead code elimination.
- **PTX generation**: The [`vm/llvm-jit/ptx_code_gen.cpp`](https://github.com/eunomia-bpf/bpftime/blob/main/vm/llvm-jit/ptx_code_gen.cpp) module emits PTX code for GPU execution, allowing eBPF programs to run directly on NVIDIA hardware.

The AOT compilation mode (configured via [`vm/llvm-jit/compiler.cpp`](https://github.com/eunomia-bpf/bpftime/blob/main/vm/llvm-jit/compiler.cpp)) pre-compiles eBPF bytecode to native ELF or PTX, removing JIT overhead entirely for long-running workloads. Benchmarks show AOT mode is approximately **30% faster** than JIT mode.

## Zero-Copy Shared Memory Architecture

bpftime implements **zero-copy shared memory** through [`runtime/shm/bpftime_shm.cpp`](https://github.com/eunomia-bpf/bpftime/blob/main/runtime/shm/bpftime_shm.cpp), which creates and manages the shared memory segment layout and synchronization primitives. This design provides:

- **Cross-process zero-copy IPC**: Multiple processes can access eBPF maps and programs without serialization or memory copying.
- **Deterministic low latency**: Fixed-size map variants eliminate dynamic resizing overhead.

The [`runtime/src/bpf_map/userspace/array_map.hpp`](https://github.com/eunomia-bpf/bpftime/blob/main/runtime/src/bpf_map/userspace/array_map.hpp) implements a pure-userspace array map with **lock-free reads**, providing the low-latency map access required by high-frequency probes.

## Lock-Free and Per-CPU Map Structures

For high-parallelism workloads, bpftime provides specialized map implementations that minimize contention:

- **Spin-lock protection**: Per-CPU maps use `pthread_spinlock` for faster synchronization compared to mutexes in uncontended scenarios.
- **Lock-free data structures**: Certain map types operate without locks entirely, eliminating serialization bottlenecks.

These implementations in `runtime/src/bpf_map/` ensure that map operations do not become the bottleneck when running hundreds of thousands of events per second across multiple CPU cores.

## GPU-Accelerated Map Support

The [`runtime/src/bpf_map/gpu/gpu_array_map.hpp`](https://github.com/eunomia-bpf/bpftime/blob/main/runtime/src/bpf_map/gpu/gpu_array_map.hpp) provides **CUDA-resident array maps** that reside in GPU memory. This enables:

- **Direct GPU access**: eBPF programs compiled to PTX can read and write map data without host-to-device copies.
- **Native CUDA throughput**: Map operations achieve full GPU memory bandwidth when accessed from CUDA kernels.

This architecture is unique among eBPF runtimes and provides significant acceleration for GPU-based observability and packet processing workloads.

## Benchmarking bpftime Performance

### Measuring JIT vs AOT Compilation

Use the `bpftimetool` utility to compare execution modes:

```bash

# Build the benchmarking tool

make -C tools/bpftimetool

# Run with JIT compilation

bpftimetool run --mode jit ./benchmarks/tracepoint.o

# Run with AOT-compiled native code (optimal performance)

bpftimetool run --mode aot ./benchmarks/tracepoint.o

```

The tool reports nanosecond-level latency per probe. In continuous integration benchmarks, AOT mode consistently demonstrates the **30% performance improvement** over JIT, while both modes maintain the **10× speed advantage** over kernel eBPF equivalents.

### Real-World CLI Usage

Deploy high-performance probes using the bpftime CLI:

```bash

# Build the example malloc tracer

make -C example/malloc

# Add bpftime binaries to PATH

export PATH=$PATH:~/.bpftime

# Load the program (triggers LLVM JIT compilation)

bpftime load ./example/malloc/malloc

# Execute target binary with automatic probe attachment

bpftime start ./example/malloc/victim

```

The `bpftime load` command compiles eBPF bytecode to native code via the LLVM JIT backend, immediately providing the performance benefits of userspace execution without kernel overhead.

### GPU-Accelerated Map Example

For GPU-intensive workloads, initialize CUDA-resident maps:

```cpp
#include <bpftime.hpp>
#include "bpftime_gpu_map.hpp"

int main() {
    // Initialize runtime with shared memory segment
    bpftime_initialize_global_shm();

    // Create GPU-resident array map (1024 entries)
    int map_fd = bpftime_maps_create(
        BPF_MAP_TYPE_ARRAY, 
        sizeof(uint32_t), 
        sizeof(uint64_t), 
        1024,
        BPFTIME_MAP_FLAG_GPU
    );

    // Load PTX-compiled eBPF program
    bpftime_prog_load("gpu_prog.o");

    // Execute with on-device map access (zero host-device copies)
    bpftime_prog_exec();
}

```

This configuration eliminates host-to-device memory traffic, achieving native CUDA throughput while maintaining eBPF's flexibility.

## Key Source Files Enabling High Performance

| File | Role | Performance Impact |
|------|------|-------------------|
| [`runtime/src/handler/handler_manager.hpp`](https://github.com/eunomia-bpf/bpftime/blob/main/runtime/src/handler/handler_manager.hpp) | Central registry for eBPF objects in shared memory | Enables zero-copy cross-process access and fast handle lookup |
| [`runtime/src/bpf_map/userspace/array_map.hpp`](https://github.com/eunomia-bpf/bpftime/blob/main/runtime/src/bpf_map/userspace/array_map.hpp) | Pure-userspace array map with lock-free reads | Provides low-latency map access for high-frequency probes |
| [`runtime/src/bpf_map/gpu/gpu_array_map.hpp`](https://github.com/eunomia-bpf/bpftime/blob/main/runtime/src/bpf_map/gpu/gpu_array_map.hpp) | CUDA-resident array map implementation | Drives GPU-accelerated performance path |
| [`vm/llvm-jit/llvm_bpf_jit.hpp`](https://github.com/eunomia-bpf/bpftime/blob/main/vm/llvm-jit/llvm_bpf_jit.hpp) | Core LLVM JIT/AOT compiler class | Generates optimized native code with helper inlining |
| [`vm/llvm-jit/compiler.cpp`](https://github.com/eunomia-bpf/bpftime/blob/main/vm/llvm-jit/compiler.cpp) | eBPF bytecode to LLVM IR translation | Applies aggressive LLVM optimization passes |
| [`vm/llvm-jit/ptx_code_gen.cpp`](https://github.com/eunomia-bpf/bpftime/blob/main/vm/llvm-jit/ptx_code_gen.cpp) | PTX code generation for NVIDIA GPUs | Enables direct GPU execution of eBPF programs |
| [`runtime/shm/bpftime_shm.cpp`](https://github.com/eunomia-bpf/bpftime/blob/main/runtime/shm/bpftime_shm.cpp) | Shared memory segment management | Underpins zero-copy architecture |
| [`runtime/include/bpftime.hpp`](https://github.com/eunomia-bpf/bpftime/blob/main/runtime/include/bpftime.hpp) | Public C API | Provides thin wrapper to high-performance backend |

## Summary

- **Kernel bypass architecture** eliminates system call overhead and context switches, providing the foundation for userspace eBPF execution.
- **LLVM JIT/AOT compilation** generates native machine code with aggressive optimizations and helper inlining, delivering production-grade performance.
- **Zero-copy shared memory** enables lock-free, cross-process map access without serialization overhead.
- **GPU acceleration** via CUDA-resident maps and PTX compilation extends performance benefits to GPU workloads.
- **Benchmark results** demonstrate consistent **10× speed improvements** over kernel eBPF and **30% gains** for AOT versus JIT compilation.

## Frequently Asked Questions

### How much faster is bpftime compared to kernel eBPF?

bpftime achieves up to **10× faster execution** compared to traditional kernel eBPF. This performance gain comes from eliminating kernel entry/exit overhead through userspace execution, utilizing LLVM-based native code generation instead of kernel interpreters, and implementing zero-copy shared memory maps that avoid system call overhead for data access.

### What makes bpftime's LLVM JIT compiler faster than interpreters?

The **LLVM JIT/AOT compiler** in [`vm/llvm-jit/compiler.cpp`](https://github.com/eunomia-bpf/bpftime/blob/main/vm/llvm-jit/compiler.cpp) translates eBPF bytecode directly to native machine code using aggressive LLVM optimization passes. Unlike interpreters that decode and execute instructions sequentially, the JIT compiler performs **helper function inlining**, dead code elimination, and instruction combining at compile time. The AOT mode further removes runtime compilation overhead entirely, providing an additional 30% performance improvement over JIT mode.

### Can bpftime run eBPF programs on GPUs?

Yes, bpftime supports **GPU-accelerated execution** through the [`runtime/src/bpf_map/gpu/gpu_array_map.hpp`](https://github.com/eunomia-bpf/bpftime/blob/main/runtime/src/bpf_map/gpu/gpu_array_map.hpp) implementation and PTX code generation in [`vm/llvm-jit/ptx_code_gen.cpp`](https://github.com/eunomia-bpf/bpftime/blob/main/vm/llvm-jit/ptx_code_gen.cpp). eBPF programs can be compiled to PTX (Parallel Thread Execution) format and execute directly on NVIDIA GPUs. GPU-resident maps eliminate host-to-device memory copies, allowing map operations to achieve native CUDA memory bandwidth while maintaining eBPF's programming model.

### Does bpftime maintain compatibility with existing eBPF toolchains?

Yes, bpftime maintains **full compatibility** with existing eBPF toolchains and bytecode. The [`runtime/include/bpftime.hpp`](https://github.com/eunomia-bpf/bpftime/blob/main/runtime/include/bpftime.hpp) API provides a thin wrapper that accepts standard eBPF ELF objects and map definitions. Users can compile eBPF programs using standard tools like `clang` and `llvm`, then load them into bpftime using the familiar `bpftime load` command. The runtime implements the same helper functions and map types as the kernel, ensuring portable eBPF code works without modification.