System call latency

376ns

Rabbit

Linux 7.3.0: 29.3 µs · Linux, mitigations off: 1.04 µs

Rabbit is a Linux-ABI-compatible operating system kernel written in Rust.

Repository
NicolasBecasAzagra/Rabbit
License
GPL-2.0-only
Toolchain
nightly-2026-10-24
ABI
Linux userspace
Architecture
x86_64
Status
In development. Not production ready.
serial0
  1. [0.000]Rabbit: boot OK
  2. [0.012]MM DIRECTMAP OK
  3. [0.018]HEAP OK 10000
  4. [0.041]USER OK exit=0
  5. [0.102]SCHED OK
  6. [1.254]TICKS 100
  7. [2.008]INFER OK tokens=42
  8. [12.9s]AGENT loop complete

Four layers, one system

Each layer owns a single responsibility. Together they run a local model and let it act.

LayerWhat it doesWhat it adds
The kernelA kernel that does lessrabbit-kernel · rabbit-arch · rabbit-mm · rabbit-sched · rabbit-elf · rabbit-initramfs · rabbit-bootinfo · rabbit-drivers

No page table isolation, no LSM, no audit, no cgroups, no hooks. Demand paging, large pages, a scheduler with a short tail and real multiprocessing. Every number is published, including the losses.

Fewer milliseconds of work per operation, in a private single tenant guest.

The runtimeA runtime that serves a modelrabbit-infer · rabbit-initramfs

The weights are mapped from the initramfs without being copied, kept resident, and read by a decoder written from scratch: RMSNorm, rotary embeddings, grouped query attention, the gated feed forward block and a key value cache. It generates the same tokens as the reference implementation, one for one.

No dependency outside the Rust standard library, and no copy of the weights.

The agentAn agent that actsrabbit-agent · rabbit-http

The model answers with a tool call, the kernel runs the tool, and the model answers again. The shape of the call is not a request in the prompt but an automaton over bytes: the answer cannot be anything but a well formed call of a declared tool, with the keys that tool needs, each of them once, with the type the tool expects.

A grammar that makes a malformed tool call impossible.

The networkThe fourth layerrabbit-net · rabbit-netclient · rabbit-netstream · rabbit-http

The guest enumerates the bus, claims a network device, resolves the address of the gateway, sends a datagram to a server on the host and reads the answer, with the socket calls of the Linux ABI. The agent has a tool that does it, so the loop of the agent reaches the network.

A stack sized for the agent loop, not for the general case.

Rabbit is faster at every measured time, and uses less memory

Lower is faster on the same QEMU rig. The raw table below contains every measurement, including the losses.

Benchmark dot plot: Rabbit versus mainline Linux on a logarithmic scale

Benchmark comparison between Rabbit and mainline Linux. Operation times span 6 kernel measurements on a logarithmic axis from 100 nanoseconds to 100 milliseconds. End-to-end times span 3 measurements from 1 second to 10000 seconds. Memory and throughput comparisons are shown in the table below.

The chart continues to the right: scroll it sideways for the two mainline series and their values.

Kernel operations (log time, 100 ns – 100 ms)RabbitLinux 7.3.0Linux, mitigations off100 ns1 µs10 µs100 µs1 ms10 ms100 msSystem call77.9× faster376 ns29.3 us1.04 usMap and touch memory3.78× faster6.83 ms/MiB25.8 ms/MiB8.69 ms/MiBFault in memory, 4 KiB pages22.2× faster2.01 ms/MiB44.6 ms/MiB13.7 ms/MiBFault in memory, 2 MiB pages54.4× faster825 us/MiB44.9 ms/MiB13.0 ms/MiBFutex round trip62.3× faster6.53 us407 us97.7 usFour threads, spawn to join12.5× faster620 us7.73 ms4.59 msEnd-to-end (log time, 1 s – 10000 s)RabbitLinux 7.3.0Linux, mitigations off1 s10 s100 s1000 s10000 sBoot to the first result16.0× faster12.9 s206 s63.8 sTime to the first token2.19× faster11.25 s24.67 s22.82 sSeconds of an agent loop3.40× faster821 s2793 s2570 s

Memory and throughput

