Are Serverless Services Worth It?
Tags: applicationdevelopment, serverless
Published: 2023-04-05 12:10:15


I recently wrote about how [serverless services can be used anywhere](https://dev.to/aws-heroes/the-solution-architects-guide-to-serverless-5ae1). I tried to change the messaging around these services to help people understand they aren't exclusively for serverless applications. You can use serverless services for any part of your app that runs on-prem, in a Kubernetes cluster, or anything in between. 

After I published it and started receiving feedback on it, I realized I might have put out a dangerous message. Yes, serverless services are great - they are inexpensive to run, elastically scale from 0 to hundreds of thousands of requests per second, and require little-to-no configuration to run. But *it might not always the right choice*.

When I was running one of the early cloud teams at my last company, I was blissfully unaware of the hole I was digging for myself. I made the decision to invest my engineering team's time to learn how to build serverless architectures, design NoSQL data models, structure multi-tenant systems, heck, even learn JavaScript. All of which are sought-after, highly marketable skills. In my head, I was doing the company a favor. 

However, as our production deadline approached and we began running through operational readiness reviews, it became clear I hadn't made the best decision. The engineering team was the only set of people who knew how to support the app. Our front-line support team, technical support, implementation staff, data conversion specialists, and maintenance teams had no idea how the app worked. They were used to on-prem, single tenant, .NET, apps with a SQL database. Not all this fancy new cloud tech.

As a result, I held countless meetings, training classes, one-on-ones, and brainstorming sessions trying to figure out how to catch the rest of the company up. Ultimately it resulted in the engineering team becoming multi-faceted and taking on support, maintenance, implementation, and data conversion through our early production days. This led to slower innovation and minimal development of new features because the team was busy doing a dozen other things, effectively taking out one of the huge benefits of going serverless (pace of development). 

It made me realize that while serverless services look amazing on paper, there are a few things to consider before taking the leap.

## Find The ~~Right~~ Best Tool For The Job

When people talk about the phrase "the right tool for the job" they often refer to the saying "*when all you have is a hammer, everything is a nail.*"

Deciding to implement serverless services in your existing applications doesn't quite track with that metaphor. I prefer to use a different analogy. Imagine you're putting in a pool. The first step in the process is to dig a big hole!

The right tool for the job is a shovel. But *the best* tool for this job is an excavator. Why take months digging a pool-sized hole with a shovel when you could get it done in a week with an excavator?

Well, for one - using an excavator requires skill. You can't just go out, rent one, and expect to dig the perfect pool. It takes time to learn how to move the bucket, stick, and boom together as a single unit to do exactly what you want. You could hire someone to come dig it for you, but that's expensive. If they miss something, they'd need to bring the excavator back out, get the person back out there, and redo the work. It's a lot of effort for a quick maintenance job. 

Everyone knows how to use a shovel and many people already have one. You could get started today!

Does this feel familiar? I've seen tons of decisions made that rely solely on *how much something costs right now*. The upfront costs feel more expensive than the long-term costs, so the decision was made to go a different way despite the obvious benefits. 

Sometimes sticker shock blinds us to [some of the other costs](https://dev.to/aws-heroes/understanding-total-cost-of-ownership-of-serverless-and-container-applications-59eg) we decide to take on when going for an option that is "right, but not the best." When digging a pool by hand, what are you going to do with all the displaced dirt? It needs to be hauled away somewhere. And if you're digging by hand, you need to give yourself a few months lead time to be ready by summer, which might mean you're trying to use a shovel to dig through frozen dirt in the winter. Not a task I'd want to take on, personally.

What's are the priorities of your company? Is it being scrappy and getting something out as quickly as possible? Is it building software "right" in an easily-maintainable way? Do you have the funds to invest in R&D right now? 

> The difference between the *right tool* and the *best tool* is how it aligns with the priorities of the company. 

If my objective was to build a pool at the lowest possible cost, the shovel is the best tool. If my priority is to be swimming by summertime, the excavator is best.

## Trade-offs

Every decision in software is a trade-off. By choosing to do one thing, you opt to not do another. Let's talk about some of the trade-offs you make when you decide to use a serverless service.

* **Slow down to speed up** - When you choose to go serverless for the first time, it can be dangerous to jump into the deep end and build straight away. Cloud vendors like AWS make it so easy to build applications with these services that it's tempting to just start. *Don't do that*. Take the time to learn how the services scale, what the SLAs are, how you invoke them, and what downstream services you have in your app. If you rush into development, [disaster awaits with open arms](https://dev.to/aws-heroes/the-risks-of-moving-too-quickly-with-serverless-development-5d2p). Deciding to go incorporate a serverless service is an investment.
* **Uptime support** - On the surface, this seems a little tongue-in-cheek. Serverless services are highly available minimal downtime and no maintenance windows. If you're used to deploying batches of changes during a routine maintenance window, you might have some relearning to do. With the ridiculously high uptime, your support staff needs to adjust to expectations and availability guarantees. If you're implementing a single serverless service into a large application, this might not be a problem. But if you're rearchitecting or doing greenfield development, you might want to run it by support to verify they can handle 24/7 uptime. 
* **People don't like change** - A personal pet peeve of mine is the "*we've always done it this way, so we're going to keep doing it this way*" mentality. But I know many people disagree with me on that. When you get into unfamiliar territory, you'll get people who argue and refuse to do something because it's not what they know. I had to take on a significant amount of extra work with my decision to move to a NoSQL database because our data conversion specialists refused to adjust their processes. Keep this in mind when you have people who have been operating a specific way for a while.
* **Every change is a big deal** - Serverless services are often priced in a pay-for-what-you-use model. When dealing with serverless functions, every millisecond of compute time is charged on your monthly bill. When working with serverless data services like [MongoDB Atlas](https://www.mongodb.com/atlas/database), [Momento](https://gomomento.com), or [Amazon DynamoDB](https://aws.amazon.com/dynamodb/), you pay for data size - usually in the form of data transfer costs, read and write units, and storage. This means that performance matters! The faster your app, the less you pay. The smarter you structure your dataset, the cheaper the data costs. When reviewing code changes, every line could directly impact cost. This puts a brand new emphasis on pull requests to scrutinize data changes, the addition of new 3rd party packages, and logic updates.
* **Loss of "control"** - I know a lot of developers who like to control every aspect of their environment. They control server patches, load balancer configurations, network infrastructure, you name it. Serverless services follow a [shared responsibility model](https://docs.aws.amazon.com/whitepapers/latest/security-overview-aws-lambda/the-shared-responsibility-model.html) between the consumer and the vendor. The vendors take ownership of all the infrastructure and hardware management for you. They abstract away the routine complexities and provide mechanisms for consumers to use their services with the fewest amount of moving parts possible. Consumers can't fine-tune CPUs or opt to skip a particular patch. Depending on your perspective, this could be the best thing ever or a complete showstopper.

## Is It Worth It?

From my experience, incorporating serverless services is a no-brainer (but I'm sure you expected that [coming from me](/blog/allen.helton/how-i-became-an-aws-serverless-hero)). However, there truly is no one-size-fits-all answer.

Not every company wants to deal with the trade-offs of learning something new and disrupting the status quo. It slows down development while the organization gets up to speed on the new tech. It puts in place new patterns and expectations around availability. It shifts focus to performance, CI/CD, and data management. Things are just... different.

If you can get past the initial investment, the results are amazing. Reduced costs, no infrastructure management, and rapid pace of development are all direct outcomes of shifts to serverless services. That said, the switch to serverless is a constant investment in upskilling.

Ever since I started with cloud development, I've been on a mission to learn as much as I can. That's [why I started blogging](https://dev.to/aws-heroes/lessons-learned-from-writing-50-blog-posts-in-a-year-1cbp)! You're never done learning with serverless. It evolves so rapidly that you have to make a conscious effort to keep up with it. 

Is it worth it? Well, it depends. It depends on your priorities, willingness to learn something new, and capability to boost the skills of across all departments of your org.

Happy coding!