ButcherBox, a meat subscription and delivery service, recently moved the tech stack for their e-commerce site from a PHP monolith to Jamstack to improve performance and agility while lowering costs. In this post, we will break down ButcherBox's journey to Jamstack, as told by Jeff Gnatek, their head of engineering.
Starting with a Monolith
In 2015, ButcherBox started on Kickstarter and quickly brought their website to life with Wordpress. Non-technical people found it easy to work with, PHP and jQuery developers were easy to hire, and there were no expensive DevOps involved. All it took to publish a page was to press "Publish" in WordPress and specific behavior was added through plugins.
Unfortunately, as the complexity of ButcherBox grew, their performance dropped. Working with Wordpress's PHP means having frontend and backend code in single files. Although this is a standard, it becomes problematic as the number of developers on a team grows.
Generally speaking, backend code is involved in the business logic and security of the system while frontend code is involved in presenting the information in a beautiful and intuitive way. Having both of them in a single file is okay for small teams, but not for when there are designated developers working explicitly on one of the two. Managing conflicts in the file edits on itself can double development time and time spent on related tasks.
Gnatek says that their bottleneck was their platform. Whenever they wanted to introduce some new features they needed to work on it for a long time in advance, which limited their ability to follow trends and implement new ideas on the fly.
In addition to this, the complexity of their website resulted in having page load times around 4 seconds, sometimes even as high as 7 seconds. This is a huge issue for an e-commerce website as page load time has a great impact on conversion rates. Realizing this, they decided to change how they developed and managed their website.
Decoupling the Code
ButcherBox started separating their building blocks and concerns into different areas. The goal was to swap the engine out mid-flight—to change the system incrementally, moving it from the old, slow one to the new, faster one.
This method, known as the Strangler Fig Pattern, uses a reverse proxy such as Nginx to determine where each user's request should be handled. If the request accesses something that has been migrated to the new codebase it will be forwarded to that; otherwise the old website would be presented. ButcherBox started by routing the one-time purchase pages of their shop to a new website without affecting the old one.
The new website was created by separating frontend and backend code bases, using APIs to communicate between the two. This strategy on its own created a faster-perceived page load time. It also improved security since they no longer needed to expose a PHP server. They relied on Auth0 to handle their authentication and authorization process and used Netlify to build and serve their website over the internet.
Gatsby, and React in general, is based on the idea of components that work independently of each other. As an example, your recent article column doesn't need to be aware of your footer, so by separating their code we allow for reusable components and faster development time. Besides, Gatsby relies on server-side rendering which improves page load time at the cost of static build time on the server every time the website is updated.
After separating the frontend and backend, ButcherBox started separating backend components. They started by dividing the code into two parts: the core business logic and the ephemeral contents such as product catalog, inventory, merchandising, and promotional ads. All of these separations of previously entangled parts allowed for higher test coverage and reduced the risk that a single update to the website would crash everything. It also allowed for a more agile development.
Replacing the Admin
To replace the WordPress admin they used Laravel's Nova, a highly customizable admin panel written in PHP. Nova helped the non-technical members of the team work with the system without having to deal with direct database interfaces. To add food recipes—content that supports the selling of their meat products—the team moved to Contentful which provides a full-featured editor that automatically triggers a build on Netlify whenever there is new content to be served.
This proved to be problematic at first: having many different components and server side rendering together means that any small change requires a full rebuild of the website, taking as much as 20 minutes sometimes. To work around this issue, the team started creating different instances of frontend and backend, each working independently. This meant that adding a new food recipe wouldn't trigger a build for the Shop page.
To speed things up, they shared components among the instances wherever possible. For example, to reuse Gatsby's logic on the frontend, they used Gatsby Themes, a collection of reusable, shareable functionality to be used among different Gatsby instances.
This journey took their website from a slow monolith in PHP with increasing complexity and development costs to a fast, easily scalable e-commerce site. The team reported that their website was about 600% faster on average (going from 4000ms to under 600ms), and that the development team was able to launch a new part of the website within days.
Is Jamstack Right for You?
Jamstack is a great method for web development, but like all other methodologies, it is not for everyone. There are certain things to consider before choosing to work with Jamstack.
First, consider the data you're presenting on it. Does it need to be dynamic, relying on different users? A typical example of this would be social media sites that show you your friends' activities. Having dynamic data is not necessarily bad, but it requires having a set of APIs to provide them. That said, I wouldn't recommend using Jamstack if more than a third of your data needs to be dynamic.
Second, consider how fast the updates to your website should go live. Can the changes wait a few minutes to propagate? This would be okay for a blog post or a food recipe, but not so much for stock count and pricing. Again, if your data falls into this category, you can deliver it to the client through an API. But that would be too much trouble if all or most of your data requires real-time updates.
Finally, do you already have an API or different sources of content? The data presented on your website will usually be propagated from different sources such as Contentful, a database, and an API. If you already have different sources of data, that's a plus. Otherwise, you have to create them as you go along. This is exactly what ButcherBox did.
Switching to Jamstack provides better security, better performance, reduced complexity in code, and low-friction hosting. The only apparent downside is the cost of migrating to such a system.
Keep in mind that Jamstack relies on many third-party services, which is great for reducing costs and complexity of your codebase, but any downtime on those services could potentially affect you.
With all that said, are you ready to switch your monolithic e-commerce site to Jamstack? If so, Fabric can help simplify the process.