Resident memory of the guest319 MB476 MB483 MB1.49× less memory
Tokens per second0.45 tok/s0.20 tok/s0.21 tok/s2.25× more tokens/s
Resident memory with the model857 MB1021 MB1023 MB1.19× less memory
RabbitLinux 7.3.0Linux, mitigations off

Logarithmic scale: zero is not representable. The position of each mark encodes the order of magnitude, not the absolute difference.

Raw measurements
MetricRabbitLinux 7.3.0Linux, mitigations off
System call376 ns29.3 us1.04 us
Map and touch memory6.83 ms/MiB25.8 ms/MiB8.69 ms/MiB
Fault in memory, 4 KiB pages2.01 ms/MiB44.6 ms/MiB13.7 ms/MiB
Fault in memory, 2 MiB pages825 us/MiB44.9 ms/MiB13.0 ms/MiB
Futex round trip6.53 us407 us97.7 us
Four threads, spawn to join620 us7.73 ms4.59 ms
Boot to the first result12.9 s206 s63.8 s
Resident memory of the guest319 MB476 MB483 MB
Time to the first token11.25 s24.67 s22.82 s
Tokens per second0.45 tok/s0.20 tok/s0.21 tok/s
Seconds of an agent loop821 s2793 s2570 s
Resident memory with the model857 MB1021 MB1023 MB

A ladder of exit criteria

Every milestone ends with a sentence a machine can check. No hand-waving, no “almost done”.

Kernel and memory

  1. M0BootDone

    Xen PVH handover, serial output, physical memory map.

    Exit: Serial log contains "Rabbit: boot OK" and QEMU exits 33.

    Verification: Headless QEMU with a serial assertion.

  2. M1Exceptions and timersDone

    GDT, TSS with an IST stack, IDT, recoverable exceptions, 8259 PIC, PIT.

    Exit: Divide by zero prints "DIV0 RIP=..." and continues; 100 PIT ticks print "TICKS 100".

    Verification: Golden serial log.

  3. M2MemoryDone

    Buddy allocator, size class heap, higher half kernel, direct map.

    Exit: 10,000 allocate/free cycles without leaks or double frees; usable RAM matches -m.

    Verification: Host unit tests plus an on target self test.

  4. M2bDirect map onlyDone

    The kernel reaches physical memory only through the direct map.

    Exit: The same byte read before and after the switch.

    Verification: On target self test.

  5. M2cMetadata in its own memoryDone

    Frame metadata carved out of the memory it describes, guests of 32 GiB.

    Exit: A guest of 4 GiB boots, manages its memory and runs the workload.

    Verification: QEMU with -m 4G.

  6. M3ThreadsDone

    Kernel threads, preemptive round robin scheduler, interrupt safe locks.

    Exit: 10 threads make progress under preemption with fair scheduling.

    Verification: On target self test.

Userspace and paging

  1. M4UserspaceDone

    Ring 3, SYSCALL/SYSRET, ELF64 loader, 59 Linux system calls.

    Exit: A statically linked hello prints and exits 0; the system calls return the same values as Linux.

    Verification: Golden log plus a diff against mainline.

  2. M4bA real userlandDone

    A standard library program running unmodified.

    Exit: A standard library program runs unmodified, prints and exits 0.

    Verification: Golden log.

  3. M4cDemand pagingDone

    Demand paging for anonymous mappings.

    Exit: An anonymous mapping faults its pages in on demand, and the per page tail measures a real fault.

    Verification: The weights workload against mainline.

  4. E1InitramfsDone

    The initramfs as a read only file system.

    Exit: A user program reads a file from it.

    Verification: openat, read, lseek, fstat.

  5. E2File mapping and large pagesDone

    A file backed mapping and large pages.

    Exit: The weights are mapped with 2 MiB pages.

    Verification: The weights workload, before and after.

  6. E2bResident weightsDone

    Large pages for file mappings and mlock residency of the weights.

    Exit: The weights are resident: mlock keeps them in memory and the pages are large.

    Verification: The "locked pages" line of the boot log.

  7. E3aPrioritiesDone

    A scheduler with priorities and wakeup preemption.

    Exit: A scheduler with priorities and wakeup preemption.

    Verification: The threads workload and the wakeup test.

  8. E3bA short tailDone

    The tail of the scheduler measured, and the policy that shortens it.

    Exit: The tail of a runnable thread stays inside a budget.

    Verification: The threads workload, published with its p99.

