WebAssembly (wasm) is a assembly binary format made for the web. Originally meant as a way to run native code in web browsers, wasm has recently expanded to be able to run outside of the browser.
In this post we'll take a closer look at what WebAssembly is and the related technologies around it, and we'll explore what this might mean for one particular use case - functions as a service (FaaS) a.k.a serverless.
WebAssembly is assembly for a virtual machine. I mean 'virtual machine' here in the original sense - a conceptual machine - a machine that only theoretically exists. You can write code for that conceptual machine and a compiler can then compile it to assembly that runs on a real host machine.
The WebAssembly System Interface (WASI) is a specification that allows WebAssembly binaries to talk to the host machine's OS through a well-defined and cross platform interface. This allows WebAssembly binaries to do useful things like write files and open TCP sockets.
Fastly's Lucet, Mozilla's Wasmtime, and wasmer are all compilers that perform ahead-of-time (AOT) compilation through a library called Cranelift to turn the WebAssembly code into native assembly. Lucet and Wasmtime are also runtimes that implement the WASI specification allowing these binaries to talk to the host machine in a uniform, cross-platform way.
Advantages Over Existing Technologies
So what makes this different from existing technologies?
Sanboxing with Fine-grained Permissions
WebAssembly binaries are completely sandboxed, meaning that they only have access to the host machine's resources through WASI.
There are other systems that are also sandboxed at the application level - for instance, node through v8. The difference here is the level of control you have. On one side of the spectrum, v8 is completely sandboxed and does not offer a way to talk to host systems. Node is a way to open up v8 to allow it to take to the host system. Unfortunately, node completely opens up the host system to the application in an uncontrolled and unmanaged way.
WASI and the various runtimes allow for more fine-grained permission. For example, instead of allowing access to the host system's entire file system, a user can grant permissions to only a certain directory. Similar controls exist for networking and other system resources.
This provides a way to run programs where you can control exactly what resources the program is allowed to access.
In addition to this fine-grained sandboxing, the WebAssembly/WASI runtime is very lightweight in terms of overhead. Unlike Docker which also provides fine grained sandboxing, WebAssembly operates at the application level not the OS userland level. This means WebAssembly programs can be started much more quickly and will consume much less resources both on the host system and also when being transported over the wire.
What This Means For FaaS
A completely sandboxed and lightweight environment can allow for more tightly packing serverless applications on the same machine - allowing for serverless providers to lower costs. Additionally, startup times should be much lower (theoretically on the order of 1-2 ms).
Also, WebAssembly is meant to be completely language agnostic so in the future, you should be able to run whatever languages are capable of running in a WebAssembly environment, which could be every language.
This also makes local testing much easier as all the user needs to install is a WebAssembly runtime (a single binary).
Hopefully this gives you a decent overview of what WebAssembly is about at least in the context of helping push FaaS forward.
If you enjoyed this article reach out to me on Twitter and let me know if you'd like me to write more about WebAssembly.
Oldest comments (4)
I'm definitely interested in reading more about WebAssembly. Specially since I read yesterday that Netlify built their Dev Tools with it!
Are there any intro resources that you'd recommend?
This is another good intro
Why the heck is everyone talking about WebAssembly?
and these are great posts on the current state of things:
The other resources listed are great. If you want to write some code, I suggest checking out the Rust toolchain for doing WebAssembly. If you have the Rust toolchain setup you simply need to compile your code with:
cargo +nightly build --target=wasm32-unknown-wasi. You can then use any other compiler/runtimes I listed above to run your code.
WASM is the future of serverless. I wont be surprised if we see offerings from Amazon to run functions on top of wasm runtime. Solves lot of problems like cold start, fast boot up and secure and isolated.
Running on top of container systems like k8s also not that difficult.