Report

We partnered with High Alpha for the 2024 SaaS Benchmarks Report,

see how you stack up

Splitting the monolith: Breaking up your codebase to improve functionality

Why split your codebase?

Most high growth companies have a codebase that has evolved organically over time and your company is likely no different. It’s to be respected and cared for like anything modern and shiny. However, just like dealing with an unruly stack, working with a large system means it’s harder to make changes to, harder to monitor and maintain and harder to effectively test. No one needs this when they’re trying to focus on scaling and company success.

A common approach for addressing this issue is to split a large system out into smaller, single responsibility services, which can be monitored and deployed separately. This will improve your speed of delivery and the ease of tracking down issues, in addition to reducing hard dependencies. It is, however, very important to do the splits in the right way and for the right reasons. Let’s go through how you could approach this and balance this work with feature delivery.

Where to begin

There are several ways to split services out from a large codebase, but in our experience the best approach is to find areas which fit with business priorities and tackle them as you go. This way your company can continue to deliver your product roadmap whilst pushing the engineering strategy forward. This is also the easiest approach to explain to non-technical stakeholders; progressive improvement towards a better product which is more flexible, reliable and modern.

We currently have a large PHP codebase hosted in AWS ECS (Fargate), which we are splitting out into either mid-sized PHP services hosted in AWS ECS or single responsibility microservices hosted in AWS Lambda, written in Go or Python. The decision between these two is based on a number of factors, including team specialism in languages, how large the piece of a domain being split out is and whether there are appropriate third party SDKs for the approach.

We chose our emailer to be the guinea pig, splitting it out into a Lambda attached to our existing email SQS queue.

“One of the hardest parts of splitting your monolith is deciding where to make the splits. Too big and you’re building new monoliths with mixed responsibilities… too small and you have hundreds of services which are hard to coordinate”

How we extracted our emailer from the monolith

We send out thousands of emails a day and we already use SQS as a queuing service to make sure we can scale to higher load periods. This made it simple for us to attach a new split-out email sending Lambda written in Python to it, which abstracts away the email sending service (in our case, Postmark) in case we want to make changes in the future.

In taking steps like this you are saving yourself - and the company as a whole -  time and anxiety. If you want to make changes to how you send emails in future, you’d no longer need to deploy and test the rest of your company’s platform, making changes less risky and far easier to review.

The diagram above shows how we used various AWS components (Lambda for processing, SNS/SQS for queuing and error handling) to keep our emailer simple, easy to change and scalable for future needs.

Where to make the splits

One of the hardest parts of splitting your monolith is deciding where to make the splits. Too big and you’re building new monoliths with mixed responsibilities that are just a little smaller, too small and you have hundreds of services which are hard to coordinate and monitor in an end to end context. We have decided to take the approach of modeling our domains and grouping concepts. By so doing, you’re ensuring that you’re making sensible choices and setting yourself up for good ownership within your Engineering teams.

It’s important to make sure you continue to address and reduce technical debt in a pragmatic way. At Paddle, we’re continually looking for opportunities to create single responsibility services out in order to ensure that we can change direction quickly and deploy changes safely to support our continued growth.

How a Merchant of Record can help you focus on scaling

You’re looking to make positive changes in your business so you can focus on success, so why not take the pressure off billing as well? Paddle is a merchant of record, meaning our checkout and licensing solution not only takes care of your billing - we’re also legally responsible for compliance, sales tax, fraud prevention and much more. Grow your business with our help. Request a demo today!

Related reading

Onboarding illustration
Five SaaS UX and onboarding lessons from the creators of Trafft 
Alexander Gilmanov
What is feature creep and how to manage it
Georgi Todorov
How Juro launched freemium in a week - and the lessons learned along the way
Richard Mabey