This post about moving from PHP to Go was first published elsewhere, and republished here with the author’s permission.
Earlier this year, I made an arguably bad business decision. I decided to rewrite the Laravel application powering Boxzilla in Go.
No regrets though.
Just a few weeks later I was deploying the Go application. Building it was the most fun I had in months, I learned a ton, and the end result is a huge improvement over the old application. Better performance, easier deployments and higher test coverage.
The application is a fairly straightforward database driven API & account area where users can log-in to download the product, view their invoices or update their payment method.
Stripe and Braintree are used to accept subscription payments. Invoices are handled using MoneyBird and some transactional emails are sent using Mailgun.
While Laravel worked well enough for this, some things always felt overcomplicated to me. And what’s with releasing a new “major” version every few months? I’d be fine if the newer versions contained significant improvements, but a lot of the times it just felt like minor naming & directory structure changes to me.
Why Go?
Last year I’ve been moving several services over to Go, so I wasn’t completely new to the language. As a developer selling WordPress based products, part of my job is working in an ancient tech stack that is mostly focused on the end user.
If I weren’t self-employed, I would simply apply for a new job to make up for this lack of sexy tech. Being my own boss, I owe it to myself to make my day-to-day work fun and not just chase more immediate $$$. If revenue allows (and it does), why not have a little fun?
It’s a joy to write Go code, the tooling is amazing and it’s not only fast to develop in, the end result is usually crazy fast too. Just reading about the purpose of the Go project sold me on the language.
I think we’ll see a good amount of people switching from dynamically typed languages like PHP, Python and JavaScript to Go in the next few years.
Porting the Codebase
Migrating the code to Golang consisted mostly about getting the database interaction right & porting the Blade templates to something we could use in Go.
ORMs are one thing that always ends up getting in my way, so I went for a mockable data access layer and plain SQL queries. Meddler was used to get rid of some of the boilerplate for scanning query results into structs.
To support hierarchical templates and partials I open-sourced grender, a tiny wrapper around Go’s standard html/template package. This allowed me to port the Blade template files to Go with relative ease, since I could use the same hierarchical structure and partial templates.
For integrating with Stripe there is the official stripe-go package. For Braintree there is the unofficial braintree-go package, which was neglected for a little while but received renewed attention lately. Since there was no Go package to manage invoices in Moneybird yet, I built and open-sourced moneybird-go.
Comparing Apples vs Oranges
Since Go is a compiled language with a much better standard library than PHP, it is not really fair to compare the two languages like I am about to. That said, I thought it would be fun to share some numbers.
Performance
wrk was used to perform some simple HTTP benchmarks for both applications returning the HTML for the login page.
Concurrency | Avg. latency | Req / sec | Transfer / sec | |
---|---|---|---|---|
Laravel | 1 | 3.87ms | 261.48 | 1.27MB |
Laravel | 100 | 108.86ms | 917.27 | 6.04MB |
Go | 1 | 325.72μs | 7365.48 | 34.27MB |
Go | 100 | 11.63ms | 19967.31 | 92.91MB |
Go | 200 | 37.68ms | 22653.22 | 105.41MB |
Unfortunately, the Laravel application (or PHP-FPM socket) kept falling over once I increased the number of concurrent “users” past 100.
NetData provided the following graphs to see how the server was holding up under all this load.
Golang with 100 concurrent connections
Laravel with 100 concurrent connections
Please note that I ran the benchmark from the same machine as the applications were running on, so this heavily influences both graphs.
Lines of Code
Let’s compare the lines of code in both applications, including all vendor dependencies.
find . -name '*.php' | xargs wc -l
156289 total
The Laravel version consists of just over 156.000 lines of code. This is excluding development dependencies which, with Laravel, are needed to run tests etc.
find . -name '*.go' | xargs wc -l
33624 total
The Golang version on the other hand consists of 33.000 lines of code. That’s one fifth of the code for exactly the same functionality.
Let’s exclude external dependencies in the Laravel application so we know how much lines were actually written by me.
find . -name '*.php' -not -path "./vendor/*" | xargs wc -l
13921 total
And for Golang.
find . -name '*.go' -not -path "./vendor/*" | xargs wc -l
6750 total
The result is slightly more even when just looking at managed lines of code. Still, it’s the exact same application with half the amount of code.
Test Coverage
Testing is a first class citizen in Golang, and test files live right next to the actual source files.
license.go
license_test.go
subscription.go
subscription_test.go
This makes it incredibly convenient to apply test driven development.
In our Laravel application we mostly had integration tests that checked whether the request handlers returned a proper response. Overall test coverage was quite low, mostly due to tight coupling which in turn was mostly my fault. Writing the same application a second time really helps here too.
TLDR
I did something you should never do: rewrote an application in a different language because I felt like it. Had lots of fun and got a much smaller and faster application in return.
Frequently Asked Questions about Moving from PHP to Go
What are the key differences between PHP and Go?
PHP and Go are both powerful programming languages, but they have some key differences. PHP is a scripting language primarily used for web development, while Go is a statically typed, compiled language designed for efficiency and simplicity. Go offers superior performance in terms of speed and memory usage, and it’s also easier to maintain due to its simplicity and strong typing. However, PHP has a larger community and more resources available, which can make it easier to learn and use.
Why should I consider moving from PHP to Go?
There are several reasons to consider moving from PHP to Go. Go offers superior performance, which can be crucial for applications that require high speed and efficiency. It’s also simpler and more straightforward, which can make your code easier to maintain. Additionally, Go has strong support for concurrent programming, which can be a major advantage for certain types of applications.
How difficult is it to transition from PHP to Go?
The difficulty of transitioning from PHP to Go can vary depending on your familiarity with programming concepts and your willingness to learn a new language. Go is designed to be simple and easy to understand, but it does have some unique features that can take some getting used to. However, with some effort and practice, most developers should be able to make the transition.
What resources are available to help me learn Go?
There are many resources available to help you learn Go. The official Go website offers a comprehensive tutorial and documentation, and there are numerous online courses and tutorials available. Additionally, the Go community is active and supportive, and there are many forums and discussion groups where you can ask questions and get help.
Can I use Go for web development like I do with PHP?
Yes, you can use Go for web development. Go has a built-in net/http package that makes it easy to build web applications, and there are also several web frameworks available for Go. However, keep in mind that Go is a general-purpose language, so it’s not as specialized for web development as PHP.
How does Go handle concurrency compared to PHP?
Go has strong support for concurrent programming, which is one of its major advantages over PHP. Go’s goroutines and channels make it easy to write concurrent code, and the language’s design ensures that this code is efficient and safe. In contrast, PHP does not have built-in support for concurrency, although it is possible to achieve with additional tools and libraries.
What are the performance differences between PHP and Go?
Go generally offers superior performance compared to PHP. It’s a compiled language, which means it runs directly on the machine’s hardware, resulting in faster execution times. Go also has a more efficient memory management system, which can lead to lower memory usage. However, keep in mind that the performance difference may not be noticeable for small, simple applications.
Is Go a good choice for large, complex projects?
Yes, Go is a good choice for large, complex projects. Its simplicity and strong typing make it easier to maintain large codebases, and its performance characteristics make it suitable for high-load applications. Additionally, Go’s support for concurrent programming can be a major advantage for projects that require high levels of parallelism.
How does Go’s community and ecosystem compare to PHP’s?
PHP has a larger community and more resources available, which can make it easier to learn and use. However, Go’s community is growing rapidly, and there are already many libraries and tools available for Go. Additionally, Go’s simplicity and performance characteristics have made it popular among many tech companies, which contributes to its growing ecosystem.
What are some potential challenges when moving from PHP to Go?
Some potential challenges when moving from PHP to Go include learning a new syntax and programming paradigm, adapting to Go’s unique features like goroutines and channels, and finding the right libraries and tools for your needs. However, with some effort and the right resources, these challenges can be overcome.
Danny is a 20-something web developer with a knack for sales, working from The Netherlands during summer and warmer countries during the winter. He is the founder of ibericode, a small company building products for the web. He develops and markets MailChimp for WordPress, Boxzilla and several other WordPress plugins totaling well over 8 million downloads. His code runs on well over 1 million websites.