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.
So what makes this different from existing technologies?
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.
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.