PurePerformance - Is it the time for WebAssembly (Wasm) to take off with Matt Butcher
Episode Date: July 15, 2024WebAssembly runs in every browser, provides secure and fast code execution from any language, runs across multiple platforms and has a very small binary footprint. It's adopted by several of the big w...eb-based SaaS solutions we use on a daily basis. But where did WebAssembly come from? What problems does it try to solve? Has it reached critical adoption? And how about observing code that gets executed in browsers, servers or embedded devices?To answer all those questions we invited Matt Butcher, CEO at Fermyon, who explains the history, current implementation status, limitations and opportunities that WebAssembly provides.Further links we disucssedLinkedIn Profile: https://www.linkedin.com/in/mattbutcher/Fermyon Dev Website: https://developer.fermyon.com/ The New Stack Blog with Matt: https://thenewstack.io/webassembly-and-kubernetes-go-better-together-matt-butcher/Â
Transcript
Discussion (0)
It's time for Pure Performance!
Get your stopwatches ready, it's time for Pure Performance with Andy Grab welcome to another episode of Pure Performance.
My name is Brian Wilson and as always I have with me my amazing co-host Andy Grabner.
How are you doing Andy?
Good, good, good. That's an exciting day today. Do you know why?
No.
No, because obviously you're not following the Euro Cup
because at the time of the recording, we're only one hour away of the most important match in Austrian football, or as you call it, your soccer history, because we need to at least score one point against Holland.
If we do that, we make it to the next round, and it's going to be exciting.
Yeah, I thought football season was over, but that was back in February. No, I'm kidding. It was really interesting, Andy.
I don't know why, but for some reason yesterday
I thought, I'm going to turn on the FM radio. I don't know
who listens to FM radio anymore, but I was turning down the dial
and I found a brand new station that was playing all of some amazing songs.
I don't know if you've ever heard of it.
It was WASM.
It was a pretty cool radio station, I've got to say.
Have you ever heard of that one before?
No, but WASM, that sounds very closely familiar to something else,
but not on radio.
I don't know.
Oh, no.
Anyway, there was a long-distance dedication sent out to you.
It was Rock Me Amadeus, somebody sent out for you.
Anyway, it was a cool station, so I wanted to share it with you.
And, yeah, that's the only story I've got today.
Yeah, it's an interesting old intro.
But, yeah, maybe now time actually to WASM, or W-A-S-M, as you call it, WASM, WebAssembly, the topic of today.
And neither Brian and I have any clue about it.
Well, a little bit maybe, but not much.
No, no.
Not a radio station, but actually a little more about it.
We invited Matt Butcher.
He is not a butcher, but he has an awesome last name.
But he's going to help us, hopefully, learning more about WASM.
Matt, thank you so much for
joining the show. Sorry for all the initial
trying to be funny episode.
Thanks for having me. And I'm
pretty sure that the first song you heard,
Brian, on that news station is
everything is awesome.
Everything is cool.
Hey, there you go.
That's a great one.
And now that I have a song,
the show's already over, right?
Yes.
Yeah, we lost
two of our three listeners already.
Thank you.
Hey, Matt, in all seriousness,
I'm looking at your LinkedIn
profile, and I always thought
I'm contributing quite a bit
to open source, but if I read yours, I'm a founding quite a bit to open source.
But if I read yours, I'm a founding member of dozens of open source projects, including Helm, CNAP, CrossFed, Brigade, Open Application Model, Glide.
The list goes on and on.
You have published several books.
What have you not done?
Well, up until just recently, it was seeing on a show.
But now that I've knocked that one off, I think we're...
Yeah, I got started in open source.
I'm one of those really fortunate individuals that even my very first job in high school in the 90s, I was working on open source projects.
And so I have had a long time to do dozens of projects.
So I might have underdone it.
But yeah, I've been involved in a whole bunch of communities over time, including,
you know, the PHP community and the Drupal world OpenStack, and then the Docker and
Container and Kubernetes ecosystem. And these days, it's the WebAssembly ecosystem.
So what is WebAssembly for those that have never heard WebAssembly? Can you quickly highlight, A, why this is a technology?
What's the problem that this technology tries to solve? Why should people be aware
of it if they're not yet aware of it? So WebAssembly is
a technology that, like many other really great technologies, sort of
outgrew its original purpose. So back in 2015,
a group of developers from Mozilla sort of rallied
a group of developers, a bunch of browser developers from all the major browser companies.
So some people on the Safari team, some people on the Chrome team, some people on what at the
time was the IE Edge team, to all work together to solve a problem that we've taken several runs
at before, but to try it in a
slightly nuanced way. So, you know, like I said, I got started in the 90s when dinosaurs roamed the
earth and, you know, Netscape Communicator was the cool browser and all of that. And, you know,
there were a couple of languages that looked like they were going to be the browser language of
choice at the time. And the first one was Java, right? Java was supposed to run in applets in the browser,
but they needed sort of a glue layer to help Java, you know, you know, bind itself to the
browser objects and things like that. And so, you know, Brendan Eich at Netscape created what
was originally called LiveScript and later was renamed JavaScript.
And those were the kind of the two big languages.
Then for a while, there was VBScript, right?
They were all kind of contending for browser dominance, right?
And Java had this cool technique that the scripting languages did not have.
And that was that you could write the code on anything from a Solaris workstation to a Windows 95 workstation or all the different things that were fancy at the time.
But you could compile them to a single bytecode format, the Java bytecode format, and run it in any of the different browsers that were out there at the time, all two of them.
And, you know, it was the first real attempt to run a bytecode language inside the browser.
And as we all know, it did not succeed.
Part of that was because it was a commercial offering.
Part of that is because it was really slow.
Part of that is because Java itself was an immature language. But it did not detour people from trying different ways of doing this.
So Silverlight came along, Flash came along, a variety of other answers came along.
But each one sort of stumbled and fell, often based on the fact that they were proprietary, right?
Only one browser supported it, or the language itself wasn't open source or whatever.
So in 2015, as this consortium of developers from all the browser makers get together, they said, we want to take another run at this.
But we want to be a lot more modest in the way we approach the problem.
Instead of trying to build a sort of soup to nuts solution that handles everything from a language and a bytecode format all the way up through the windowing toolkits and all the things that these other animations and all these top level things that Adobe and Microsoft had tried in the past.
Let's just solve one problem.
Let's create a bytecode format that can be cross-platform and cross-architecture and run
well in the browser, like really fast in the browser. And if we can just solve that, we'll
let other languages, existing languages, compile to that format, and we'll let other people solve
the higher-order problems. And so that was really where WebAssembly was born. And if you sort of
look at the features that you would need to do that well, you see maybe four different things.
The first one is you want a really good security sandbox. You want to protect the browser from
opaque binaries that are going to get downloaded off the internet and executed on your machine.
You actually want to protect your JavaScript sandbox even so that something gnarly that
happens inside the WebAssembly runtime doesn't slow down your JavaScript and slow down the
browser and everything. So it needs to have a really good security sandbox, needs to be really,
really fast to execute because we all know we are not patient when it comes to websites loading.
It needs to be cross-platform and cross-architecture,
because as we know from the browser world,
it needs to run on everything from Raspberry Pi to Supercluster to the refrigerator,
anything that you can shove a browser into.
And it needs to have smaller binary sizes,
because you're moving these things around the network.
And so those were some of the big design goals for WebAs uh and you know as a technology it took off pretty well you see it
used in um office the online version of office you see it used in figma uh you see it used in a
variety of places where either old libraries the office case an old library that was written in c
is compiled to web assembly and dropped into Excel so that nobody has to rewrite that old gnarly C code in JavaScript.
Or you see cases like Figma where in order to get high-performance vector graphics, they wrote their core libraries in C++, compiled them to WebAssembly, and put them in the browser.
So that's kind of the heritage of WebAssembly as a browser technology. But what excites me is that that particular technology has had a lot of room to grow
and has actually shown up in a variety of surprising places,
including kind of the way that Fermion uses it.
So that means today, help me,
I'm here sitting in front of my laptop,
I'm running a Chrome browser.
That means I have a wasn't runtime in my browser.
Yep, yep.
Every major browser currently supports the WebAssembly 1.0 final version of the spec.
WebAssembly, by the way, is standardized.
And it's standardized by W3, the same standards body that does HTML and CSS.
So it is considered a core web standard, thus pretty uniform adoption across all of the web browsers.
Where, on which runtimes and which devices, maybe, would you love to see, Wes?
You thought it should be there already, but maybe the adoption is not there,
though somebody didn't port it over.
What are people asking for?
Well, and this is where it gets interesting, because as a browser technology,
it's kind of landed in all the major browsers, right?
But as a runtime technology, there's no reason you couldn't take something like WebAssembly out of the browser and run it in different environments. In fact, that's what we do, right?
We kind of pulled the WebAssembly runtime out of the browser and built a server-side runtime.
And on that side, then, it's getting really interesting,
and I'm excited to see this happen, right?
It's getting really interesting to watch it show up in embedded devices
and in gigantic server farms, right?
We have been playing around with this Ampere 256-core onboard
and trying to get a WebAssembly
mega interpreter that runs across all
256 cores, right?
But you also see it down to sort of small
form factors of devices. So what
we're seeing it now, and what's exciting
is some of the more exotic
like RTOS and small embedded
operating systems that are starting to get support. But I'm
looking forward to seeing that kind of come
to fruition
over the next few years.
There are some good starts to that.
But of course, as you know, there are a lot of embedded devices
and a lot of different pieces of hardware and small operating systems
that it needs to be ported to yet.
So then, also, I know these are all probably basic questions for you, but for the benefit of me and Brian and the listeners that have not yet had the time to look and dive into Wasm,
then what type of applications are people building?
Is it serverless applications?
Because I hear a lot of Wasm talk around serverless, like you're building lightweight functions. functions? Is this kind of like the standard that would replace some of the more specific offers
that the cloud vendors offer, like a Lambda, Azure functions, Google functions? Is this what
people are trying to do? Like, use it as a standard to build serverless apps? Or what else
are people doing with it? Yeah, absolutely. I mean, we've kind of seen four distinct areas where web assembly is
gaining traction the browser we already talked about uh we are starting to see embedded use
cases for web assembly bbc and amazon and a few others you know they're embedded streaming players
that you're probably watching on your roku or your apple tv or whatever uh those use web assembly uh
they they actually you can write a very small shim that binds your hardware to here
and your WebAssembly runtime to the application,
and then you can run the same application code in a wide variety of devices.
That's a great story for cases like that.
We're seeing some of it used in plug-in architectures and databases,
but the one you pointed out is the one that I'm most excited about,
and that's cloud.
And to jump right in to that one, as I told you,
I got started in OpenStack.
And OpenStack, when I was first beginning to work on it,
OpenStack was entirely based on the virtual machine world.
The containers were not really a thing at that point.
So we had containers, networking, storage,
I mean, virtual machines, networking storage. And, you know, what we saw happening then, and this is,
you know, rewind 10 years, 12 years from now, right? What we saw happening then was this sort
of breakdown of the one-to-one relationship between a piece of hardware and an operating
system, right? You could suddenly, you went from installing one operating system on one piece of hardware to suddenly having one piece
of hardware with, you know, potentially dozens or more virtual machines on it. And that was a
really exciting time. But, you know, you are talking about packaging an entire operating
system up and running it in an environment. So some of the early projects I did using virtual machines, we were writing an application
that was two meg.
We were packaging it up into a six gig Linux image and shipping it up to Amazon to run
it for us.
And at one point, you're kind of going, this virtual machine thing is cool, but that's
an awfully big image and an awful lot of data shuttling.
It took us three and a half hours to deploy our end copy cluster of this app.
That's an awful lot of space and time for a two-meg app.
So the virtual machine world was definitely solving problems.
It actually continues to be sort of like the battleship of the cloud world.
But when containers came along, we had a second option, right?
If you're working on long-running processes,
you can package them inside of a container instead of in a virtual machine.
And instead of talking about gigs and gigs,
you're talking about maybe hundreds of megabytes
or even tens of megabytes of data.
And so, you know, suddenly this two-meg app is only a 20,
instead of being a six-gig app when it's all packaged up as a virtual machine was only, you know, I think at that time it was probably about 40 or 50 meg because we were using the Debian slim version.
So we had, you know, two solutions there.
We had the virtual machine solution.
We had the container solution. And for long-running processes, you know, we were starting to see databases and the kind of burly things that need to run for a long period of time sort of land on virtual machines.
And then for a while, it was the microservices that were landing on containers.
And things have matured and lines have blurred over time, but that's the way it was sort of when Kubernetes was new.
Then Amazon came up with this interesting idea that was, you know, we got all this excess compute.
Wouldn't it be cool if we could schedule this compute to be used for only little time slices instead of, you know, long-running virtual machines?
And they built Lambda basically in order to consume the excess compute.
And the original idea for it was like, this is for utility computing.
If you need to respond to an event here and shove something over there and time doesn't matter and length of execution doesn't really matter, Lambda was a great solution.
And, of course, Lambda really took off.
I think a couple of years ago when I was at reInvent, they said they execute one trillion, with a T, Lambda requests per month.
And so that's one trillion runtimes that got started, handled a request, and shut down in one month. And so that's one trillion run times that got started, handled a request, and shut down in
one month. Far, far beyond, I think, what the original scale was they intended. And part of
this would be because the serverless, the method of writing serverless functions is just so easy,
right? Instead of writing a long-running server that's hundreds or thousands or hundreds of
thousands of lines of code, you're just writing an event handler, right?
And it takes a request, it does something, returns a response, and shuts down.
Eventually, right? I mean, that's exactly what, I mean, in the end,
this big thing that you just talked about is just handling individual events
that are coming in as requests.
So in the end, it's a perfect fit for Lambda, right?
Handling individual requests.
Yeah, exactly, yeah. And so, you know, by this point in for Lambda, right? Yeah, exactly. Yeah.
And so, you know, I was at, by this point in my career, right, I was at Microsoft.
And so I'd gone from, you know, HP working on OpenStack on into Microsoft working on
Kubernetes and containers.
And, you know, we were looking at the way that Azure functions, you know, Azure's competitor
to Lambda was running and going, wow, this is kind of, kind wasteful, actually, because you're spinning up an entire virtual machine. In fact, you are spinning
up thousands of virtual machines, queuing them up so that when a request came in for an Azure
function, a virtual machine would get slated to handle that, the code would get dropped on that
virtual machine, executed, the request would be handled, and then the entire virtual machine is
torn down,
and a new one is spun up and pushed on the end of the queue. And the reason you do this is because you need this high degree of security. And frankly, they didn't have a technology at the
time that could handle it. I learned that actually that particular design pattern was exactly the way
Lambda was implemented too. So you have these huge queues of virtual machines. And because so much work has to be done real time,
that last possible instant,
the cold start times for serverless functions
were in the 200, 500, 700, 900 millisecond range.
Any of y'all who are browser developers
hear these numbers and go,
oh, that's cringeworthy, right?
Because Google starts dinging you on your search results at around 100 milliseconds. So if you're not returning data
in the first 100 milliseconds, then it's starting to harm your SEO. When you're not even cold
starting for 200 to 500 milliseconds, you're never going to be able to build a really high
performance website. Likewise, you're not able to build high performance job handlers, scheduled
workloads, things like that. You're always taking a delay at the beginning. So here we are at
Microsoft looking at this problem and trying every which way to figure out how to solve it. We were
trying it with containers, we played around with unikernels, we were playing around with all kinds
of things. And we went, maybe the way we're thinking about this is all wrong, right? We're kind of entrenched in this heritage of virtual machines and containers being the two classes of cloud compute.
And everything else in cloud compute being built on those two abstractions.
What if there's a third kind of cloud compute that had all the properties of a good cloud runtime, right?
Security, portability, all that kind of stuff. But in addition to that,
was just highly optimized for lightweight workloads that would run in this kind of
serverless paradigm. And that's actually what got us looking at WebAssembly. So we really were
looking everywhere and went and said, oh, this thing that was built for the browser,
this actually pairs perfectly. This checks off all the checkboxes for what we're trying to accomplish on the server.
And so we started building a cloud-side runtime
for serverless applications.
And really, that's where Fermion was born, right?
We saw a need, we saw a big challenge,
and we found a potential solution for that
and have just been spending our last three years
kind of developing both the developer tools for that and the cloud runtime for that and have just been spending our last three years kind of developing both the developer tools for that and and the cloud runtime for that so that means huge uh resource
gains and uh and efficiency gains on the operating side of all this right because as you said
like it's crazy to think about that for every request you have to spin up and then tear down
a full vm um yeah yeah and uh it's just like a lot. And I just like
the example that you brought earlier for
a couple of hundred lines of code, you need to package
everything up into a big, either
multi-gigabyte image
or even in a container. And that's just a
complete waste of time and
waste of resources.
So that
means, are there any limitations?
Like if I think about building this, are there any limitations? Like if I think about building this,
are there any limitations I have to be aware of
when I want to build something?
So is there anything where you say
WebAssembly is not the right thing?
You still need to go with the container
or with whatever other serverless framework?
Yeah, and I'll give you two.
There are two kind of big ones.
The small one and then the double extra
large one. So the small one is
as WebAssembly
does not handle multi-threading and there
are a few other features like that that WebAssembly does
not provide yet. It's coming.
It's in the works with specifications
and things like that. There's actually
the work that goes into building
a multi-threaded runtime for
lots and lots of programming languages
is intense and in particular when you have to share threads across instances of a web assembly
runtime but the work is all coming along very well uh there's an asynchronous runtime implementation
that's coming out soon but there are a couple of things like that right networking has been a
little bit slower uh low-level networking high high-level networking like HTTP, piece of cake. Low-level networking, much, much harder. And so there are
some features like that that are still working their way through specifications. And the workaround
so far has been that the runtimes will provide sort of a native, not WebAssembly implementation
of some of these things and expose those to developers so that they can keep working.
But that does mean that, you know, some off-the-shelf libraries don't work as expected.
Any language that heavily uses threading libraries underneath the hood,
you end up doing either some library rewriting or some picking and choosing.
So that's one.
WebAssembly's biggest liability from day one
has always been the rather audacious expectation by the original WebAssembly developers that if they build it, everybody else in all the different language communities will suddenly say,
hey, we'll write a C to WebAssembly compiler, we'll write a Rust to WebAssembly compiler, we'll write a Python WebAssembly runtime. And so its biggest risk has always been that it wouldn't be able to handle
the major programming languages, if not all the programming languages.
And that one's big, right?
Because again, just to be crystal clear on what the expectation here is,
you write a specification that says,
if you can compile it to this bytecode language we can
execute it but you leave it to every language community to say this is how we get from our
python source code to a to a web assembly binder from our dot net run uh you know assembly to the
to web assembly and the remarkable thing is that uh right now we seem to have kind of hit the kind of critical mass,
and we are seeing language after language
starting to add support.
So C and Rust were very, very early.
You know, Rust, I think, is sort of like
what Go was to the Kubernetes ecosystem,
where Docker and Kubernetes were written in Go,
so seemingly everything was written in Go.
Rust is kind of like that for the WebAssembly ecosystem.
The kind of core reference implementations were written in Rust,
and consequently you see a lot of Rust.
You see Rust as kind of the dominant language in the ecosystem.
So you saw a couple go early.
But then, kind of like dominoes, things started to fall,
and you started to see Python, and then Ruby, and and JavaScript and some of the interpreted languages built
so that their interpreter could compile into WebAssembly and then, you know, go from there
even farther beyond that.
.NET,.NET 9 has support for WebAssembly in it right now.
And it's due out, I believe, November of this year.
But we've already been working with the.NET team piloting their stuff inside of Spin.
And it's really cool.
So there you're seeing a bytecode language.
So the first wave languages, right, C and Rust,
were basically compile-it-to-native kinds of languages,
and they moved fairly quickly.
Then you saw some interpreted languages go,
and now you're seeing some bytecode languages go.
And that pretty much runs the gamut
of the different language types,
and then we're seeing language after language get support.
So Zig had it fairly early.
Swift now has it.
And I think kind of the big laggard in this world is Java.
The Java community has somewhat, I wouldn't say stagnated,
but they're in a rut.
They have a way of doing things,
and they have not been as flexible or as
quick to adapt as technology has changed, right? It was hard to put Java in containers. Now it's
hard to get Java in WebAssembly. So, you know, hopefully that one will move. And I think Java
is the last big language. So, yeah, you know, going back to your question, you kind of have
two things going on here. On the one side, you've got this audacious requirement that lots of languages will move. And then on the other side, you've got sort
of like core operating system constructs like threads or like low-level networking sockets
that were not part of the original WebAssembly specification, which was designed to run in the
browser, but are part of the current draft specifications that are on their way through
standards bodies. And in the interim, until those land, it makes a certain class of application hard to write.
And that, by the way, is how we ended up at serverless, right?
We started with serverless, right?
We were looking for a runtime that could do serverless really well.
And one of the things we were totally willing to give up in a serverless environment was
threading.
Because if your thing is going to handle a single event to completion
and then shut itself down, the cases where you need threads
tend to be fairly rare, right?
You really take an event, handle it, send a response.
I mean, I was a PHP developer for many, many years.
We didn't have threads.
We were happy with it, you know?
We just wrote web pages.
And I think WebAssembly is kind of in that,
you can sort of mentally categorize it
in that family of language
or that family of feature sets right now, right?
Great for single-threaded things,
nearly impossible to do with multi-threaded things for now.
And probably it'll be another year or so
before you see the really great threading support in it.
Yeah.
From an observability perspective,
because that's the area where Brian and I
obviously spend most of our time,
is there anything built into the runtime,
into the specs of the runtime,
to make it observable?
Because I think that's obviously critical.
And also, thinking about how lightweight it is,
we would hope and assume that
observability is very lightweight and following
standards like, I don't know, is it exposing
open telemetry? What's happening on
observability sites?
Fermion is building a developer tool
called Spin. And Spin
is kind of the tool to help a developer go from
blinking cursor to deployed
application, right? All those steps along that process. And then there's a spin runtime that's the
serverless WebAssembly runtime. And so really, in both cases, as we built
this, we've asked that same question. How do we make what's happening in the WebAssembly
visible to the developers on one side and visible to the operations team on the other?
So I'm going to start at the high level and go down, because what's there today
is Table 6, right?
OTELs, sort of open telemetry support, standard observability of the sandbox environment that you're running in.
All of that is fairly easy to add right away.
This is one of the nice things about the way WebAssembly works. You have a single runtime, unlike Docker, where underneath the hood, Docker is sort of an assemblage of different pieces and parts of core Linux operating system. And it just sort of
orchestrates the setting up of cgroups and sharing the kernel and all of those kinds of things.
WebAssembly, all the code is running inside of a single runtime. So you have one runtime that you
can instrument and say, you know, spit out telemetry about how much memory is being used, how much CPU is being used, you know, that kind of thing. But there's, you know, if we
are to look a level deeper, right, if we're starting to go down into what's happening,
in the virtual machine world, the runtime was handling the lowest level of instructions,
right, machine level instructions. And they were And they're basically opaque to the runtime as to
what's actually happening. You'd have to reconstruct so much context to see what's
actually executing in a virtual machine that, frankly, as far as I know, nobody but probably
government-level hackers have ever even tried doing these kinds of things, right? You just assume
you'll have to instrument inside the virtual machine. Containers are actually fairly similar.
What's running inside is relatively opaque to the runtime outside. You might know process IDs,
you might know some of the memory details, but that's about it. If you want to see what's
happening inside the application, you go to the developer and say, hey, can you instrument your
application? Can you add some stuff in here that emits events? Web assembly is the opposite
end of this spectrum, right? You're getting the languages bytecodes, and you're getting it in the
form of instructions, the instructions that are happening inside of the program. So you can
actually observe a web assembly and say, this function was just called. Now this function is
just called. Okay, this function seems to have been called about 60,000 times in a row. You might
have a recursion problem, right?
Or something like that.
And so you can actually instrument externally the WebAssembly binary.
Now, it comes at a cost, of course.
Anytime you're observing anything, you're imposing a performance penalty.
But where we think we're going with WebAssembly would be sort of like a utopian world for operators, right? Where
something's going wrong and you go to your dashboard and say, okay, turn on deep tracing
on this particular instance of this application. And it starts spitting that out and you bundle
it up and send it to the developers and say, what's going on in production, right? And give them the tracing output without,
you know, I came from the sort of,
ran a major website
and we used New Relic to instrument our code.
And we would end up in those cases
where something would go wrong in production
and the ops team would call us and say,
hey, something's wrong
on this particular part of the site.
And we'd go in and dump new relic function calls
all the way through the stack
and then ship a new binary to them.
And they would run it.
And if they could reproduce the problem,
then we'd get the trace information back out.
We couldn't log into production.
It was against the rules.
They couldn't do anything to turn on instrumenting on their own.
We see WebAssembly as maybe getting us past that, right? Where the operations team could say something's going badly now, let's see what
it is, turn on the switch, record some stuff, turn off the switch, ship it to the developers
and start to reconstruct and let them start to reconstruct what's going on. That I think will
be a leap forward as far as how we can do observability in the future. So today, you know, very much Web
Assembly is in the table stakes world of being able to do all the kinds of things that we've
worked on in the container and, well, in the cloud native ecosystem as a whole, right? But I think
tomorrow it may be even more promising. Just one clarifying question. Thank you so much for all the
insights. But I just want to clarify, if I understand this correctly,
are you suggesting when we want to instrument code, that we are actually instrumenting the bytecode
and basically make the bytecode then emit telemetry data? Or do you see this more
in the responsibility of the actual runtime and therefore pushing it to the runtime developers on the individual operating
systems to emit the code. I wasn't clear on that. Yeah, I think it will end up being in the Web
Assembly runtime that you would have to say, allow the user to give me a function and then I will be
able to emit the tracing for that particular function. I mean, that's the way we have approached
it. And there's sort of like, yeah, there's sort of like some standard runtimes out there that work
on a variety of operating systems. We work, we run the actual WebAssembly interpreter, the actual
WebAssembly runtime that we use is called WasmTime and is created. It's sort of a reference
implementation of the WebAssembly plus WASI
specific. We haven't talked about WASI much. We should talk about that in a little bit. But
it's a reference implementation. And so we figure if instrumentation makes its way into that level
of software, then you'll start to see it really kind of crop up everywhere. But you should be
able to do this without recompiling or redeploying
or anything, because really all you're saying
is, hey, I know there's a function in there
called execfoo.
Tell me what execfoo is doing right now.
Oh, that's not it. What about execbar?
Oh, there we go. You know, that kind of thing.
And that also means
the bytecode standard
that still has the concept of functions
and function names,
they're all preserved because otherwise it will be tough to say, hey, which function was actually,
what was it called? Because you want to in the end link those back to your source code. I mean,
remember, and I know in some of the other bytecode languages, when the compilers are basically
transforming your code into bytecode, then you have mapping files. So you can always then map it back
to the original source code line
so you can actually provide good debugging tools
or developing tools and so on.
And I imagine in some ways
it'll have to run analogous to that.
But the interesting thing is
most of that transformation happens
at startup time, not at compile time.
You compile to a WebAssembly binary and you can still, to my knowledge, you can still
see within Reason the names of any exported
function, any public function.
So actually, you get us into an interesting realm, which is
to this point, we've talked about WebAssembly
as being, in this point, we've talked about WebAssembly as being, you know, in some ways running parallel to, say, Java or.NET or these other kind of bytecode languages.
And yes, it has some pros there, right, that make it a uniquely good fit for what Fermion wants to do.
You know, fast startup time, good security sandbox.
Those are really important for what we want to do.
But what makes WebAssembly interesting is that there's a feature in there that no other language environment really has.
And this is where we start talking a little bit about WASI, the WebAssembly System Interface,
but more specifically talk about this thing called the component model.
So, you know, if we were to back up to the, where are we, right? Well, we've got WebAssembly binaries. WebAssembly binaries run inside of sandboxes. The original design for
WebAssembly binary was, hey, I'm going to compile this old crufty C library and drop it in the
browser, and then JavaScript can call in and out of this. Or in Figma's case, I'm going to write this fancy new C++ high-performance vector library
so I can have my JavaScript call into it and do all the number crunching
and send me back the numbers I need faster than I'd be able to do it, right?
So it was a language designed to make libraries accessible,
not just top-level main functions, but libraries.
It's also designed to be language-neutral, right?
So I can run Rust, I can run C, I can run Python.
So it should, in theory, be possible to say,
hey, I wrote this in language A and that in language B.
I got a Python library, I got a Rust library,
and I'm writing some Go code,
and I want to compile all of that together
into one WebAssembly application,
or assemble all of that together
into one WebAssembly application. And that of that together into one WebAssembly application.
And that's what the component model allows you to do.
Basically, it's a way of saying, hey, this library exports these functions and this application needs to import these functions.
And then the WebAssembly interpreter says, OK, so I'll start up, you know, one of your main things and of your library things, and I'll run them both side by side and let them communicate with each other.
And so there's a case with two components, but there's no reason you couldn't have hundreds or even thousands of components all running.
Now, the way that this actually runs is where things start to get interesting because you've got two binaries.
Each binary is running in its own sandboxed version of the runtime, right? So,
you know, binary A, my high-performance vector library, and binary B, my serverless function,
they can see the functions that are imported and exported, but they can't see each other's memory.
So those of you who work in compiled languages or who have been following some of the recent
big security vulnerabilities know that you compile all of these into one big binary object.
And there's nothing stopping a misbehaving library like, say, a compression library, say, from attacking using functions in another libraries that another library controls the memory for, whatever, like, say, OpenSSH.
And so you can end up with some very
dastardly dependency injection things well in web in the web assembly world with components that
simply can't happen it's it's just the public interfaces that they're allowed to access the
memory is completely separate unless they decide mutually to share the memory and so you start to
you start to see a possibility for building a new kind of application
where instead of us constantly rewriting the exact same functionality
in every single stupid language under the sun,
you can say, ah, I got a Rust YAML parser, I got a JavaScript date parser,
I'm going to import both of those into my Python code, and all is good.
But then the security part means we can also start to say things like,
oh, by the way, that Rust YAML parser,
I don't want it to have access to the network.
So disallow it from using any network requests.
And that JavaScript date parser,
I don't want it to access the file system, the network,
or even the system clock, which would be weird for a date parser, I suppose.
And you can kind of turn on and off security for each of these modules.
So you start to see a glimpse of what the world could look like
if WebAssembly and the component model began to be sort of broadly adopted.
And that, I think, is what's really exciting.
That's where we see WebAssembly going
from a convenient replacement for serverless runtimes into a new kind of ecosystem that's
opening brand new opportunities for fun and new ways of writing code that is hopefully
far less wasteful of our time and resources and far more secure and observable, right? Because
anytime those function calls are going across modules, you can literally say,
hey, tell me anytime this library gets accessed
because I want to know.
Or we've got this internal running,
what if kind of thing where we're going,
what if you discover that OpenSSL
had a vulnerability in the calculate foo function?
So you wrote another component that said,
hey, I'm going to wrap the OpenSSL thing, and anytime somebody calls calculate foo, I'm going to
sanitize that request. Any other time, I'm just going to pass everything directly in and out.
So you start to see emerging this new way that we might be able to
handle security, observability,
software development, and it's exciting. I think that's
what really gets me going on WebAssembly's potential.
You can obviously feel it, that you are excited about it.
And for me, thank you, because when you started talking about this,
I thought, why not compile all of these different languages into one binary?
Because in the end, everything gets compiled into the same intermediate language.
But I think the benefit, what I now understand,
is that you can run all of these individual components
in isolation as a component.
And therefore, also to your SSL example,
if you have a vulnerability,
you can just replace this particular piece
and you don't need to recompile all of the other apps
and updating it with a new version of the library
that doesn't have the vulnerability.
So you really, basically, really basically know in the end, it's all micro services or serverless functions.
Everything is kind of isolated and encapsulated.
I really also like the fact that you can give it individual privileges.
So you can basically say which component runs in which particular security context so you
can actually secure it and give it just a least privileged approach, right?
You just basically say, what does this
particular capability
need? It doesn't need access to the network
so we don't give it access to the network.
It's really interesting. I could
also then obviously see the more
flexibility we provide here,
the more challenging it will become
to actually understand what is really going on as
things are executing because you have component A calling B, C, D, and then you have everything runs in a different security context.
That's why observability, again, has to play a vital role in all this.
Yeah, yeah. And I think, I mean, I'll give you an anecdote here, because everything you said is dead on, right? That's why it's so exciting.
I was at Microsoft when a low-level library,
open source library, had a major vulnerability.
And how did the operations team have to handle that? Well, they had to say,
all right, we got 1,400 or so applications
that were impacted by this,
all of which are containerized.
We can't actually do anything.
We have to send it back to all the developer teams
who built all these applications and say,
hey, y'all, stop everything you're working on,
cancel all your meetings, patch these right away,
re-upload all of these, and we'll redeploy them.
And that's disempowering to the operations team
because they're stuck not being able to do anything.
And it's really frustrating for the engineering teams
who all had their work interrupted that day
in order to do a high-priority patch.
And that kind of experience is one of those
where it comes to the forefront
that we have built technologies
that introduce human friction
into a human process of software developers packaging their applications, shipping them to
platform engineers, platform engineers running those applications, encountering issues,
having to go back to the software engineers, ask for things to be instrumented, right? We've got
this back and forth and back and forth that we know is the source of so much tension, right?
And people get grouchy when they have their work interrupted and people get grouchy when something's
going wrong in production and they can't do anything until the developers, you know, go fix
the problem. The component model might help us toward a solution there if we could say, as you
just said a moment ago, right? Oh, SSL bug. We will redeploy the SSL component with a fix or with a, you know,
web application firewall style wrapper on it. And that's a thing that the operations team often can
do or can do with the help of only one developer team instead of all the developer teams. And if
your application is just assembling components, then, you know, all it takes is redeploying this
component into all the applications. And, you know,ceivably, we can envision a world in which the Microsoft scenario of 1,400 services all becoming vulnerable on the same day,
resulting in 1,400 teams having to stop their work to fix it,
to being really more of an operation problem where that same level of vulnerability would just involve a small number of people saying,
okay, we've got to patch this one calculate you know, calculate foo function and recompile WebAssembly into their recompile Open
SSL into WebAssembly and then redeploy this thing out to everywhere. So it does have some exciting
things. And as you point out, observability in this case is both the, you know, the difficult
part and the kind of fun part, because in a way now one debugger is not just going to be able to watch
everything that happens start to finish
because you'll be calling in and out
of different bytecodes.
But on the flip side,
the observability on the operations side
may be just leaps and bounds
farther than what we have now
because we can say,
hey, this one module here,
this one component seems to be the source of
problems on applications A, B, and C. Something's wrong here and be able to diagnose things that
previously were completely opaque to us as platform engineers. Yeah. Two final thoughts on
mine because I know we are kind of approaching the end of the recording hour here, but on this,
I think we also need to be careful though, because if we,
let's say we made the jump from one monolith to a hundred microservices,
we may make the jump from a hundred microservices to 10,000 components.
If we really decide that everything becomes its own component,
right?
I mean,
that's from scaling and from managing a hundred thousand small components.
Like if you really go to do it as granular as like a
date function a formatting function then the question is are we going too far I think we I
guess that will be the interesting thing like how how small do we need to go how micro um so that's
that's that's going to be interesting like how do you manage all of this and then the second question
um it sounds nice that you know obviously obviously every component can then call another component.
It seems it's been very efficient,
but still calling something that is outside of its scope means you need to
cross scopes.
That means there's always some type of overhead involved in making two
components talk with each other that don't run in the same kind of space.
So I guess I assume that I hope
there's a good education going on
on how small should you go
and also what's the overhead
because there's always a way in communicating.
Yeah.
Yeah, and I mean, I think
the risk of talking to people like me
is that, you know, I'm looking out there going, I think we can do this.
I think we can do this.
I have no idea what the best practices are going to look like a couple of years from now.
Because in some ways, we need to start building applications and learning which way is the right way and which way is the wrong way. And I do share your concern that if we tried to literally
componentize at the, you know, at the library level, every single thing, we could certainly
end up in this case where even a, I mean, I was looking at node applications a while back and to
do an express node application with a database connector was 100,000 lines of code. But it's
also something like, you know, 1,400 libraries
or something like that. We don't want to run 1,400 WebAssembly components in order to do
Hello World, do we? Probably not. So we're going to have to sort of re, we're going to have to
invent some architectural patterns as we go to say, what is the right level of isolation or
whatever it is that's the characteristic we care
about at that time. Right size of API surface? I don't know. I'm not sure yet. But you're right,
because I think we could easily walk ourselves into a dystopia where debugging hello world
involves 400 human beings, and that would not be good. And then somebody will say, well,
back in 2024, I listened to this podcast with Brian
and Matt and they told me I need to put everything in a component and look at the mess that we
have now.
Yes, we don't want to.
People if you listen to this all the way to the end, then they know there's still ways
to figure out best practices.
And yeah, yeah.
And this is the trick of software engineering, right?
Is the engineering part of it is often learned through some hardships and some false starts.
And that's the part that we're going to hit pretty soon here is when is the right time to use this technology this way or when should we use it that way?
When should we default to just using a library as a library compiled inside of a binary. I think that probably gives me some hope because a lot of times we see people
choose technologies without any thought or consideration to observability or
security, right?
I mean, we've seen some people go full serverless just because they thought it
would be cool to run full serverless.
Nothing to do about taking advantage of what, you know,
the pros and cons of serverless.
And the reason why I say this gives me hope
is that I think one of the things you'd have to do hand-in-hand
to figure out how low can you go to resay how Andy said
how small you can go, we'll go a little limbo there,
is with proper observability and understanding
those different architectural regressions as you're planning it out.
Like, okay, if we're at 10 versus
100, do we have any
performance trade-offs? Do we get anything better?
And by observing that as you go,
taking and making observability
and performance a first-class citizen as you're
moving to WebAssemblies, I think that
would help.
We've seen that even in microservices, right?
When you can start going into nanoservices
and all this kind of stuff.
The key there is to observe it and find out what that's going to be. And then obviously best practices will come from it, but even still
you would need to have that visibility to make sure you're doing the right thing.
And I do have to give you a big kudos for saying dastardly.
I immediately thought of Dirk Dastardly and Muttley and all those old cartoons, and I was
like, you are the first podcast guest to say the word Dastardly.
So, yeah.
I will wear, I want a t-shirt now that it says that.
I guess I didn't even pick it up.
Yeah.
I don't know if this is like a Colorado thing you know that did you know with you know
kind of the like Wild West heritage that
dastardly is just it's just a word
that's in the vocabulary right what else
does it I haven't heard anybody say if
haven't heard anybody save in forever I
just know from the old Hanna-Barbera
cartoons like you're the first people
I've heard in real life that wasn't like
in some weird movie you know like oh we going to get that Dastardly guy.
So it's a bit old-timey, but great. Andy, was there
another question you had? I think you had. Yeah, just the last thing, because
we need to get this unfortunately to a close soon. Matt, you talked about
Fermion, actually not too much, because you kept it really focused on
the topic at hand,
but maybe just like a kind of a final sentence or a final comment on what you guys are bringing to the table in that community. Yeah, and you know, what got us going was this interest in
serverless. And so we built, you know, kind of two halves of this, a developer tool for building
serverless functions into WebAssembly objects that can be deployed,
and that's called Spin.
Developer.fermion.com is where you can kind of find more out about Spin,
all open source, all written in Rust.
And it supports a wide variety of languages,
including Go and JavaScript, TypeScript, Python, Rust, of course.
And then we have a Kubernetes runtime called SpinCube.
We built this together with SUSE, Microsoft, Liquid Reply, and others.
And this turns your Kubernetes cluster into a WebAssembly runtime
side-by-side with containers.
For those of you who do a lot of Kubernetes work,
how deeply is this integrated?
It's integrated all the way down to the container D layer,
so you can literally deploy one Kubernetes pod
that's a mixture of WebAssembly and container images inside of it,
and it can execute them side by side.
So basically, we slot it in the WebAssembly runtime
side by side with a container runtime,
and you can use them both.
It's really cool.
So that's Spin and SpinCube are the two main things
that Fermion is working on.
Perfect.
And we'll add all the links, folks, if you're listening in, all the links in the description.
Matt, thank you so much for doing this.
I think I learned quite a bit about WebAssembly.
Thank you so much for enlightening us.
Brian, I hope you feel the same.
Yeah, I mean, as you can tell, I was absolutely silent in this one because it was just all learning.
I couldn't even think of smart comments to make during it.
Absolutely enlightening.
I think there's a lot of cool stuff.
That's a really nice way of saying, Matt, you talk too much.
No, no, no.
Anytime I even had a half of a thought, Andy was right on it because he was so enthusiastic, too.
And I was just going to say something stupid anyway.
But it's not that you even talk too much.
This is all new,
and I feel like we're seeing something around the cusp.
The idea of this being used on the back end
is really exciting,
and I can't wait to see how that pans out.
And now, I use Office 365 Web quite a lot,
and now I'm going to know that's awesome.
It's not only awesome, it's wassome.
Thanks for stealing my joke and repackaging it, Andy.
I guess, see, mine fell flat.
So thank you.
Anyway, I guess we'll wrap it up here then.
Thank you again for being on, Matt.
This was just absolutely incredible, and I
hope this all goes
very well. It sounds like there's a lot of exciting
potential.
I can't wait to see what comes on.
Thank you as well. Thank you both for having
me. This was great. Awesome.
Looking forward to seeing you
at KubeCon in
Salt Lake, I would assume.
That's right.
Alright. Thank you, everybody.
Thank you. Cheers.
Bye. Thanks.