How to Decrease Your SaaS Expenses
The Essential Guide to Building a Low-Cost High-Quality SaaS Product
CEO of SaaS Tune
When you're running a B2B SaaS company, you'll naturally want to keep your costs low. Most SaaS businesses run lean because of a fundamental timing mismatch between subscription income and spending — your revenue comes in monthly, but expenses must be paid immediately. If cash flow isn't balanced correctly, a SaaS company can go broke even with healthy-looking income.
Unfortunately, budgeting for a SaaS business isn't the same as budgeting for your pocketbook. When you're building software, everything costs more than the sticker price. Add one feature to your SaaS product, and you'll pay for it multiple times: to maintain it, enhance it, test it, fix it, integrate it into your customers' systems, and then continually help them use it.
If you don't look at your product through a Total Cost of Ownership lens, by the time you realize you've run out of money, it will be too late to salvage it. SaaS businesses with small teams seldom include finance or operations professionals, so they're more likely to view money as a short-term obstacle. This leads to a reactive approach to solving cash flow problems rather than preemptively structuring the product design and development process to keep costs down.
In this guide, you'll learn the best way to design and build your SaaS product to keep your expenses low throughout its entire lifecycle. We'll do this by dissecting the two most significant sources of superfluous expenses: Product Design and Engineering.
Reduce SaaS Product Design Costs
Cost problems begin early — when you're designing how your product should work. Let's look at what choices you can make during the product design stages that will lower your total expenses well into the future.
Focus on User Experience
User Experience (UX) isn't "Customers say it looks nice." Some ugly apps have great UX. What's important is giving your customers a frictionless, self-directed path straight to value.
Do users get lost or stuck looking for what they want in your app? If they do, you're going to pay for it. It will cost you in support tickets, extra onboarding, knowledge base creation and maintenance, support rep time, retargeting and churn reduction efforts, and more. Minimize or eliminate these by making it intuitive and straightforward for your customers to get what they came for.
Here are a few ways to improve UX:
If you want something to get better, test it. UX is no different.
You want to use quantitative data to make smaller changes and qualitative data to make more extensive changes such as sweeping User Interface (UI) modifications or adding new features.
Quantitative information is information about numbers. 87% of users do this, 75% use this feature within three months, 10% never use that feature. Put these numbers together, and they tell you a story, one you can use to fine-tune your customers' journey through your product.
Qualitative information is information about qualities — as in, "It's too hard to find the export tool," or "I wish there were bulk export to my CRM." This kind of feedback lets you learn things no amount of number gathering could have told you.
If you're in the early stages of a SaaS startup, you should be devoting a significant chunk of time to seeking early adopter feedback. Your first thousand customers will tell you how to turn the product you have now into one your next ten thousand customers will want to use.
If your product is already established, you should continue gathering and using both types of data to improve it further.
Automate Customer Workflows
Automate entire user workflows where possible. Build a path between customer desire and a positive outcome that requires minimal thought on their part — a design principle enshrined in Steve Krug's classic Don't Make Me Think.
Avoid introducing mental roadblocks and small frustrations; make the process of using your product as "downhill" as possible so that it's always easiest to do the right thing.
This is especially true during onboarding when potential customers are deciding if your product is right for them. In the past, B2B customers cared more that software could do what they needed, regardless of how easy it was to use. Nowadays, customers expect business products to provide the same positive emotional feelings as consumer apps do. So make things easy for them.
Build Help Directly Into the Product
Onboarding works best when it helps customers find the value they care about in your product themselves, rather than making them sit through a training course. Offer unobtrusive guidance that can be easily hidden by experienced users, but make sure they know where to turn for help when they need it.
Make Buttons Clear and Obvious
Is it obvious what will happen when you click either of these buttons?
Many users disagree with designers about what "obvious" means, so this is a good use case for heat mapping.
Make sure you clearly label buttons with text that is unambiguous. If you must use "icon-only" buttons, make sure text tooltips pop up whenever users hover their mouse cursors over the icon.
Track Feature Usage
Track your users' activity to see which customers use which features. You want to build a product your ideal customers can't live without. So if your best 10% of customers never use feature X, but everyone else does, there's a strong argument for removing it.
Every feature you have first costs you money to create then continues to cost money to maintain and support as long as you keep it around. Keeping a redundant feature just because you already built it is shortsighted. The fact is, it's a sunk cost and is harming your bottom line.
Sunset Features Correctly
If you do decide to trim a feature, don't just unplug it. Some users may still use it, and others might just be surprised that it's no longer there. Instead, offboard users from the feature the same way you'd onboard them initially to your product. That is, as part of an app-wide, ongoing process of guiding their interactions to improve the value they get from your tool.
Don't Add New Features
A successful business tends to expand as time goes on. However, try to avoid adding new features to your product wherever possible. "Feature creep" kills apps and drowns businesses under additional sales, marketing, development, maintenance, and support costs.
Prioritize features ruthlessly using the MoSCoW method or something similar:
Focus on the highest-value features and don't try to fix problems with features that can be solved a better way.
If you're trying to solve revenue or profitability issues with new features, you're probably on the wrong track; those are usually marketing or brand messaging issues.
If you have customers crying out for a feature, it might be a good idea to give it to them. But most of the time, customers who are already using your product don't want you to add endless new functionality. They want you to fix the bugs in the features they already use daily.
Fix Bugs Before Adding Features
From a business perspective, there's not much difference between a feature request and a bug fix, at least on the surface. Both involve engineering costs, both offer value to customers, and both should be prioritized by cost/benefit in those terms.
But the calculation isn't so simple: bugs are more important than features from the customer's perspective because these are flaws in the tools they already use and rely on. Your bugs are costing your users money, adding friction and cash cost to the price of being your customer, and reducing the value you offer them. Those customers are going to churn.
Even more crucially, there's the technical perspective that if you don't fix a bug now, you might have to fix more of them later.
There's a programming best practice called Don't Repeat Yourself (DRY), which dictates that a programmer writes a particular piece of code only once. The programmer should reference that existing code elsewhere in the software any time they need to access its functionality. This technique saves the programmer from repeatedly typing out the same code in different parts of the software and avoids opportunities for human error.
But suppose the code the programmer is referencing has a bug in it. In that case, they will replicate the bug unintentionally throughout the codebase.
That creates a "contagious" bug that will add costs to all future maintenance until the source of the error is fixed. In other words: not fixing a bug has constant ongoing costs with the potential to escalate.
For these reasons, bug fixes should be prioritized above new features unless there's a rock-solid reason not to.
Charge for Features
If you have high-cost features that demand more development, maintenance, and support, it makes sense to put them in a higher price tier and charge users more for them. You can hide them from lower-tier customers or use them as bait to encourage conversions to a more expensive plan.
As a corollary to optimizing your product for your top users, it's also worth checking your prime features' UX. Maybe those features are only used by power users, not because they define a premium product, but because no-one else can understand them.
Be Careful When Using No-code and Open-Source Solutions
When NASA wants to test a rocket engine, they don't build a new rocket. They strap it to one they already know works.
When you build a product prototype or Minimal Viable Product (MVP), it's the functionality that counts. If that functionality already exists in an open-source software package or no-code product that you can customize, use it.
Be careful, though, as using pre-built technology isn't always the best choice to base a highly-specialized SaaS product.
For one thing, how a pre-packaged solution has been designed can negatively dictate how your product ends up working. This can lead to a diminished User Experience or force you to maintain features that you wouldn't otherwise build had you made everything in-house.
But also, sometimes it's just more time-consuming to customize something generic than to build what you need from scratch. Tearing out all of the unneeded functionality of a pre-built solution can take longer than just rolling your own.
If you encounter either of these issues, then as soon as you've validated your product concept, consider creating a fully-custom foundation for your product on its next iteration.
Avoid Mobile Apps if You Can
If your target audience is mobile-dependent and expecting to use a mobile app, then yes, you should make a mobile app. Fitness apps are an excellent example of this.
But for many markets, mobile apps just don't make sense.
For instance, in the education space, many schools are using old, low-power laptops and iPads in the classroom. Kids aren't allowed to use their phones at school, and teachers all have laptops or desktop computer access.
In this case, the only rationale for a mobile app would be if you need time-sensitive parent-teacher communications. Even then, you might be better off using an extant communication channel. A SaaS that targets school district admins probably doesn't need a mobile app.
But besides being inappropriate for some industries, there are other reasons to avoid mobile apps if you can:
High Development Costs
Building a mobile app means creating the same app in iOS and again in Android. That burden can be reduced, but not eliminated, by using cross-platform scripting solutions like NativeScript, React Native, or Flutter. Still, it's best to avoid this cost if possible.
High Maintenance Costs
Supporting mobile apps means an increasingly complex technology stack — you'll need mobile APIs, push notification solutions, tweaks for mobile client quirks to accommodate the way they process data and requests, and more. All this means more upfront development costs, more maintenance costs, and more support when things go wrong.
Will Anyone Use Your Mobile App?
Of all the reasons not to build a mobile app, whether someone will want to use it is the most overlooked.
People are still installing and using apps; that's true. And app installs rose alongside the pandemic.
But app marketplaces are increasingly pay-to-play, with organic installs lagging, and smartphone users' time spent on just three core apps:
Breaking into those top slots is challenging because the current players are entrenched. That's WhatsApp, Facebook and Messenger, Instagram, and YouTube.
So unless you're in the right niche, an app probably isn't a low-cost way to differentiate yourself and gain users. Instead, it's Engineering and Marketing dollars spent to enter a crowded marketplace with subpar usage and conversion numbers.
Mobile App Alternatives
Before you spend money building a mobile app, ask yourself if you can solve the problem another way:
Market Instead of Building a Mobile App
We've already seen that most apps are installed but rarely opened. For instance, most people only open travel apps when they want to travel. That's usually once or twice a year, not once or twice a week.
If you're in a market like this, it might be cheaper and more effective to use paid ads on search and social, together with well-targeted email marketing:
Use the ad network's vast amount of data to target users precisely when they're considering travel, then redirect them to your web app. This will be cheaper and faster to do than building and supporting a mobile app.
Consider a Progressive Web App
Progressive Web Apps (PWAs) are web apps that users can install on their home screens, similar to native mobile apps. Their advantage over pure mobile apps is that they use the same codebase as your web app while getting better usage. That makes them cheaper to build and potentially more profitable.
When Twitter switched to a PWA, they got a 65% increase in pages per session, 75% more Tweets, and their bounce rate dropped 20%. All of that with a 97%+ decrease in the size of their app.
If your only use case for a mobile app is to be visible on users' home screens, this could be the smart way to go.
If You Must Go Mobile, Cut Features
If you're building a mobile app alongside a desktop web app, putting the same full feature set into both apps might be a waste of time. After all, people use their phones and tablets differently than their computers.
For example, web designers aren't going to dive into Figma's full functionality on a smartphone. Actual design work will be taking place in front of the biggest screen and processor they can find. So there's no point even trying to cram the tractor engine of Figma under the lawnmower bonnet of a mobile app.
However, designers might still want to use their phones to read annotations other team members have made on their designs. In that case, allowing them to view the design on mobile without editing it makes sense. You can keep the editing functionality out of the mobile client and reap enormous cost savings.
Reduce SaaS Engineering Costs
It won't matter how lean and streamlined your Product Design process is if you have a wasteful Engineering team. You need to pay attention to how you implement your product too.
Paradoxically, the cheapest way to build software is not to try to save money on engineering. After all, what's built fast, breaks fast.
Instead, the best way to save engineering costs is to focus from the outset on quality and reliability rather than speed. Speed will happen on its own as a byproduct of a quality mindset.
What's unfortunate is that many young companies think of the race to their product launch as being a destination, when, in reality, it's just a milestone on the path to profitability. This is especially true, though not always, for those companies whose founders' backgrounds are in sales, marketing, or some other non-engineering area.
In these types of companies, engineers must resort to writing code optimized for "fast to write," not "easy to maintain" or even "works particularly well." While this practice will get your product out the door fast, it ends up vastly inflating your costs later, as I'll explain shortly.
Moving from product prototype to profitable SaaS company is like building the Wright Flyer, taking off, and then transforming it into a jumbo jet midair, one piece at a time. It's already hard enough, but base the whole process on hastily-written code from engineers watching the clock, and you'll regret it when it's time to add new features, fix pricing rules, or target new customer segments.
So, when you're considering engineering tactics, think about your long-term strategy. Don't just think "How will this pay off at the MVP point?" but also consider "Will our one-thousandth customer break it?" and "Will having extra bugs affect our fundraising efforts?"
With that in mind, let's look at some engineering strategies that will pay dividends in cost savings throughout the full life of your product:
Hire the Right Engineers
First and foremost, hire with the "Minimal Viable Engineer" in mind. Engineer wages are most SaaS startups' greatest expense. Anything that reduces them gives you more oxygen in the tank for launch.
Here's how to do that without ruining your product in the process:
One MVP, One Engineer
If your company is in the prototype or MVP stage, it should be possible to build your product with only one dedicated full-stack engineer.
When you build a product this way, one professional knows where everything is and how it all works. So if (when) something doesn't quite go right, you call your engineer up, and she says, "Oh yeah, I know what the problem is, " and she fixes it. You avoid delays caused by multiple developers needing to coordinate or a team member on vacation.
If you can't build your product this way, it's almost certainly for one of three reasons:
You made the wrong product or tech choices early on and are paying for them with inefficiency. If you follow this guide, you can avoid that.
You're suffering from "scope creep" and are overloading your product with unnecessary features. Work harder to discover what real minimum is and build that instead. More on this later.
Your business has advanced beyond the MVP stage, and you can afford multiple quality-focused engineers to deliver a better product. Throw in a Chief Technology Officer (CTO) and Product Manager to keep things running smoothly.
Now, you might be saying to yourself "Wouldn't having two engineers double our velocity?" Read on to see why this isn't the case.
Doubling Engineers Does Not Double Your Speed
Unfortunately, hiring another engineer doesn't double the amount of development work that gets done. Another engineer means more communication and coordination, more tooling and process, and more wages and vacations. This results in decreased per-engineer productivity, almost always.
An exception might be when both engineers have worked together on the same team for many years. In that case, they likely already have everything set up to get things done most effectively. But even then, your velocity is never doubled; there's always some overhead that will slow you down.
Always Get the Best Engineers You Can Afford
You've seen that two engineers aren't necessarily better than one during the early stages of your business. So if you're just hiring one person, you better make sure they're the best you can get.
With a senior-level engineer in your corner, you'll spend less upfront and much less down the line to repair and maintain code than if a less experienced engineer wrote it.
This is true in nearly every other role too. On average, highly-successful startups hire earlier, more often, and much more expensively. That's because high skill is an effect multiplier.
Specifically, a highly-skilled engineer will have the depth of knowledge to create exactly the functionality you want — and the breadth to do it with any of the dozens of tools and languages they're familiar with. They can help you with technology selection as well as execution, saving you hours of consideration every time you have to make a tech decision.
Imagine doing your taxes, then think about how quickly your accountant can complete the same task while simultaneously finding deductions you never knew existed. It's the same concept.
By contrast, junior and mid-level engineers often know only their piece of the puzzle. Nevertheless, they might still be highly confident in their ability to do anything due to the Dunning–Kruger effect:
There's a time and a place for the kind of competent specialism that junior engineers can bring to the table. It's when you're making enough that it makes economic sense. When your product is already established in the market, the need for senior-level strategic development is reduced, and specific types of maintenance and updates are more important. This is when junior engineers will save you money.
Choose Technology Wisely
Besides the engineers you hire, technology choices matter too. Let's look at how:
Don't Reinvent the Wheel
If you look under the hood of the cars produced lately, you'll find that many models all share the same internal parts: the same engine, same gearbox, and same drivetrain. Planes are no different; modern airline fleets consist of four aircraft models with two types of engine.
The components inside these machines are complex; engineering them to the point where they work reliably and don't suddenly break under stress takes enormous investment. It also inevitably takes time to iron out all of the kinks. So parts are reused between models whenever possible to save time and money.
It's the same with a SaaS product. If the technology you need already exists, use it — don't get stuck in the long grass trying to invent something better.
For example, if you set out to build your product using a PostgreSQL database running on Linux behind an Nginx web server, you're in good company. These technologies are part of the most popular tech stacks out there. Don't choose an experimental graph database, and don't write your own web server.
Popularity isn't the most critical metric when choosing a tech stack. Still, it increases the probability that all of the technology's common flaws have been encountered, documented, and GitHubbed to death.
Additionally, you'll be able to hire from a larger pool of skilled engineers, which is essential on two fronts:
- First, it means you can hire based on excellent references, great attitude, and outstanding performance — not because there are only three other people who can do the job, two are busy until 2045, and the other one's in jail. That's the start of a good movie, not a good project.
- Second, it means you can attract a better engineer for the money because they won't have to reinvent the wheel. Much of what software engineers do is stick together already-familiar elements in the correct way to build a working system. There are already pre-made solutions, libraries, and tech support channels for conventional tech stacks that can accelerate development and keep it on the rails.
Thus, innovative technology represents a risk that should be costed. Before you consider using something new and unproven, ask yourself: "What are the benefits?" and "Will it make potential delays or even failures worth it?"
Make Your App Monolithic
It's recently become fashionable for startup engineering teams to split their code into separate microservices due to marketing influence from infrastructure providers like Google Compute Engine.
Microservices are separate chunks of software that talk to each other over a network. They perform the same function as if they were stuck together in a single codebase. This unified codebase is often called a monolith.
Unfortunately, each microservice you build incurs high additional costs in terms of the engineers required to develop and maintain them. They also necessitate a DevOps role to manage the whole system continually.
Because of this overhead, stay away from massive microservice systems like Kubernetes until you have a clear and present need for them. Similarly, don't start a new product with microservices. For most SaaS companies, there are cheaper and better ways to architect your applications that will keep costs down.
Get Out of the Library
As much as possible, minimize the number of third-party libraries your software uses. These libraries provide pre-made functionality, saving your engineers from reinventing the wheel and writing the code themselves.
However, reliance on third parties can become a liability. These libraries need to be continuously updated to stay secure and free of bugs. Every time libraries are updated, they could potentially change how they behave, including how they interact with your proprietary code.
Experienced library engineers will make sure that they never introduce any "breaking changes" into a mature and heavily-used library. Unfortunately, many libraries are not mature, stable, or created by seasoned engineers.
So using libraries minimally is a good rule of thumb. But when you have to, using older, more reliable libraries is your safest bet.
You don't control the engineers who work on these libraries, so you have no say in how they write them. You get a tactical win and a strategic loss; better to write your own code whenever possible.
Update for Security
If you use third-party libraries — and it's nearly unavoidable — you need to make sure they're updated to maintain security. One of the most prolific digital security mistakes is the widespread failure to keep security patches up to date.
This is a dull, pedestrian matter — if you do it. If you don't, things can get exciting quickly. You can end up with adult content, inappropriate ads, hate speech, or malware on your website.
Or you can suffer a data breach that blows big holes in customer trust and costs a fortune to recover from. This has happened to Equifax, eBay, and LinkedIn. They kept calm and carried on, but the average business doesn't recover from a major data breach.
Review your server logs, and you'll likely see hacking attempts happening not just every day but sometimes several times a second. These attacks happen as botnets and professional criminals run automated scans for known vulnerabilities in software libraries. Apart from social engineering, it is their primary way into your systems. Shut the door.
Don't Build a Single Page App
SPAs — Single Page Applications — are a frequent choice for implementing SaaS applications' data-heavy dashboards and tooling. But when it comes to keeping costs down, they're often the wrong choice.
When you build a traditional web app, the heavy processing takes place mostly on the server-side; the front end is the levers, but the gearbox is on the server.
In an SPA, the front end is the levers and the gearbox. That means that the user's web browser handles processing that would typically happen on the server, which reduces server load and makes for a snappier User Interface (UI).
So far, so good. Aren't these significant advantages?
You can see the case for SPAs here, but experience has caused me to disagree with the conclusions in that article. It isn't a popular opinion in web development circles these days, but in my view, SPAs don't pay their way.
Suppose you're selling leads, e-commerce advantages, or something else that requires a data lake and some real processing power. In that case, all of that data can only live server-side. It's just too big, or too private, to hand over to a user-controlled front end.
When you build an SPA, you have to develop the front end tool to display this data. You must also recreate something similar server-side to handle all of the front end's requests for data. As a result, you end up doing nearly all the same work twice!
In terms of overall project costs, the payoff isn't worth it most of the time. Server space isn't expensive compared to engineer time for most purposes; neither is processing power. For both, you'll likely be relying on an Infrastructure-as-a-Service (IaaS) provider like Amazon Web Services (AWS), which allows you to keep costs low by scaling up and down as necessary.
Instead, building your app twice in two different places means:
Business rules and application logic are replicated on the frontend and server in two different programming languages. When logic code is duplicated, it becomes more costly for engineers to find and update it later when business needs change.
Two teams must build two applications, in addition to an API to link them together so they can communicate. It's going to take longer to write two systems instead of just one.
Impaired User Experience
User Experience (UX) is worse in SPAs because they must load all their code from the server when a user first visits your website. This means your customers will see a loading spinner for several seconds — much longer than they likely have the patience for. As a result, you'll lose conversions to free trials and be beaten out long term by competitors with better UX.
It's possible to prerender the first page of an SPA, but this takes even more engineer time to set up and is more fragile than an "old-fashioned" web app.
Bad SEO and Slow Page Load Speed
Page load speed is a Google ranking factor. Unlike some of the other factors that affect how high you rank in search engines, it's directly under your control.
As you saw above, SPAs load slower. Build a traditional Multi-Page App (MPA), and you'll not only save yourself engineer wages but also marketing dollars.
When you spread code across multiple systems, you exponentially increase the chances for bugs and glitches, and make it exponentially harder to find and fix them. With an SPA, you'll have two applications built by two teams in two different languages, doing more or less the same thing. And if the bug is not in one of those systems, maybe it's in the API layer. It's going to take additional expensive engineer time to fix things whenever a bug crops up.
When You Should Use an SPA
I'm not pro- or anti-SPA. I just think they're overused and chosen without enough critical consideration. There are times when you should use an SPA:
Interactivity is Important
You're Building a Mobile App Too
Suppose you're in a mobile niche, so you're building a mobile app alongside a responsive web app. In that case, you can share some of the same code between apps using technology like React Native, NativeScript, or Flutter. If your strategy is "get a bunch of mobile users, quick," this makes sense.
However, suppose you're building a web-based MVP and planning to develop a mobile app sometime down the line. In that case, you'd be saving pennies in efficiency gained by sharing code and wasting dollars in inefficiency using the wrong architecture.
Build your MVP the best way — which in most cases is a traditional multi-page web app. Then build the mobile app later, when you have user feedback and bug histories to guide you.
Offline Mode is a Must
How often does this happen? Rarely, but sometimes your users need to use your web app without an Internet connection. In that case, an SPA is ideal. A use case is an urban transit app meant to be used underground and in low connectivity areas.
There are ways you can get the best of both worlds. Tools like Turbolinks, Unpoly, and Phoenix LiveView let you build speedy frontend experiences that feel SPA-like to users — snappy and fast — but without the downside of having to download a million lines of code into their browser. Code and app state still lives server-side, and app complexity is significantly reduced. You also get fast load and response times, with no SEO penalty.
Don't Believe the Hype
The popularity of SPAs illustrates another pitfall you'll encounter when choosing technology.
Tech giants like Google or Facebook often create trends and fashions in the tech industry because they have vested interests in propagating them. In particular, they often develop solutions that address the problems only multi-billion-dollar transnational corporations have but market them like they're for everybody.
Big tech wants their technology adopted as widely as possible so they can recruit efficiently from the resulting pool of engineers trained in these tools. They also want to form third-party ecosystems that plug neatly into their businesses.
Technical and non-technical decision-makers alike can't help but fall for these tactics. I mentioned Kubernetes earlier, which has been adopted by many hip startups. It solves a challenging scaling problem for large corporations, but it's costly premature optimization if you're a new SaaS company.
The same goes for technology like Artificial Intelligence (AI) or Blockchain. There have been many remarkable advances in these fields in recent years; however, much of it is still in the early stages or with unclear use cases. Many businesses have tried adopting these technologies because they're new and sound exciting. But in most cases, their business needs would have been better served with a more "boring" technology.
So if even your engineers are recommending much-hyped technology to you, how can you differentiate the truth from the propaganda?
That's when I like to refer to the Gartner Hype Cycle:
It demonstrates the stages that technologies tend to pass through before they reach maturity. If you're ever considering a new technology, try to figure out where it is in its hype cycle and focus on "plateau of productivity" solutions only.
Follow a Quality-First Workflow
Once you have the right engineers using the right technology, it's just a matter of having the right development process. Here's how to structure that to save the most money possible:
Encourage Maintainable Code
Have engineers focus on creating code that other engineers find easy to read, understand, and maintain.
This mindset will let you sidestep the most prominent money sucks at each stage of the app's life. You'll see fewer bugs as engineers will spend less time deciphering code and more time creating new features. That translates into faster time to market — a crucial metric for SaaS growth.
Engineers spend up to 80% of their time reading code, not writing it. Cut that in half, and you've earned the equivalent of two extra engineers by merely having easily-comprehensible code.
It's even true if you only have one engineer. If they come back four months later to code they wrote in a hurry, are they going to remember what it all means? Probably not.
What about if your original engineer moves on from the company? Will their replacement be able to pull up a chair and start work, or will they need to spend weeks figuring out your codebase?
Everything needs to be simple and easy to understand to save the most money possible. So spending a little extra time writing good code upfront will save you money down the line.
Regular Code Reviews
Development teams should do regular code reviews to test the comprehensibility of each other's code. If one engineer can't understand another's code easily, it needs to be fixed so they can. Over time, you can use the results of these reviews to build a code style guide that will result in consistently easy-to-understand code.
Do code reviews before merging code with the main codebase to catch bugs and make sure that another engineer can easily understand everything. This process also helps transmit information around the engineering team about how the whole codebase works and lets junior engineers benefit from senior engineers' knowledge.
You might remember hearing about this as part of something called Extreme programming back in the day, but I don't think it's that extreme. Basically, one engineer codes while the other watches for bugs. It also lets engineers share knowledge on how to program better and results in cleaner code and higher-quality output across the whole team.
Annotate Code Clearly and Write for Humans
Use code comments to explain why your code is doing what it's doing, rather than what it's doing. The code itself will tell the engineer what it does, which is dependent on knowledge of the programming language. But another engineer might not know why the code is there in the first place because that's dependent on insight into your specific industry or problem domain.
For example, an engineer can look at the code below and see that we're adding two variables together and storing the result in the variable x:
let x = foo + bar;
But what does that represent in our business domain? Someone new to the codebase won't know what those numbers mean unless you write it down somewhere and make it clear.
This code does the same thing, but it's obvious why it exists in the first place:
/** * Increase the count of car parts in our inventory by * the number of items in the user's shopping cart. */ let newInventoryCount = oldInventoryCount + shoppingCartItemCount;
Any extra information required to understand the code should be pointed out within the code itself. Consider using a tool like ExDoc to parse your code and turn comments into an easy-to-reference HTML document.
Insist on Using a Linter
Engineers should be using a linter as a matter of course. A linter is a static programming tool used to catch errors and bugs, goofy syntax, and weird-looking code as it's written. It's like spellcheck for code. It ensures that engineers follow a consistent style and coding best practices, resulting in the whole codebase being clean and consistent.
Encourage Automated Testing
Automated tests are code that tests code. Essentially, they mimic someone going through your app to check whether it works. Because a computer is running the tests, it goes much faster than doing it manually. This saves time in the long run because it avoids the need to have a human look at each part of your application every time a change is made, which can happen dozens of times per day.
Some engineers write their tests before they write their code, which helps to clarify purpose and ensure code is simple to reason about.
Because of the immense time savings and reliability guarantees automated testing can provide, application code should be written to make it easy to write automated tests.
Use Continuous Integration / Continuous Delivery
Use a Continuous Integration / Continuous Delivery (CI/CD) service like GitHub Actions, Bitbucket Pipelines, or Jenkins, to deploy your code. Engineers push their code to this service; then, it runs all the project tests, linters, and any other checks you've mandated. Only then does it automatically package the code and deploy it to live servers.
This workflow lets you formalize all your Quality Assurance (QA) right into your routine, meaning engineers don't need to think about it. You're turning a complex, error-prone, and precarious process into a comfortable, robust workflow, saving hours of development time.
Use Staging Servers
Test code on staging servers before going live to production. These staging servers should be identical to your live servers. That will allow you to test the product under near-identical conditions — including performing strenuous tests that you wouldn't want to risk on a real server. You can also check for bugs before you release the code.
Dedicated Quality Assurance
If you have a larger team, you should have a dedicated QA Engineer who focuses solely on Quality Assurance. Their whole job is to identify flaws and bugs and to test everything written by every other engineer on the team until it breaks. A QA person shouldn't be used as a replacement for automated tests or inline QA processes, only to augment them.
- Be systematic and consider your product's Total Cost of Ownership. Use strategy to eliminate unnecessary costs, including maintenance and support costs.
- Is your feature essential? Avoid feature creep and focus on onboarding, user success, and bug fixing.
- People are your biggest expense. The more skilled they are, the more efficient they are, so — paradoxical as it sounds — expensive is often cheaper in the long run.
- Select simple, reliable technology with a proven track record.
- Aim for as few third-party dependencies as possible, including code libraries.
- SPAs, Mobile apps, and Microservices can be a trap. Only build them if you have to.
- Make code easy to read, maintain, fix, and duplicate. Always assume general skill and specific ignorance: write for a good engineer who's never seen your code before.
- Always test, stage, and review code.