Parallelism and network

  1. M9SMPDone

    ACPI MADT, INIT-SIPI-SIPI, LAPIC and IOAPIC, IPIs, four processors.

    Exit: Boots with 4 vCPUs; every processor runs its own threads and reports a heartbeat.

    Verification: Boot gate with four processors in CI.

  2. M10The networkDone

    The PCI bus, a virtio device, IPv4 and UDP, the sockets of the ABI.

    Exit: The kernel reaches the network: an agent calls an API and reads the answer.

    Verification: The networking gate in CI.

  3. M12TCPDone

    TCP in the kernel, so the agent can speak HTTP.

    Exit: A request and a reply over TCP.

    Verification: The networking gate in CI, with a request and a reply over TCP.

Inference, agent and measurement

  1. E4The inference runtimeDone

    A real model, token for token against the reference.

    Exit: A Rust inference runtime generates the same tokens as the reference implementation.

    Verification: Token for token diff against the reference.

  2. E5The runtime measuredDone

    Tokens per second and time to first token, both kernels, same machine.

    Exit: Tokens per second and time to first token, both kernels, same machine.

    Verification: The rig, with the raw data published.

  3. E6The agentDone

    Model, tool call, tool result and model, with a grammar that forces the call.

    Exit: The agent asks the model for a tool call, runs the tool and goes on, and the call is always well formed.

    Verification: The agent gate in CI, and the grammar tests.

  4. E7The agent measuredDone

    The latency of a step and the tokens of a step, on both kernels.

    Exit: The agent is measured on both kernels: the latency of a step and the tokens of a step.

    Verification: The rig, with the raw data published.

  5. E8The tools of an agentNext

    The agent writes a file and lists a directory: the tools need a file system the kernel serves.

    Exit: The tools need a file system the kernel serves.

    Verification: The tools against the same program on both kernels.

  6. M8The benchmark rigDone

    Seventeen measurements, the comparison published with its raw data.

    Exit: Published benchmark report: raw CSV, median, p99, sigma, N >= 30.

    Verification: The bench scripts.

  7. M11A quantized checkpointNext

    A quantized model fits in the memory of the machine and keeps its answer.

    Exit: A quantized model fits in the memory of the machine and keeps its answer.

    Verification: The runtime against the reference, with the digest of the checkpoint.

  8. M13TLSNext

    TLS in the kernel, so the agent can read the certificate of an API.

    Exit: Against a server with a certificate.

    Verification: The networking gate in CI.

Deferred

  1. M5A shellDeferred

    A /init busybox shell runs "ls | wc -l" with the same output as Linux.

  2. M6Dynamic linkingDeferred

    A musl dynamic binary runs from a read-only ext2 rootfs.

  3. M7Signals and pipelinesDeferred

    A signal and pipeline test suite produces identical output to Linux.

Run it today

Clone, build, boot. The repository has everything: the kernel, the runtime, the agent, the benchmark rig.

Clone the repository
git clone https://github.com/NicolasBecasAzagra/Rabbit.git

Boot in QEMU with make run. The serial log ends with exit status 33 when the boot is clean.

What people ask

Is this Linux?

No. Rabbit is an x86_64 kernel written from scratch that is compatible with the Linux userspace ABI: the same system calls, the same struct layouts, the same ELF loading rules. It is not a distribution and it does not replace Linux.

Does it run on my machine?

It runs in QEMU on x86_64, with -M q35. It is not bare metal yet, and without KVM or HVF the timings describe an emulator. Hardware acceleration is the open issue.

What does it need?

QEMU 8.2 or newer, 512 MiB of memory for the operations or 1024 MiB for the model and the agent, and a virtio network device for the network. The full comparison against mainline Linux needs a Linux host.

Which model does it serve?

SmolLM2-135M-Instruct, in bfloat16, with the revision pinned and the SHA-256 verified. A quantized checkpoint is produced by the same repository and measured too: Q8 reproduces the reference tokens, Q4 changes the answer, and that change is published as a loss.

The kernel is the comparison. Every measurement is published, every loss included.