Enjoying this issue?
Get tomorrow's AI & engineering digest in your inbox — hand-picked, summarized, and always spam-free.
TLDR
Facebook avoided a costly rewrite of its PHP codebase by incrementally replacing the runtime and type system underneath the code that kept shipping. The company first compiled PHP to C++ with HipHop, then built a JIT compiler (HHVM), and finally introduced a gradually typed language (Hack) that allowed organic migration. A 2026 AI-assisted rewrite of Bun from Zig to Rust in 11 days shows that fast rewrites are possible but still incur long-term costs in earning back trust.
Key points
- Facebook refused to rewrite its PHP codebase in a compiled language despite CPU costs, instead building a compiler (HipHop for PHP) that turned PHP into C++, halving CPU usage.
- HipHop's compilation was slow and hindered development, so Facebook built an interpreter (HPHPI) for development and later replaced both with a JIT compiler (HHVM) that matched and then exceeded the C++ compiler's speed.
- Facebook introduced Hack, a gradually typed language on HHVM, allowing typed and untyped code to coexist, enabling organic migration of the entire PHP codebase without a dedicated migration team.
- By 2019, HHVM dropped PHP support entirely, having migrated the codebase to Hack through incremental tooling and a fast type checker.
- In 2026, Bun was rewritten from Zig to Rust in 11 days using Claude Fable 5, with 7,000 commits and an estimated API cost of $165,000, achieving memory safety and a 20% binary size reduction.
- Despite the fast rewrite, Bun had not shipped a release tag 11 weeks later, with over 2,400 open pull requests, illustrating that the real cost of a rewrite is earning back the trust accumulated by the old code.
- Joel Spolsky's argument that rewriting code from scratch is a strategic mistake still holds, but AI-assisted rewrites can be an exception when there is a language-independent test suite, a single maintainer with full design knowledge, and a clear safety goal.
Tools mentioned
Techniques
- source transformation
- just-in-time compilation
- gradual typing
- incremental migration
- AI-assisted code porting
Stop scrolling. Start reading smarter.
Receive the day's most important AI & engineering updates in one concise email. No spam.
Transcript (captions)
In 2009, Facebook was running more than 30,000 servers. And the code on its web tier was PHP. All of it. Every profile, every wall post, every photo tag interpreted one request at a time. PHP is cheap to write and expensive to run.
And at that size, the expense has one name, CPU. CPU means machines. And machines were the fastest growing line on the company's budget. So, the engineers looked at it and reached the conclusion you would reach. Rewrite it in a compiled language.
Facebook refused and then spent 9 years getting off PHP without ever running a rewrite project. February 2010, they shipped a compiler that turned their own PHP into C++. Webtier CPU fell about half. That compiler then made their own engineers slower, so they threw it out and built a virtual machine instead. In 2014, they changed the language underneath the code file by file until the PHP was gone.
By 2019, their runtime dropped PHP support outright. There was no migration project because there was nothing left to migrate. Which raises the question this whole story turns on. And it is a 2026 question, not a history lesson. In May, an AI ported a million lines of bun from Zigg to Rust in 11 days.
Does that make the old advice wrong? Go back to the refusal because the reasoning is the part worth stealing. Facebook's problem was not that PHP was a bad language. Their problem was that a lot of their engineers knew PHP. The site shipped changes every day and both of those facts were the business.
Their own announcement says it plainly. The common suggestion was to rewrite the site in another language and given the complexity and the speed of development of the site that would take some time. Sometime is carrying enormous weight in that sentence and they knew it. Netscape had already run that experiment. In April 2000, Joel Spolski wrote it up in an essay called Things You Should Never Do and called rewriting the code from scratch the single worst strategic mistake that any software company can make.
Netscape shipped version 4. Then there was no version 5 at all and their market share fell the whole way down. Spolski's argument was not that new code is worse code. It is that old code has been used. Bugs were found in it and those bugs were fixed.
Every one of those fixes is knowledge and it survives as a weird-l looking line that a new team would delete on site. Throw the code away and you throw away the fixes and you get to rediscover all of them in production in front of your users. So Facebook took the third option, the one people forget exists. Keep the code, change what runs it. Hip hop for PHP was a source transformer.
It read their PHP, emitted highly optimized C++ and handed that to G++ to compile. It started as one engineers hackathon idea. Hyping Xiao spent eight months getting a demonstration to work. Then two more engineers and another 10 months of coding finished it. Hip hop itself came out to over 300,000 lines with more than 5,000 unit tests.
6 months of production testing later, it was serving 90% of Facebook's web traffic on roughly half the CPU. Same traffic, half the burn, and the people writing the site did not change a single habit. Xiao put the mechanism in one sentence at Stanford that May. Dynamic symbol lookups get replaced with static binding and weakly typed symbols get inferred into stronger types two to three times faster on the site. He said at 30,000 servers having the web tier CPU stops being a benchmark number.
It becomes the difference between buying machines this quarter and buying them next year which is a sentence a finance team understands and a rewrite proposal has no answer to. But a compiler that halves your server bill charges rent. And Facebook paid it for three years in the currency that actually hurts. Compiling the whole site produced one binary well over a gigabyte with no incremental build, change one line, rebuild everything. So they could not develop on it.
They built a second engine, an interpreter called HPHPI purely so engineers would not sit waiting on the compiler. Now the same team maintains two implementations of one language on different syntax trees and the two have to agree. They did not always agree. You wrote your code against one engine and shipped it on another and HPHPI was slower than the plain PHP engine it replaced. So answer this before the next part.
Would you take 50% off your server bill for that? Facebook took the deal, then spent 3 years buying its way back out. In December 2011, they announced HHVM, a just in time compiler for PHP. Same idea a modern JavaScript engine uses. compile the hot paths while the code runs and use one engine in development and production.
It was a race against their own product. In the fourth quarter of 2012, HHVM matched the C++ compiler on speed. In the first quarter of 2013, facebook.com stopped using Hip Hop. By that December, the virtual machine was about 15% faster and the compiler was retired. Notice what did not happen in that paragraph.
The site never stopped. No team was pulled onto a 2-year port. The PHP files sat exactly where they were, while the thing executing them was swapped out underneath twice. The runtime was solved. The language was not.
Millions of lines of dynamically typed PHP where a type error still meant a page breaking in front of a user. So in March 2014, Facebook released hack. PHP with a real type system running on HHVM. Hack is gradually typed and that phrase is the entire strategy. Typed code and untyped code call each other freely, which meant most existing PHP files were already valid hack files.
You annotate one file, the checker starts helping in that file, and 10,000 others keep working. They also made the checker fast because a slow checker is one people turn off. It typically runs in under 200 milliseconds and rarely takes more than a second on a codebase that size in your editor while you type. Within a year, they had moved nearly the entire PHP codebase to hack through organic adoption plus refactoring tools they wrote themselves. There was no migration team.
There were tools and a type checker that made the converted file the nicer place to be. Then in September 2018, the HHVM team posted the sentence that closes the loop. Version 330 would be the last release series where HHVM aims to support PHP. 4.0 shipped on the 11th of February 2019 and put it flatly. With this release, we no longer aim to be compatible with PHP.
Read the decade backwards and there is no rewrite in it. A compiler, then a virtual machine, then a type system, then a language. Four tools whose only job was to let the code that already existed keep running. PHP fell off the end of that ladder. And PHP did not die on the way.
It is still the serverside language on around 70% of the sites where anyone can identify one. And in 2020, PHP8 shipped a just in time compiler of its own from its own core team. Which brings the question back because 2026 handed that whole argument its strongest counter example. And I am not going to pretend it away. On the 14th of May, a poll request titled rewrite bun in Rust merged into Maine.
Over a million lines added. All,448 Zigg files ported. Start to finish 11 days. Jared Sumner drove it with Claude Fable 5. About 50 dynamic workflows, up to 64 instances running at once, an implementer, two adversarial reviewers, and a fixer on each change, and nearly 7,000 commits.
The bill at API pricing was about $165,000, and the goal was not speed. Sumner stated reason is memory safety, use after free, double free, forgot to free in an error path. In safe Rust, those stop being bugs and start being compiler errors. The results back him up. Binary shrank about 20%, throughput came out a few% faster.
And one instrumented leak that grew to nearly 7 GB over 2,000 builds came down to about 600 megabytes. So the Spolski argument is finished. Except look at what happened after the merge instead of at the merge. Bun's last release tag is the 12th of May 2026. 11 weeks later, on the 27th of July, developer Tom Lockwood counted the bot's open poll requests.
2475, up from 1,277 18 days before. Still no release tag. The Rust build is still Canary, not the ship default, though Claude code has run on it since June. Lockwood also argues the real bill is closer to $800,000 once you count the anthropic engineers attached. And that is one person's estimate, not a published figure.
None of that makes the rewrite a failure. The memory bugs it was built to kill really are compiler errors now. And Sumner published his regressions instead of burying them. What it does is make the invoice legible. 11 days bought the typing.
What is still running 11 weeks later is the other half of the bill, earning back the accumulated trust that the old code had already paid for, which is exactly the asset Spolski set a rewrite throws in the bin. So here is where I land and who it is for. If your codebase makes money today, Facebook's path wins and it is not close. You do not rewrite. You replace one layer at a time underneath code that keeps shipping.
Runtime first, then types, then the language. Bun earned its exception and the conditions are specific. A language independent test suite that could referee the port. One maintainer holding the whole design in his head and memory safety as the goal rather than taste. If you have all three, take the deal.
Most teams reaching for Rust this year have one of those at best. And watch the actions, not the announcement. The receipt for a rewrite is a release tag, not a merge commit. So, a bet with a date on it. If the Rust build is not Bun's default binary on every supported platform by the end of 2026, then the 11 days were the cheap part and I will come back and say so, which leaves the thing this story started with.
Facebook never rewrote PHP and Facebook does not run PHP. So, did they escape PHP or did PHP escape them?