“WebAssembly runtimes will replace container-based runtimes by 2030”
changelog.com
changelog.com
So I would guess that the future is static linkage with control groups moreso than it is a specific JavaScript/TypeScript software stack running in a specific runtime. Frankly the way we're shipping dependencies in what are basically checksummed tarball blobs is an echo back to static linkage at a time when most OS platforms have gone very deeply down the dynamic linkage rabbit hole to the degree where everyone is shipping dynamic libs instead of statically linking those libs into their executable.
Control Groups are supposed to provide process isolation but are being used to solve this configuration management issue as well because a particular company decided to use chroot in this way.
Docker is basically abusing this system for configuration management and providing some process isolation as a byproduct, because it turns out configuration management is a much more widespread problem than resource control.
With a mount namespace you can pivot root
When I use a container, I get all the stuff a Debian distro brings:
A file system
Process management
My favorite database (SQLite)
My favorite webserver (Apache)
My favorite runtime (CPython)
A gazillion helpful applications and libraries (Like imagemagick)
Tons of convenience glue (like /etc/hosts)
I get all of that in a reproducible, isolated little universe.How does a "WebAssembly runtime" provide me with those?
What wasm people seem to be interested in is to eliminate the process (and hence a language runtime) spawning overhead, and directly execute the specific function of your application..
"Write your serverless function in any wasm compilable language and our multi tenant runtime can host 1000s of such functions and invoke them without much delay"..
Of course, that only makes sense for programs which are written in wasm compilable language. When they do crazy things like running js scripts on top of a quickjs interpreter compiled to wasm to run on top of a wasm interpreter "for portability and safety", it gets weird to see the benefits..
It's basically the same thing as using a language runtime vs using a generic container for Lambda, except WASM would be lower level (you would need to ship language runtime on top of WASM but that's probably order of magnitude less overhead than a container)
Containers feel like a clever hack to get existing apps packaged up and reduce the overhead of VMs, but I'd much rather deploy runtime/app code only.
The way I see it VM -> Containers -> WASM is a logical progression in the same direction from the perspective of deploying applications.
Bare metal, VM, and containers all "look the same", like from a UX perspective. Wasm does not.
Nobody is arguing that WASM today will replace containers - 2030 is a long time away in tech.
WASIX is POSIX :)
That's because that's exactly what they are, and that's why this claim is weird. Containers do not solve the same problem as WASM. No one is going to be taking Postgres and compiling it to WASM. They're not going to do that for redis or memcached or any of the other innumerable services that live happily inside of a container and need low-level access to a Unix system.
We may very well find that WASM replaces containers as to go to for bundling a typical web app, especially one built with a compiled language rather than one that already has a runtime. But we will still use containers for the things that containers are good at.
Overall the timeline doesn't seem implausible to me.
Right now compiling to WASM is sort of the equivalent of "but will it run Doom?" People are doing it for everything, and it's a fun experiment to stretch WASM. I could see it being useful in making some things available in the browser that otherwise couldn't be. But that doesn't mean it's going to replace containers in their rightful place. It'll be another option, and unless you're trying to solve one of the few problems that WASM was designed to solve (like running in the browser), it will be the wrong one.
Realistically containers neither. DBs are infrastructure best left to PaaS or dedicated VMs you can provision/manage better.
These projects care far more about performance than they do about ease of compilation or even of installation, because they're compiled once and run trillions of times in performance sensitive contexts. As I noted in reply to a sibling, I could see it being useful to run in a browser as a sort of learning playground, but that is not how people are going to deal with their production DBs—the bottleneck represented by WASI is not going to be worth it.
Containers just add overhead for stuff like memcached and complicate database management.
Lower overhead.
> clever hack to get existing apps packaged up and reduce the overhead of VMs
Yeah, exactly.
I think the view here is WebAssembly as another architecture. Instead of compiling for x86 or ARM (or both) you just compile to WASM and it can run anywhere.
What does curl do if it cannot talk to a network stack?
What does "touch" do if there is no filesystem to touch?
What does "dd" do if there are no block devices?
Their favorite database (SQLite)
Their favorite webserver (Spin)
Their favorite runtime (CPython)
Hopefully some imagemagic, but definitely none of the linux clutterI can't tell if you're being sarcastic or not.
What would the Python "requests" module do if it has no Linux kernel below it to pass the requests to a network stack?
> What would the Python "requests" module do if it has no Linux kernel below it to pass the requests to a network stack?
Why does requests need a linux kernel? It's cross-platform. Strictly speaking it only needs the appropriate I/O calls. WASI provides a system interface to do I/O, network, files, etc.
https://medium.com/graalvm/whats-new-in-graalvm-languages-16...
You can now distribute Python applications or libraries as standalone binaries or JAR files without any external dependencies. The Truffle framework on which GraalPy is built, and the Sulong LLVM runtime that GraalPy leverages for managed execution of Python’s native extensions, enable virtualization of all filesystem access of Python applications, including those to the standard library and installed packages.
So now you can build a standalone executable as follows:
graalpy -m standalone binary - module my_script.py - output my_binary
or a JAR file that runs on GraalVM and includes GraalPy as follows:
graalpy -m standalone java - output-directory MyJavaApplication - module my_script.py
The first form creates a fast starting native binary. The second is a portable bytecode standalone file. So this WASM dream is delivered already, just by a different group of people.
Now, GraalPy is a different implementation to CPython so not all Python apps run on it yet. But obviously any WASMPy would have the same issue.
I don't know if WASMpy would be a completely different implementation, or just CPython compiled against a WASM target. Probably the latter. Which has already been done.
> I’m not gonna say it’s gonna replace every use case; it’s clearly not. But for certain high-performance latency-sensitive use cases like trying to deliver feature flags globally to mobile apps, or web apps around the world (that is our use case)… it’s definitely very applicable to this problem.
I do think that if WASI gets sockets and threading soon as planned, it suddenly becomes compelling for a bunch of interesting workloads that containers are used for now.
I fail to see how it's applicable. Unless your entire world is Javascript and its performance
So when people say stuff like "high-performance latency-sensitive use cases are applicable to wasm" they clearly only understand performance and latency in comparison to Javascript.
and like there's plenty of people doing wasm on the server where performance is measured in microseconds
According to the website and the core spec it's still the main goal
> there's plenty of people doing wasm on the server where performance is measured in microseconds
I'm old enough to remember when node.js was also marketed as "web scale" and high performance.
1 - The best timeline: WebAssembly keeps its strong capabilities based security model, which requires explicit granting of resources to code inside the sandbox. This is great for security, but it requires giving up full access to the file system, and other I/O... which requires rewrites of things. This will, in turn, mean that many workloads won't shift to WebAssembly
2 - The worst timeline: WebAssembly repeats the mistakes of JVM, and eventually succumbs to the demands to allow full access to all of the resources of the host system, defeating capabilities, and making it a new JVM. Thus, it's not as safe as a VM, why would anyone use it? So, most workloads don't shift to WebAssembly.
[Edit/Append] WebAssembly uses a capabilities model of security. You have to explicitly give it access to resources from code outside of the sandbox, which are then passed (like file handles) to the code running inside the sandbox. This completely and securely prevents the code inside the sandbox from causing any undesired side effects in your system.
Think of it as handing someone $5 cash to make a purchase. You can't lose more than $5, no matter how confused or wrong things go after that point, you've limited the side effects to that $5.
Or think of it as plugging in a device to an outlet with a 15 Amp circuit breaker. No matter what you do, you won't draw 100 amps through the outlet, nor take down the grid (like the power in the old TV show Green Acres).
This is different than "capabilities" on a smartphone, which are "allow location access" or things like that, global, non-granular access to big chunks of your system. There is no "allow access to your file system?" flag in WebAssembly. In the best timeline, there never will be.
Can you unpack that a bit for those of us who don't know this area well? Can't "access to filesystem" be one of the capabilities that can be granted or not granted, thus giving no decrease in security because anyone who wishes to host webassembly without granting it is able to do so?
You can optimize the size of your containers to be pretty small, like tens of megabytes… But WebAssembly is, at its core, designed to be more portable than that.
You’re talking about tens of kilobytes, instead of tens of megabytes. And the boot-up times can be measured in microseconds, instead of milliseconds, or tens of milliseconds, or even seconds (!) for containers.
This paragraph is emblematic: it's mixing up code size, startup time, portability, containers and virtual machines of two different kinds without really linking them together or defining requirements.
The thing is, WASM isn't a new idea. The industry has a lot of experience with VMs that JIT compile portable bytecode. Startup time of any WASM program is going to be dominated by the fact that you're in the interpreter the whole time. As programs get larger they do things like load config files, connect to databases, initialize in-memory caches, possibly reflect themselves because that's often convenient, and so on. Because it's all init code none of this is hot, so it gets interpreted and that's slow. WASM offers nothing in the way of a standard library that could be accelerated, so languages have to bring their own which makes things worse. And the WASM environment is extremely minimalist, so you need to ship a lot of code with your app to make things comfortable especially as most servers aren't written in C++ or Rust and aren't going to be any time soon because that's not their sweet spot.
> As programs get larger they do things like load config files, connect to databases, initialize in-memory caches, possibly reflect themselves because that's often convenient, and so on. Because it's all init code none of this is hot, so it gets interpreted and that's slow.
One of the most interesting aspects of Wasm is that because it is built with isolation in mind, it's really easy to get a snapshot and run it later. So instead of doing all the cache initialization etc. at init time, you can initialize the module at build time and then take a snapshot of it for a very quick cold start next time.
When running in the browser, there is still an initialization step to process the wasm bytecode, but in the server-side world this can also be done in advance since you can trust the compiler and know in advance which processor architecture you will want to run it on.
HotSpot has a less aggressive version of this where you can pre-initialize a lot of VM state and dump it to a file for faster startup time. It's about a 30% win and that's going up over time, but it doesn't AOT compile everything.
Of course, if you're serious about instant startup from zero then you end up going the native-image route, but then what value is WASM adding? What's being shipped to the edge in that case is a compiled binary anyway.
There is some scope here for threading the needle - for example, an edge worker implementation could be given compiled bytecode of some kind and then do the compilation and dumping process server side. This is a bit like how Apple compiled LLVM bitcode itself for delivery. However then the build process needs to be sandboxed and at that point why not go full FaaS and let users upload whatever binaries they like? AWS is doing it successfully.
Exactly. WebAssembly is complementary. Docker has Wasm beta support [0]. See: Announcing Docker+Wasm Technical Preview 2 [1] (Mar 22, 2023)
[0] https://docs.docker.com/desktop/wasm/
[1] https://www.docker.com/blog/announcing-dockerwasm-technical-...
I can't drop in use a Rust module in my Go code, at minimum, I'd need to dip into some kind of FFI.
With WASM, you can just import the WASM module for usage into your language, as long as it supports WASM, regardless of original source. Its a portable format and runtime. That is the key difference than VMs of the past to me at least.
It also makes sharing code that was written in say, C or C++ easier and safer too.
I agree that WASM replacing Docker is something I can't "see" right now, because its just very different, but I do think the highlights above are pretty great.
EDIT: Actually, I think I understand the point of WASM replacing Docker potentially which is, if WASM runtimes support the underlying operating systems sufficiently (like virtualization has to) then you could just compile what would be a container into a WASM module. IE, I could compile Postgres, Redis etc. to WASM (or more importantly, the projects could) and simply use their WASM binaries to support my application. Thats what I think they're going for here. Its hard to "see" it because there are so many unknowns (WASI doesn't have all the features currently needed for this to happen I don't think, for instance)
Note that both the JVM and CLR do try to solve this problem, hence the name Common Language Runtime. WASM actually does far less in this area.
Still, times change. If you want language interop then these days Truffle/Graal is the state of the art to beat. It actually does define both a generic inter-language FFI, but also has a compiler that understands how to compile and inline across that FFI. So in Truffleworld calling a JS function from inside a hot Rust loop isn't actually an insane or stupid thing to do because the whole thing will be compiled and optimized as a single unit, and things like maps/arrays/etc will be properly converted between languages without any data copying.
I'm not even sure Truffle/Graal is doing that across language boundaries (yet).
Of course, in practice, this is basically C, C++ and Rust being used in the web browser or with V8 / Deno, because its the biggest WASM runtime there is right now, but thats changing too, as language communities are starting to seriously consider first party support for WASM.
To address the point of mapping types / data from one language to another: thats the whole point of WASM, is that those languages need to only bind their output to the WASM guidelines. Its all there is to it. Valid WASM will run in any valid WASM runtime
var array = Polyglot.eval("ruby", "[1,2,42,4]")
console.log(array[2]);
Invoking a C/C++/Rust main method from Python: import polyglot
cpart = polyglot.eval(language="llvm", path="polyglot")
cpart.main()
Reading a JS array from C: #include <stdio.h>
#include <graalvm/llvm/polyglot.h>
int main() {
void *array = polyglot_eval("js", "[1,2,42,4]");
int element = polyglot_as_i32(polyglot_get_array_element(array, 2));
printf("%d\n", element);
return element;
}
More examples here: https://www.graalvm.org/latest/reference-manual/polyglot-pro...W.R.T. the "WASM guidelines", can you point us to these guidelines and where they define how to map a Python dict to a Java HashMap, for example? The Truffle Polyglot messaging spec does define how this is done in a way that avoids performance problems because the FFI is expressed in terms of compiler IR. WASM can't even run either of these languages natively so it can't define how they interop with each other.
Big question I have: can I just import (like I'd import anything else in a code base) the dependency and it'll "see" the exposed API surface of the module?
This looks like it does some eval of the underlying code depending on what it is, but it must be explicitly mapped by the consumer (declaring the language and the code), which I respect wholly, but its a little different from the "ease of use" perspective.
That said, its another promising approach, always interested to see how this matures.
To answer the second half of this, its not about defining how Python Dict should map to a Java Hashmap. Its about how Java or Python or whatever language maps to WASM. As long as the produced output is valid WASM, it will work across any boundary that supports WASM. Inherently, it devoids itself from having to think about any specific language this way. Right now this also produces limitations (because features have to be specified uniformly so the target of compilation is the same for everyone)
The inherent flaw of most multi-compat runtime systems, in my opinion, is making the consumer think about the underlying language. Rather, if you use Go to produce a WASM module, it can be used in Rust, or JavaScript, or C / C++ etc. without considering how it was written
You don't technically have to specify the language. The file extension is usually enough to select the right language. I'm not sure how it gets easier, unless you are asking about a sort of polyglot package manager or build system. Indeed there isn't one of those, because they're usually language specific. It would be a good improvement to have though. Right now you'd need to use npm to get JS code, pip to get Python code etc.
With respect to language mappings, I don't think WASM solves this. There is no mapping to WASM of a hashmap because the WASM type system doesn't have any such concept. Could you elaborate on what you're referring to here? As the name implies, it's a kind of assembly language, so it offers no more assistance in this task than ARM or x86 does. Moreover the approach of defining a universal "language" and mapping everything to it was tried and didn't work so great, that's sort of the classical JVM or CLR approach. Languages disagree on how core concepts work. For example a JS array is a very different thing to an array in C, a Java HashMap has a different API and behavior to a Python dict which in turn is different to the same concept in Scheme. You can make some progress by trying to compile everything through to the One True HashMap, but performance and edge cases at the boundaries become problems.
The Truffle insight is to let each language be its own thing. Instead of having One True HashMap (or whatever), you let each language work with its own concepts and memory layouts then define a standard way to export basic operations like "read member", "invoke function", "access key" in the form of compiler IR snippets. So when you invoke polyglot_get_array_element on a Ruby array it's not really doing a function call, and there is no shared array type that every language has to compile to. Instead the function call is replaced with the actual machine code that the Ruby engine would use to look up an array element, and the result is stored in a C void* but it's not a pointer to some unified object concept or even a real pointer at all. That's why you can do something like casting it to a struct of function pointers, and get something that will then directly invoke Ruby methods. The cast operation is also being virtualized. This approach sidesteps the question of how to share stuff between languages without trying to compile it all to a generic meta-language.
The operations are called the "interop protocol" which is a bit confusing because it's not actually a network protocol of any kind. It defines lots of high level mapping operations so you can do things like work with a time/date from a guest language using your host language's time/dat types.
https://www.graalvm.org/truffle/javadoc/com/oracle/truffle/a...
It's important to note here that the exported operations aren't target language specific. Once you implement the interop protocol for a Truffle language it works for every other language, there's no N:N binding work required. So it's a scalable approach.
This all requires a WASM runtime of course, no doubting that. However, the mere fact I can take two languages, compile one to WASM and use that as the module in that other language, is what I'm talking about.
And WASM compat is taking off pretty well so far. I admire Truffle's approach, it might prove to be long term better in solving this problem, because languages can move at the speed they want to move, and the interop story doesn't really change. Where as with WASM, you have to keep up with the WASM specification and runtimes, which could be a headache if not done in a community oriented, deliberate way.
All that is to say, its up the language toolchain to deal with compiling that language to WASM, but once its WASM, its portable
I can write some code or use modules written in JavaScript that compile to WASM. I can use that compiled output with any runtime that can import WASM and expose its interface natively. To that end, I could use it in Rust, no problem.
The same is in reverse. I can write a Rust program, compile to WASM, and use it in JS runtime (lots of projects do this already, actually. esbuild does this with Go as well).
Right Now there are of course limitations, however if current trajectory holds, you'll be able to just import wasm directly into a compat runtime. So I can take the JS to WASM output and share it to any language to can understand it.
This is, as I understand it, the advantage of WASM in the future tense (and if you use JavaScript, its kind of present tense, esp. with import assertions)
Welcome to 2001, .NET CLR.
Welcome to 1988, IBM AS/400 and TIMI.
Welcome to 1980, Amsterdam Compiler Toolkit.
Welcome to ....
The thing WASM has getting for itself is marketing and young generations completly cluessles of the history of bytecode environments since Burroughs Large Systems was introduced in 1961.
and mindshare
Which wasm runtime has more deployments in production than the CLR since 2001?
Its key feature is less friction. WASM is well specified relative to other options, and doesn't rely on one language to be feature compliant, or have any one language in mind for its targeting.
CLR is naturally really tied to C# / F#. The JVM is a bit better in this regard (Kotlin, Java, Clojure, Scala, and I think Julia all leverage this) because it has a better specification for doing this.
I think WASM excels because its specification is much easier to digest and implement for. Writing WASM modules by hand isn't too terribly bad either (its a LISP even!).
WASM also has good marketing and a good place to test it. Every evergreen browser right now can run WASM code. That makes it infinitely easier to test WASM implementations. As WASI becomes more mature, it will also make it easier to develop interop as well.
I think centrally its just the right combination of good specification, ease of implementation relative to the others, and good marketing.
The incompatibility on higher level constructs seems like much more of a bugbear to resolve. - for example, almost all popular high level languages have some idea of garbage collection/reference counting. There's a WASM GC proposal, I'm not sure how can they make it play nice with every languages idea/semantics of garbage collection as many languages place their own particular set of restrictions on GC like interior pointers/pinning/copying etc. some of which might be mutually exclusive.
I could go on, but my point is that I believe there always needs to be an FFI between languages, that is usually barely more expressive than what a protobuf contract/C API would be (and we already have those)
The rest of your comment I agree with, but this isn't really true. One of the advantages of engines/platforms like wasmtime is that they do indeed do AOT compilation and transparently cache JITed modules. Few Wasm runtimes have interpreters. So the fast startup that you get on the Fastly platform is primarily because Wasm modules are precompiled and instantiation has been heavily optimized.
I think overall that Wasm and containers solve mostly orthogonal problems, but there is some overlap in the serverless space. If programs are small and have few dependencies that can be inlined into a Wasm module, Wasm will do well against containers. If you have a very large software stack that has a lot of stuff in the container or base image, Wasm won't be as competitive; at least yet.
A basic use case for moving from containers to WASM is to provide the option for custom backend code for users in a more lightweight way. For example, I have a site that allows procedural image generation via an API and I originally built it using containers. It could be much less resource-intensive and faster startup if I could run that code in web assembly.
Or, I was building a generative AI site that creates custom web applications. In order to allow backend code, I set it up so everyone gets their own fly.io VM/container(s). This is very flexible but not very fast startup time and the smallest option is like 128MB or 256MB RAM which needs to stay loaded otherwise they will have to wait for another restart.
I never really needed to provide arbitrary Linux capabilities, just sandboxed backend code. So if I do something like that again I will try to use web assembly instead. Probably with lightweight TinyGo or Rust-based request handlers or something like that.
For context, I had just returned from KubeCon + CloudNativeCon EU in Amsterdam. I had a chance to talk to many of the great folks pushing the WASM ecosystem forward, and there certainly seemed to be a large amount of momentum behind using WASM in the server space and at the edge. I'd had a great time learning from the folks at various open-source projects / companies pushing WASM forward:
- https://bytecodealliance.org/ (shout out to Bailey)
At DevCycle we are using WASM to help share core Feature Flag decisioning code across our Cloudflare Worker APIs and our server SDKs for local decisioning. We've learned a bunch about compatibility / optimizing performance / limitations that I'm happy to chat about in more detail. But we are generally excited for the future of WASM, especially for the new features coming: Component Model / Threading / Garbage Collection changes / Networking.
If you are looking for how to use WASM Components to replace container-based runtimes, look at the companies linked above.
Indeed, JVM can run everywhere, and has reached far and wide, from SIM cards to huge servers. But it has not replaced all other runtimes, even when it achieved really good GC and and near-native speed thanks to JIT compilation.
WASM is very similar to JVM in many regards. It will reach far and wide, it will supplant a few things, but I bet it's not going to replace too many things, let alone native code in containers.
Then there are the CLR, IBM TIMI and plenty of other ones all the way back to 1961.
WASM was ground-up designed with security in mind (learning from earlier projects like pNaCl). Likewise, WASM was designed with a lot of language targets in mind rather than just Java.
JVM might not be the ideal example of polyglot runtime, yet there are several others of the same vintage, designed with multiple languages in mind, including C and C++, e.g. CLR, TIMI,...
This new thing will address all the shortcomings of WebAssembly, and will be projected to become the standard portable way of running applications by 2040.
The appeal of vx32/NaCL/WASM lies in its bytecode (or verified x86 asm stream), which cannot operate independently due to its lack of access to syscalls or other inter-process communication (IPC). However, a program without syscall access is essentially futile, limited to using the CPU's arithmetic logic unit, reading/writing memory, and potentially handling input/output buffers.
Soon enough, developers will require access to modern amenities offered by OSes such as memory mapping, file descriptors, and async IO. Consequently, OS bridge creators will supply proxies to the kernel, some of which will be improperly implemented. Given their complexity and size, these proxies may essentially become exploitable mini OSes.
There's no perfect sandboxing, some forms appear more trustworthy (or more thoroughly scrutinized by researchers) than others. WASM may seem safer than vx32/NaCL because it lacks bytecode verification issues; the bytecode is fully understood, unlike verifying x86 instructions (which are prone to erratas). However, the bridge/glue/proxy/broker problem remains unavoidable.
From my old cynical curmudgeon viewpoint, this may be a valid approach, but you need to find a way of saying it that doesn’t sound so ridiculous. A wasm SpiderMonkey runtime running inside a native SpiderMonkey runtime? And presumably the inner runtime supports wasm?
WASM runtimes should grow to a maturity level somehow comparable to V8, JVM, .NET runtimes before they start competing with them. Currently WASM accompanies other software, and I find it pretty correct.
https://www.destroyallsoftware.com/talks/the-birth-and-death...
> 2 very fast boot-up time
> 3 scalability at the edge
> 4 much smaller footprints
> 5 portability across environments
Aren't #2-4, just wasm rediscovering static linking?
95% of the advantage that docker has over a tarball is due to gcc's (and glibc's) strong bias towards dynamic linking and how hard it is to portably package a python application's dependencies.
The main thing to watch out for is that the steady state disk usage is different from the worst case. During upgrades the amount of disk used can balloon up for a little while, and these sorts of transient costs tend to mess with people’s ability to do capacity planning properly.
So there’s a law of diminishing returns for pushing things out of your images into a common base. The more you do the larger the over/under gets. Spend a good bit of energy in shrinking the base image, not just growing it, and you’ll be okay.
To be clear this is a great idea and will solve a lot of problems, but it's not like people haven't thought of this before today.
N wasm operations to guard rather than N syscalls.
The cloudflare worker infrastructure is very cost effective. The thing that I wonder about portability is side channel defense mechanism responsibility.
WASM came out of the web and is needed/wanted by the web folks because they can't rely entirely on operating system kernel sandboxing (Windows is dubious, macOS is powerful but private/undocumented API), and because they don't like the idea of implicitly incorporating every possible device's CPU ISA into the HTML5 spec. Neither issue applies on Linux servers where nothing is a formal spec anyway and the Linux sandboxing facilities are powerful and open.
JIT/interpretation can only slow things down over using native code, so "fast startup" is probably being confounded by the fact that WASM programs tend to be written in C++ or Rust.
> 95% of the advantage that docker has over a tarball is due to gcc's (and glibc's) strong bias towards dynamic linking and how hard it is to portably package a python application's dependencies.
Mhm. docker, flatpak, snap, appimages .. so much complexity is basically us dealing with linux dll hell imo.
But that WASM might enable intensive applications (e.g. cutting edge games, or 3D rendering software like an architect might use) to run in the browser, rather than on the OS, thus enabling developers of that software to make much more frequent updates (just like any web application)?
What would this mean for page load times (e.g. surely not a 700MB program downloading when the user visits a URL..?.. or.. can it?)
(apologise for the newbie questions)
I can write code once and run on many runtimes across many different programming languages.
I think the server use-cases are actually more compelling than the browser use-cases.
For example, Fastly's edge compute supports running WASM code at the edge. Similar to lambda, but in the language of your choice and with great sandboxing qualities baked in.
WASM probably won't enable cutting edge games. It has been around for years and there's no interest from the gaming community there, the newest additions to WASM like GC won't affect games much. There are other issues with the web platform that prevent this from working, e.g. the implicitly managed disk cache, the relatively old graphics APIs exposed into the sandbox, the performance impact of sandboxing, and a few other things. The games world has Steam and consoles, that seems to be good enough for them.
There might be some attempts to port desktop productivity software to the web using WASM, probably in partnership with Google, like what an architect might use. But probably not. Installing software isn't hard and pro grade software isn't an impulse buy. How much incremental revenue would a web port bring relative to the cost? Probably not much.
700mb programs downloading when a user visits a URL isn't necessarily a problem if that download actually sticks, but see caching issues above. After all, people routinely download programs that large. Chrome itself is ~500mb on disk!
Behind the clickbait headline, a much narrower and reasonable claim.
It's been tough to get _truly_ unpopular opinions (as voted on by Twitter/Mastodon users) represented on the pods.
The thing is: Docker or Podman is just the runtime coordinated and controlled by Kubernetes or Nomad in our case. Nomad practically already supports a hypothetical WASM runtime or offers simple hooks into this: You have e.g. a java driver in Nomad, which downloads a fat jar from an artifact store, cgroups it as far as I know and launches it with one of the available JVMs. There's a bunch of these drivers, even down to IIS pools.
Some generic WASM runtime would slot right in there.
However, we don't use them. Once you use them, you're again coupling the application runtime to OS updates and management. Staying in the Java example, currently teams are entirely free to use whatever Java version they want. If they want to update multiple times per year to the latest versions - entirely feasible for tight services with low technical debt and good tests - they can do so. As soon as the JVM becomes part of the OS configuration again through the Java driver, us as in infra-ops are immediately blocking all Java updates across the entire infrastructure again. And on top of that, we have a team providing base Java images with a jvm baked in, so most nomad workers pull the JVM layer once after it's released and then the layer is cached locally forever until no application needs it anymore. So it's not much more storage-expensive than putting the JVM on the disk directly.
But that's the smaller part of the problem. Nomad isn't just the driver runtime. I can tell Nomad to run 5 instances of an application and to spread them across AWS regions, or VSphere HVs / Racks as well as possible. And Nomad will implement and maintain this, almost regardless of what the infrastructure does. I can drain workers and shift applications around without really knowing them, since this management is configured in the jobs.
Again - this decoupling of OS and infrastructure management and application management makes a container orchestration valuable at a larger scale. The runtime below it is an important detail, but it's a detail for average REST service deployments. A WASM runtime may slot in as being faster and more cost efficient or it may not. Who knows.
https://developer.okta.com/blog/2022/01/28/webassembly-on-ku...
- System calls call into the Linux kernel for things like disk and network access. These are highly tested and reliable.
To keep WASMs isolation and portability it would need to replace these APIs with new message passing ones which would kill performance.
- C FFI
- Dynamic libs
Being able to integrate with existing C libraries in the way they are intended to be used.
- Better VMs/OS level sandboxing
MicroVMs like Firecracker that let you run your code unmodified as if it is running directly on the OS.
I like WASM, but feel it is over hyped and the alternatives are “good enough” and already widely used.
In the browser it is great though.
Title is clickbait anyway, and such blatant and Shameless clickbait at that.
> Click here to listen along while you read. It's better!
How could it possibly be better to listen to some people talking thus distracting you while you're reading?
wasm is orders of magnitude faster -- actually comparable to native execution, at least on the server
I would like serverless or at least rapid booting GPU functions...
Are we perhaps over-utilizing web browsers?
The article itself is talking about server runtimes/workloads, nothing to do with browsers.
If generic specs can be built around WASM in such a way that you can run code securely without booting an entire OS, WASM will replace traditional containers. Smaller runtime footprint.
A consequence of having a generic compile target/spec is that your applications will also be able to run in the browser with minimal effort
What about it is preferable to MLIR or even LLVM?
LLVM doesn't provide that to my knowledge... instead just cross-compiling code specific to each target. Correct me if mistaken.
I imagine there are meaningful build time drawbacks to compiling an executable for each environment as well. While WASM will never outperform native code, it can get very close. Minor loss in performance is a small price to pay for portability/security.
If that is the case, why was a new standard necessary vs. bytecode from JVM or CLR, for instance?
the main difference distills down to execution/implementation
java applets were slow, wasm is fast
that distinction makes a categorical difference
I guess I'm wondering what makes WASM so much better than investing engineering energies into existing things.
if you're deploying wasm to the browser, then native means your JS engine
if you're deploying wasm to the server, then native means actual machine code
the competitive advantage versus java is (at a very high level) the language design -- java is much higher-level than wasm, which limits its potential
These days you are not required to have a JRE or .NET runtime installed. At least on the JRE side, it can be embedded in the executable - I assume .NET has something similar.
There has to be more to it than that, though. Perhaps it is the "easy" part you mentioned - I have no idea what's involved in building a greenfield java bytecode interpreter, for example.
I guess that brings me back to my original question - why WASM vs. some existing bytecode interpreter? What makes WASM the best choice, and why does it exist?
those properties are important
Browser vendors agreed that they could standardise something lower level than JavaScript, in the browser, and is is the chosen outcome. Why _not_ make something new? There is experience doing it, so it's possible, is a known engineering task, and it can be built to the specific requirements. And by making a new one, you don't have to buy into someone else's brand or ecosystem.
The rest is historical details.
Ultimately, asking strangers on the internet to justify software architecture design decisions that happened years ago and worked out rather well, is for the birds.
In future the question is going to be less "why use WASM when JVM is right there, one install away", and more "why use JVM when WASM is right there, zero installs away" .
JVM bytecode is open, standardized and quite easy to implement. CLR bytecode likewise albeit less easy to implement. You can implement a simple JVM on your own. Avian is an example of a lightweight JVM written by two guys (albeit very productive guys) and that didn't only implement the spec but had a proper JIT compiler, AOT compiler and semi-decent garbage collector too! In practice, ease of implementation isn't very important for this sort of thing. Having a good open source implementation is sufficient. WASM has this in V8 and other than the rewrite-it-in-rust factor it's not super clear (to me?) what other runtimes bring to the table?
> Because of this simplicity it is also an easy target to compile to
No, this is backwards. WASM's simplicity makes it harder to compile to, not easier, because language implementations have to do more themselves. That's why even after many years the only languages people are using with it are languages with very minimal demands on the runtime, like C or Rust. Languages with more advanced compilation requirements like GC integration (modern GC algos affect the compiler too) have been ignoring WASM so far, and this is why V8's JavaScript engine isn't itself running on WASM.
Also it seems to solve a different problem, yes some thing containers are useful for Webassemtly might be really useful for.
But a lot of other things I just don't see it. Will I run databases compiled to webassembly?
That said I really think Webassembly is cool and like many of the ideas. Will listen to this podcast, lets hope I am convinced.
Edit: Good title marketing