Repository navigation
Announcing Hyperlight 0.19.0 #18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | ||
|
|
||
| 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()?; | ||
| ``` | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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