Running PHP blazingly fast at the Edge with WebAssembly
Syrus Akbary
Founder & CEO
May 23, 2024
PHP currently powers ~75% of the websites on the internet. It may not be the “sexy boi” of programming languages… but it has been an important actor since the internet's birth and our pulse to use it for sharing memes and cat images. Starting today, in open beta, you’ll be able to run PHP fully in Wasmer and Wasmer Edge.
But …why is running PHP in WebAssembly important? Thanks to the properties of WebAssembly, we can safely restrict the resources that the program can access, and as such… we can run PHP safely without the overhead of OS or hardware virtualization.
The support for PHP in WebAssembly arrives after countless hours of work from the Wasmer team (Arshia and Amin in particular!) working to make PHP run flawlessly and as fast as possible. TL;DR: we got up to 3x faster speeds by enabling opcode caching inside WebAssembly, a feat never achieved before!
Bringing serverless-like scalability to any PHP app can unlock immense value, allowing you to run your PHP apps in the Edge and pay a fraction of the price that cloud providers charge.
This also means that you can run every PHP application out there with Wasmer without ever worrying that the app will break sandboxing and do harmful things they shouldn’t be able to.
You can now run the most popular PHP frameworks in Wasmer and Wasmer Edge:
All PHP templates: https://wasmer.io/templates?language=php
Note: Wasmer Edge support for custom filesystem volumes is on the way. The deployed apps that are using SQLite (such as Wordpress or Symfony), currently only store database changes memory, not yet permanently.
To squeeze the max out of WebAssembly and PHP we have been able to enable opcode caching, allowing Wasmer to run WordPress without any modification, at 3x the speed… going from 600ms to a reasonable 200ms to render a basic blogpost page.
Do you want to try it?
If normally you would do:
php -S localhost:8000 .
You can now simply run it fully sandboxed via Wasmer with:
wasmer run php/php --mapdir:/app:. -- /app -S localhost:8000
You can also run wordpress locally easily. Just clone the Wordpress repo: https://github.com/wasmer-examples/wordpress-wasmer-starter and run
wasmer run . --net
on the root! Note: you’ll need Wasmer 4.3.1
And there you go… a fully functional PHP CLI running in your server, and fully sandboxed! You don’t have to worry anymore that the app will have access to your /etc/passwd
or your precious bitcoins!
Welcome to the new frontier, where the software that we know and love can be compiled and run in a way that is fully sandboxed.
Technical feats
Getting PHP to work flawlessly in Wasm with Wasmer was not an easy feat. We solved many problems along the process:
- We found an obscure bug in our
longjmp
/setjmp
implementation (required to have try/catch statements within PHP), where the stack was being overwritten and not properly restored - We discovered and fixed a bug slowing down outgoing HTTP calls by a 10x factor
- We enabled PHP
opcache
by default, allowing up to 3x faster PHP times - Many small fixes on the filesystem virtualization layer and networking (oh, IPv6 our dear friend!)
If you have followed our previous blogpost on running WordPress with Wasmer, you may have realized that we have had to do countless code adaptations (a.k.a. hacks) in WordPress to change its behavior and not trigger a blocking edge case. Namely, these are all the hacks:
- We had to standardize calls to the
exit
function: https://github.com/wasmerio/wcgi-wordpress-demo/commit/9116a7ba25bb14cc50f1a18b81490929347c8462 - We had to comment out any fetch calls: https://github.com/wasmerio/wcgi-wordpress-demo/commit/ef1550ba3cce4fb6882a738d8409aacbc09784f0
- We served the static assets using the PHP interpreter (there’s code I’ve been more proud of than this one! https://github.com/wasmerio/wcgi-wordpress-demo/blob/main/app/hacks.php#L44-L150)
As of today, none of those hacks are needed any longer.
The good news is that on the latest release of Wasmer, WordPress, Laravel, and Symfony run in Wasmer without any code modification whatsoever.
We are incredibly happy with this because running those frameworks successfully with no modifications required also means that Wasmer will likely be able to run every PHP program out there.
But… how fast is it?
Just running PHP at baseline speeds was not enough for our use case, we wanted to run it as fast as humanly possible in WebAssembly.
Thankfully for us, PHP has one module that makes its execution much faster: the Zend Opcache. The Opcode caching module works by optimizing and caching the bytecode that the PHP source is transformed into, thus saving time by not parsing the AST of the files that have already been processed.
Opcode caching can bring a 3x speed up to the number of requests an app can handle, so it seemed obvious to enable it on WebAssembly.
However, opcode caching (and Zend module loading) was disabled by default (as it requires dlopen
, dlsym
, and more support in Wasm, which is not available).
So we set on a unique quest: enabling opcode caching in PHP.
After some research, we found one novel way of doing it, and we were up for the races: we found a way to statically link it, and had to fix a bunch of things along the way… but we got it running at the end!
Here are the timings of WordPress without Opcache in Wasm: ~620ms
And the timings of WordPress with Opcache enabled in Wasm: ~205ms
That’s a 3x speedup just by enabling Opcache!
While doing the work, we also realized there are even further improvements that we can make to PHP to bring it close to native speeds. Stay tuned!
Our work opens up even more avenues for projects that are currently relying on Emscripten to run PHP in the browser, such as the WordPress playground, allowing those projects to work with packages that can run both in the browser and in the Edge!
But this is not all: we are working on a completely revolutionary approach to cold-starts that will supersede any other provider by a big factor (Cloudflare & Fly.io, we are looking at you!)… exciting times are coming to the Edge market.
Did you like running PHP in WebAssembly with Wasmer? You can also:
- Join our Discord channel and tell us what you are building!
- Follow Wasmer on X/Twitter to hear updates about Wasmer
- Deploy your first PHP app to Wasmer Edge: https://wasmer.io/templates/php-starter
About the Author
Syrus Akbary is an enterpreneur and programmer. Specifically known for his contributions to the field of WebAssembly. He is the Founder and CEO of Wasmer, an innovative company that focuses on creating developer tools and infrastructure for running Wasm
Syrus Akbary
Founder & CEO
Technical feats
But… how fast is it?