Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions src/content/docs/blog/hyperlight-0.19.0.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
---
title: "Announcing Hyperlight 0.19.0"
date: 2026-11-05
---

# Announcing Hyperlight 0.19.0

_Hyperlight is a lightweight Virtual Machine Manager (VMM) designed to be
embedded directly in applications. It enables safe execution of untrusted code
with low latency and minimal overhead._

Hyperlight 0.19.0 has been released! This release includes significantly faster
snapshots, enables memory reuse between snapshots, lets you resize scratch
memory on snapshot, and changes the way guest heaps are laid out. To view the
full list of changes, please see the [_0.19.0
changelog_](https://github.com/hyperlight-dev/hyperlight/blob/v0.19.0/CHANGELOG.md#v0190---2026-11-04).

## Faster snapshot creation and restore

Snapshots in this release have gotten a significant speed-up. In some cases
latency has been reduced by as much as 99% (171 ms → 1.7 ms). Here are our
benchmark results targeting both MSHV on Linux 6.6 and KVM on Linux 6.17:

| Benchmark | MSHV | KVM |
| ----------------------------------- | ----------------------- | ----------------------- |
| `snapshots/create/default` | 440 µs → 249 µs (−43%) | 380 µs → 262 µs (−31%) |
| `snapshots/create/large` | 171 ms → 1.68 ms (−99%) | 162 ms → 1.7 ms (−99%) |
| `snapshots/call_and_create/medium` | 38.1 ms → 726 µs (−98%) | 35 ms → 778 µs (−98%) |
| `snapshots/restore_alternate/large` | 4.41 ms → 106 µs (−98%) | 1.66 ms → 131 µs (−92%) |
| `snapshots/restore/large` | 1.2 ms → 91.6 µs (−92%) | 403 µs → 52 µs (−87%) |

## Layered snapshots

Snapshots can now share memory between multiple layers using copy-on-write
semantics. This can greatly reduce memory usage when working with guests that
have a relatively big immutable part that is loaded as part of every guest. For
example: JavaScript workloads on Hyperlight now only have to pay the memory cost
for loading the JS runtime once, even if the workloads themselves are different.

In Hyperlight snapshots form a tree. You can restore an earlier snapshot and
take a new one to create a separate branch. Here is an example in Rust, where
`first` and `second` share memory with `root` but not with each other:

```rust
// Our root snapshot
let mut sandbox = ...;
let root = sandbox.snapshot()?;

// The first snapshot (branch 1)
sandbox.call::<i32>("MyValue", 42)?;
let first = sandbox.snapshot()?;

// The second snapshot (branch 2)
sandbox.restore(root)?;
sandbox.call::<i32>("MyValue", 100)?;
let second = sandbox.snapshot()?;
```

One caveat with layered snapshots is that layers are _immutable_, and so data in
a previous layer remains accessible in later snapshots. This requires extra care
when snapshots involve secrets: if a secret was snapshotted as part of one
layer, it will remain accessible by the guest even if it was subsequently
zeroed.

## Resize scratch memory when taking a snapshot

A guest may need more memory during initialization than it needs during the
remainder of the program operation. Hyperlight now lets you give these stages
different scratch sizes using
[`SnapshotOptions`](https://docs.rs/hyperlight-host/0.19.0/hyperlight_host/sandbox/snapshot/struct.SnapshotOptions.html).
This is for example the case with many interpreted languages, which consume more
memory during the initial interpretation:

```rust
use hyperlight_host::SandboxBuilder;
use hyperlight_host::sandbox::snapshot::SnapshotOptions;

// Create a sandbox which boots with 8MiB of scratch.
let mut sandbox = SandboxBuilder::from_file("guest.bin")
.scratch_size(8 * 1024 * 1024)
.build()?;

// ... Perform initialization work here.

// Snapshot the sandbox, resizing scratch to 2MiB.
let options = SnapshotOptions::default().scratch_size(2 * 1024 * 1024);
let snapshot = sandbox.snapshot_with_options(&options)?;
```

You can now also inspect how much scratch the guest has allocated using
`Sandbox::scratch_allocated_bytes`. It reports allocations since the last
snapshot or restore. Though note that this value is guest-controlled, and should
be used for diagnostics only.

## Guest heap is now backed by scratch memory

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Guest heap allocations is also faster than before, I think we should call that out, even if just in a sentence (. See hyperlight-dev/hyperlight#1968


Heap memory in the guest is now backed by the scratch region, providing a single
value to control. As a result of this change snapshots no longer contain a
zero-filled heap region, making them smaller and faster to create and load. As
well as making heap operations on the guest faster.

As the heap size now uses scratch memory, this may require a larger scratch
size. As part of this change we’ve removed all `heap_size` controls, making
`scratch_size` the only way to control heap size:

```rust
// before (0.18)
let sandbox = SandboxBuilder::from_file(guest_path)
.heap_size(1024 * 1024)
.scratch_size(4 * 1024 * 1024)
.build()?;

// after (0.19)
let sandbox = SandboxBuilder::from_file(guest_path)
.scratch_size(5 * 1024 * 1024) // heap now draws from scratch
.build()?;
```
Loading