unikernels have been onerous. key phrase: have been.

Justin Cormack, who labored on MirageOS and Unikernel Systems again within the day, has been noticing what I’ve been noticing: individuals are discovering (or rediscovering) unikernels once more. He’s working a sequence of conversations on the subject for his publication, and I used to be first up. He emailed me, and 5 minutes later I used to be speaking to him from the pub with a stein of beer in hand. We went deep on Mirage, Orleans, Haskell, Nix, Cursed and a complete lot extra.
Here’s the gist, written up correctly, with chapter hyperlinks on the backside if you wish to leap to a selected a part of the dialog. Justin’s edited transcript is over at Ignore Previous Directions.
Unikernels have been onerous. Key phrase: have been. Now we have now AI.
what a unikernel is, and why they have been onerous
I first bumped into unikernels round 2015. I’d staffed up a crew of Haskellers and gone fairly deep on useful programming. Where there are Haskellers, there are OCaml programmers, and from there you discover MirageOS. Great concept. I performed with it again then.
A unikernel is the concept that your utility is the working system. There’s no userland. If you need a internet server, DNS, or to ship an e-mail, there’s nothing you may fork or spawn. You have to write down these issues as libraries in your utility.
That was the friction. Justin remembers it properly: once they have been constructing Mirage, that they had a TCP stack and an HTTPS stack, however there was virtually nothing for storage. They have been pulling drivers out of NetBSD as a result of they may run them in userspace. It was onerous again then.
There’s numerous dogma in our trade. Nix is tough. Bazel is tough. Unikernels are onerous. Yes, they have been. These onerous ideas are actually within the mannequin weights. All you have to do is immediate for them and, cognitively, do away with the dogma that they are onerous.
the working system is design debt
Every utility that is not a unikernel was constructed on the belief that there is an utility, after which there’s an working system beneath. Why will we even have an working system? Because forty years in the past there was a human operator. I’ve completed IBM 5250, AIX, Solaris, and mainframes. The multi-user working system exists as a result of an individual sat in entrance of it, after which we put the applying on prime.
I contemplate that design debt, and here is why it issues proper now. Applications get popped. They have been getting popped earlier than AI. Someone pops the userland utility and will get a shell. That shell is a VIP butler service for exfiltration.
With a unikernel, the assault floor is far smaller. If the performance is not within the utility (the working system), then the attacker is screwed. There’s no subsequent hop.
Justin pushed again right here, and pretty. Attack-surface discount is one thing individuals are very fuzzy about. You can take away the shell from a Linux container, however virtually each Linux atmosphere nonetheless has one thing that is successfully an interpreter. You can execute a brand new program with no writable filesystem. You’ve nonetheless bought reminiscence security and devices to fret about.
All true. But have a look at what we have been doing for twenty-six years. The earliest adage I bear in mind from the SunOS and cgi-bin days was “do not put the compiler on manufacturing.” Then got here construct containers and manufacturing containers. Then Chainguard. We maintain chipping away on the assault floor, as an alternative of getting in the wrong way and making certain there is no assault floor.
And that is the bit folks miss: if there is no shell and no interpreter, there’s nothing within the mannequin weights that is aware of what to do subsequent. That turns a drive-by (choose your framework’s RCE of the week and you have a shell, and the mannequin weights know what to do with shell entry) right into a focused assault that wants your supply code.
you may simply port the lacking libraries now
The traditional objection: your unikernel wants to speak to Stripe, and OCaml does not have a Stripe library. Before AI you’d sigh and write it. Now? Run a loop to port the Go library to OCaml. Here you go: Stripe in a unikernel.
Justin had an important instance of the identical factor. He’d been constructing minimal Linux OS pictures for home equipment, which is midway to a unikernel anyway, because you’re solely working one utility as PID 1. He wanted to make an XFS filesystem. Rather than drag in xfsprogs and the whole lot it brings with it, he sat down with an agent and had it write mkfs.xfs in Rust, producing byte-for-byte similar output, with each flag interpreted. It reverse-engineered the on-disk codecs one after the other, with exams throughout block sizes. It took a couple of hours.
That works as a result of the unique instrument is a golden oracle. Generate filesystems at completely different sizes with each implementations and diff them. Port the exams throughout. Automate it.
porting software has been trivial for a while now. here’s how you do it.
If you have an oracle, porting is a loop.
Geoffrey Huntley
Storage was the opposite large hole. Most workloads lately are cloud-shaped, even on-prem, so take the turbopuffer method: S3 as your major, infinitely growable storage, with a neighborhood NVMe block cache and an LRU (or no matter caching algorithm you want) for the new bits. Justin is an enormous “S3 for the whole lot” fan too. As lengthy as latency is not the constraint, you get infinite storage with multi-user entry, and you may construct the whole lot on it.
nix machine exams and overlays
Justin had been experimenting with Nix too, and was shocked that the primary time he bought an agent to prototype an OS, it constructed all of the exams into flakes.
Nix the language sucks. Nixpkgs is nice. NixOS machine tests are the bee’s knees: you write a take a look at that spins up a fleet of machines and workouts the interplay between your community guidelines and your utility. It’s the factor folks do not learn about.
And when one thing upstream is damaged, or there is a provide chain drawback in your dependencies, that is simply an overlay.
the world hasn’t figured out yet that you can literally just fix everything with a Nix overlay
Patch the world.
Geoffrey Huntley
If it’s important to tool-call a human, also referred to as “Dear Maintainer”, who is perhaps on vacation or may need deserted the venture, and wait a day, two days, and even 5 minutes, that is not AGI.
We’re constructing recursive merchandise right here. Agents want the power to change the globe as first-party supply, not as third-party bundled binaries. We’re going again to the contrib folder and Unix patches.
if you happen to care about safety, you’ve got two decisions
Justin requested what unikernels nonetheless want for folks to find them. Honestly, it is this. We’ve raised two generations of builders who do not even know they are a factor.
If you deeply care about safety, there are actually two decisions:
- You’re sending satellites into area, and it’s best to most likely use seL4, a formally verified working system. (I’m nonetheless a bit salty in regards to the Australian authorities disbanding that crew.)
- Everyone else ought to critically contemplate unikernels. Stop attempting to harden one thing that could be very hackable. Invert it and design from the opposite route.
The different traditional criticism is that many early unikernel designs ran the whole lot at a single privilege degree: your utility in the identical ring because the OS. In 2026, that is a immediate away from being mounted if you’d like ring separation. It’s actually safer than praying to god your systemd cgroup configuration is true.
Think about how a lot time enterprises spend patching the globe each time one thing new drops in Linux. Upstream now expects you to patch your kernel weekly. The week we recorded, somebody popped KVM (primarily Firecracker, the core primitive all of us thought was good sandboxing) and picked up $50,000 from Vercel and some different distributors. That shouldn’t be a lot cash for one thing that would root each managed cloud supplier within the globe.
spaceleans: a distributed unikernel working system
About seven months in the past, I went deep on unikernels to examine whether or not my psychological mannequin was proper. I confirmed Justin my Mirage folder, which holds all of the performance I wanted so as to add.
- There was no method for a unikernel fleet to maintain time, so I took an NTP consumer from one other language and ported it. Then I constructed an NTP server primarily based on RADclock and borrowed concepts from how TigerBeetle handles time: not one clock supply however many, packaged as a library.
- Network stack, DNS, HTTP shoppers and servers, structured logging, OTel, Anthropic and OpenAI shoppers, and funds through Airwallex.
- A generic retry library for dealing with again strain over HTTP, plus some PPX metaprogramming for fun.
- A PII wrapper on the logging boundary, so secrets and techniques and PII by no means leak by way of the logging subsystem. Every venture ought to have one. It’s pluggable; simply use a functor.
And then essentially the most cooked factor, which I’d by no means proven anybody earlier than: Spaceleans, Microsoft Orleans ported to OCaml, working as a unikernel.
Orleans is a distributed actor system with transactions. You take many bodily machines and merge them into one addressable heap. An actor all the time exists: await GetCustomer(), and if it is not in reminiscence, it will get rehydrated from a pluggable storage supplier. You collapse your n-tier structure into actors and cease caring whether or not one thing lives on machine A, B, C or D. The runtime handles it as an transport systems primitive.
So in a bizarre sense, I constructed a distributed unikernel working system out of actors, with a filesystem on prime. Justin known as it Erlang-esque, and he is proper. I did all of it in per week. I’ll most likely by no means launch it, however it falsified the concept that unikernels are onerous.
sampling historical past
Being a little bit older means you may pattern historical past, like an skilled DJ resembling Carl Cox, who’s been within the scene lengthy sufficient to tug from earlier repertoire and produce it ahead. All of those concepts existed within the eighties. The fashions have learn the papers. They’ve bought TAPL and essentially the most superior sort principle of their coaching information.
The factor that is missing is folks’s curiosity and ambition to do these unhinged issues, and the data that earlier data exist that may be sampled from.
How will we get folks to do that stuff? We simply do it. If you’ve got bought a turbo Lamborghini alien area rocket that is extra environment friendly and safer, good for you; you’ve got bought a leg up. Do cool issues, appeal to curious newcomers, mentor them, develop. Same because it’s all the time been.
Meanwhile, everybody else will probably be attempting to Chainguard their Ruby on Rails utility and managing AWS with fifty AWS-certified engineers, when two folks with Nix and Hetzner would do. Eventually, it comes right down to cash. Higher-powered instruments are extra environment friendly, and effectivity wins, particularly as AI collapses margins.
ocaml, rust, haskell and again strain
Has OCaml’s time come once more? It’s nonetheless going sturdy. A sure buying and selling agency is utilizing it very properly. When I caught up with Yaron in the beginning of the 12 months, I requested him whether or not OxCaml exists so their language extensions find yourself within the coaching information and elevate the entire firm. I bought a really “no remark” smile.
For brokers, OCaml is gorgeous. Functors between modules are lovely. The .mli recordsdata, a typed header explaining how a module ought to work, are actually environment friendly context for brokers. opam and Dune are legitimately good. Hindley–Milner. And compile instances are quick. I see no purpose to do F# lately.
Justin has largely been writing Rust, and brokers are good at Rust. But compile time is the tax on back pressure. LLMs hallucinate, and when compilation is gradual, every hallucination is pricey since you get fewer makes an attempt per minute. Justin’s S3 clone is about one million traces of Rust; with 4 brokers compiling without delay, they combat over disk and CPU. You find yourself spending extra on quick machines than on tokens.
Haskell’s sort system is nice, and the fashions do it very well. But I do not really feel good working it in manufacturing: an area leak lives within the runtime state area and solely exhibits up in manufacturing. Justin identified that the linear-type concepts in Rust got here out of Haskell papers attempting to resolve precisely that. Then there’s Zig’s method: allocate the whole lot up entrance and by no means allocate once more, which is what sport devs did within the eighties and nineties. It’s onerous to influence an agent to try this in Rust, although, as a result of constant-memory applications aren’t in its coaching set.
I feel dependent sorts are the winner for next-generation languages. Anything that permits you to codify extra into the sort system is extra again strain. You most likely will not be shocked to listen to I’ve bought a fork of the Rust toolchain with dependent sorts. You can simply do issues now.
languages for brokers, and what cursed taught me
The tempo of language improvement has been held again by how briskly people can study new ideas. Operator chaining is basically sugar for people. If brokers write the code, we will lean on forty years of educational PLT analysis, so long as you know the way to pattern it.
The trade codified “don’t make breaking modifications” after Python 2 to three. Justin knew firms with tons of of individuals on that migration for years. I feel that rule is now not true. Ship a talent pack with the breaking change and let brokers auto-migrate.
Justin requested what it really prices to make a brand new language profitable now. Go was the final language an organization spent actual cash on, and it took a very long time. I can reply that one.
i ran Claude in a loop for three months, and it created a genz programming language called cursed
It’s the only compiled language that lets you code with sus, slay and vibes.
Geoffrey Huntley
Cursed was constructed with Sonnet 3.5 and three.7, a intentionally underspecified immediate, and three months of working it in a loop. I began in C (not sufficient again strain; I wasted an excessive amount of time in Valgrind because the agent clobbered its personal updates), then Rust, then Zig. Zig was a mistake; it will work right this moment if I’d stayed with Rust. It value roughly US$6,000, and I did it 3 times over. Compare that to what Go value.
Now the actual bit, the half that also scares me. If you allocate the context window accurately — a lookup desk of the lexical construction and grammar — the mannequin can program in a language that is not in its weights. It’s brute pressure and inefficient, however it works.
Think T-diagrams (tombstone diagrams). Lock down your grammar and lexical construction, attain a stage-two self-hosting compiler, ship a wise commonplace library, and begin the subsequent coaching run. From there, you may attain a Roslyn-style self-hosted compiler with language providers stupidly quick. Justin requested whether or not fine-tuning an open mannequin would assist bootstrap a language like this. It’s not wanted.
That was true a 12 months and a half in the past with a lot weaker fashions. It’ll take only one programming language designer going all in with the great fashions to shock the globe.
what subsequent
As the pub was shutting, Justin requested what was on my thoughts. If you have not learn my newest put up, go learn it. If you handle folks, create the area and time for them to experiment now, as a result of inside six months, management will ask you to place folks on a vitality curve.
if your team is too busy doing their ‘normal job’ to experiment with AI, you’re preparing them to be replaced
AI use is now mandatory for employability.
Geoffrey Huntley
Yes, the labs skilled on the commons. I hate that, and I get it. But you commerce time and talent for cash; employers have minimal requirements, and people requirements have modified quicker than ever earlier than in our trade. Be curious, discover ways to construct an agent, and go create lovely stuff. We’re in a renaissance.
It’s a time-compression system. The extra expertise you’ve got, the extra you may pattern. Not the whole lot ships; a few of what I confirmed Justin might by no means see the sunshine of day. I take advantage of these tasks as katas and redo them when the fashions get higher.
But if you wish to construct one thing safe, critically contemplate unikernels.
chapters
- 0:21 — discovering unikernels: Haskell to OCaml to Mirage
- 0:55 — what a unikernel is, and why it was onerous
- 2:45 — onerous was previous tense
- 3:33 — why do we have now an working system?
- 4:17 — the shell is a butler service for exfiltration
- 5:12 — assault floor discount is fuzzy
- 7:26 — do not put the compiler on manufacturing
- 9:13 — porting Stripe right into a unikernel
- 9:54 — minimal Linux and mkfs.xfs in Rust
- 12:22 — S3 for the whole lot
- 13:48 — Nix, machine exams and overlays
- 15:28 — tool-calling a human shouldn’t be AGI
- 15:53 — seL4 or unikernels
- 16:56 — privilege rings
- 18:24 — weekly kernel patches and the KVM escape
- 19:38 — demo: the Mirage folder, NTP and time
- 22:05 — Spaceleans: Orleans in OCaml as a unikernel
- 25:31 — sampling historical past
- 26:52 — methods to get folks to do that: simply do it
- 28:57 — OCaml and OxCaml
- 31:45 — Rust compile instances and again strain
- 33:06 — Haskell, area leaks and dependent sorts
- 35:13 — reminiscence methods: Rust, Zig and sport devs
- 36:10 — languages designed for brokers
- 37:41 — breaking modifications and talent packs
- 38:53 — Cursed
- 42:36 — what Cursed taught me
- 46:47 — what’s subsequent: AI use is necessary
Keep curious.
