App Dev Best Practices App Modernization architecture cloud native microservices Modernization Best Practices Tanzu Application Service

Should That Be a Microservice? Part 7: The Freedom to Choose the Right Tech for the Job

In the first part of this series, we laid out a set of principles to help you understand when microservices can be a useful architectural choice. In this post, we explore one those factors, the freedom to choose the right tech for the job, in more detail.

Microservices are a great architectural option when your teams need to choose the right tech for the job. But when does this scenario arise, and why does it matter? It is tempting to let résumé-driven design justify the selection of a new language, but it is a terrible reason to opt for a microservice architecture.

You should consider a new technology stack when there are recognizable benefits to your business! For example:

  • New business initiatives are best served with a non-relational database.

  • A different programming language greatly simplifies an algorithm.

  • Evolving business requirements suggest an event-driven solution that depends on a distributed streaming platform.

It is tempting to reach for a new toy after reading about a new database or sitting through a webinar on an evolving language. But it is a much more nuanced decision. Before you add complexity to your environment, be sure you have compelling reasons to do so.

As we’ve done in other parts of the series, we can start with a look back at how we got here.

When monoliths were the only choice

Let’s start with a ride in the Wayback Machine, to a time when monoliths ruled the data center. In the past, companies tried to standardize on a limited set of technologies. Many development organizations described themselves by their primary technology (i.e., as a Java shop or a .NET team). In the same vein, developers used their favorite language as an adjective, as in “I’m a JavaScript developer.”

In the era of the monolith, these colloquialisms made sense. Companies standardized on one tech stack because they could:

  • Develop deep expertise with a given language and the associated frameworks,

  • Shuffle people between teams to balance workloads and cross-pollinate ideas throughout the organization,

  • Simplify the hiring and training process, and

  • Allow operations teams to specialize in a single environment.

All was not puppies and rainbows during this era of software development, though. Things are never that simple—tradeoffs are unavoidable! Language standardization often exacerbated currency issues. For example, shared servers lead to months-long slogs to move from version N-2 to version N-1. (Okay, let’s be real, N-7 to N-3.) In the amount of time it took to complete an upgrade, a major new version of the technology was often released. Eighteen months of freezes, testing, change-review boards, and frustration was not the winning recipe for outstanding relationships with our business team.

Bespoke infrastructure often forced the “lowest common denominator” for library and language versioning as well. Even if a team wanted to move to the latest and greatest version of its preferred tech stack, it may have been limited by the “slowest moving” legacy application in the house. How often have you heard a variation of “We can’t upgrade to X until the Wombat application is ready for it”? Unless there was a burning platform moment (looking at you, Windows XP), most product owners prioritize shiny new features over paying down technical debt.

All that said, very few organizations were ever truly homogeneous. Mergers and acquisitions happen, inevitably bringing new technologies to the business. Some far-flung requirement would lead to the introduction of a new database or language. But, as a rule, organizations wanted to limit the technology solutions they supported.

Shift the balance (just not too far)

As we have noted before, cloud computing opened up a new universe of options and flexibility.

Elastic infrastructure combined with microservices architectures enabled us to break free from the tyranny of a singular technology stack. No longer were you required to pound a square peg into a round hole. You could simply pick up a round peg! If a different database simplified a solution, or if using an alternative language greatly reduced the codebase for a service, you were free to choose the right technology to fit the problem. The promise of polyglot programming was finally realized!

However, there is a massive downside to a polyglot approach. To paraphrase the mathematician in Jurassic Park: Just because you can doesn’t mean you should.

In today’s world, your business is evolving at an ever-increasing pace. To keep up, you need to ship high-quality code very quickly. Developers should be free to choose the right tools for the job. So how do you empower your teams responsibly? Glad you asked!

Avoid stack sprawl

Every developer has their favorite languages, frameworks, and tools. Products will have their own deployment pipelines, monitoring suites, and preferred metrics. Without some guardrails you will quickly discover there are an awful lot of ways to “do that one thing,” depending on who you ask. How do you develop any amount of consistency if, well, nothing is the same?

Technical sprawl is only one consequence of a polyglot environment, though. Consider the challenges in building a development team that uses Go, Haskell, Java, .NET, Ruby, Python, and JavaScript. Developers can always learn a new language, but it takes time to start thinking in a given technology. The cognitive overhead of disparate stacks can be worse than standardizing on a one-size-fits-all model.

And don’t underestimate the inherent challenges of maintaining a polyglot environment. For example, think about how much effort it takes to stay current on one stack. Now multiply that toil by four or five, and remember you’ve signed your development team up for a long-term support agreement on each and every one of those frameworks.

Too much choice can be just as painful. (Side note for all the parents out there: It’s much easier to give kids the choice between two or three things rather than a limitless universe of options.) Teams will spend hours (more likely days) “debating” which one to use.

So don’t be afraid to establish some guardrails or guide posts. For example, you may decide to standardize on the JVM or to provide well-worn paths to production on a limited set of tech stacks. Teams may be allowed to venture off that path, but they take on the responsibility of that decision—you build it, you run it.

Provide adequate guidance to your teams to help them make the right technology choice. Decision trees are invaluable. Say you have the choice between three different message queues. Create a flowchart asking the relevant questions to help teams narrow down their options.

The key word is “micro”

There are as many definitions of microservices as there are companies employing the pattern. But as long as you and your team have a shared understanding of the term within your organization, it doesn’t really matter how you define it. However, it is important to stress the micro part of microservices.

We can debate what we mean by small, but I’ve always been partial to the idea that a microservice is a service that can be rewritten in two weeks or less. Emphasizing the “small” frees us to experiment—and more importantly, correct course if our hypothesis is proven incorrect.

The more time you’ve invested in a solution, the less open you are to making changes. How committed are you to code you’ve spent five minutes on? What about something you spent a few weeks crafting? If you keep your microservices small, you can afford to spend an iteration on an experiment. After all, you’ve only committed a short amount of time to it. If you are wrong, you can easily adjust.

In the era of the monolith, trying out something new was a recipe for disaster. How could you just mix in a little Clojure/Scala/Groovy/JavaScript into your existing application? With longer development cycles, you might not discover where the “gotchas!” are until it is too late to change course. By focusing on smaller bits of functionality, you have the room to practice hypothesis-driven development on your technology stack as well.

I can’t stress this point enough: While polyglot programming might be the most common reason for developers to embrace microservices, you must weigh the pros and cons of a diverse tech stack for your organization.

Very few organizations fully adopt the level of developer autonomy that says, “Use whatever you want.” But those that do apply the requisite response of, “You build it, you run it.” A chef in a professional kitchen brings her own knives to work and is responsible for maintaining the tools of her trade. When a team brings its own technology stack to a project, they, too, are accountable for those decisions.

Be sure you aren’t practicing résumé-driven development. Instead ask whether this particular language or framework provides demonstrable business advantages, or if are you simply trying to add it to your CV.

Focus your energy on process standardization, not stack standardization

The most agile teams are the most disciplined. This seems counterintuitive at first. But when you think about it a bit more, you realize that you gain velocity and responsiveness when you eliminate variation and manual effort. 

Consider the case of West Corp. West handles millions of conference calls and millions of emergency 911 calls each year. It has thousands of developers pushing code to Pivotal Cloud Foundry®. The executive leadership of West encourages development teams to use the right tool for the job. Instead of mandating a given stack, CTO Thomas Squeo focuses his team on three things: test-driven development, instrumentation, and automation.

 When you have this discipline in place, along with a modern platform like Pivotal Cloud Foundry, it’s much easier to feel comfortable with a diverse ecosystem of developer tools. Empowering your teams to use the right tool for the job leads to more engaged developers. Consequently, you can more easily meet the demands of a constantly changing business environment. Want to learn more about West Corp? Watch this video

The microservices journey

We started this series with a modest goal: to rid the world of superfluous microservices by giving you a set of principles to help you make the right decision. As we wrote nearly a year ago:

There are many good reasons to use a microservices architecture. But there are no free lunches. The positives of microservices come with added complexity.

We hope this series has helped you have more rational and informed discussions about when and how to best use microservices in your enterprise. This topic is one of the most important you’ll face in the next five years, so we will return to it often.

Thanks for reading, and please microservice responsibly!

Read the rest of this series:

Part 1: Should that be a Microservice? Keep These 6 Factors in Mind
Part 2: Multiple Rates of Change 
Part 3: Independent Life Cycles
Part 4: Independent Scalability
Part 5: Failure Isolation
Part 6: Simplify External Dependencies

Want to learn more about microservices? Join us at the next SpringOne!

Want more architectural guidance for your modern apps? Be sure to download Nathaniel's eBook Thinking Architecturally.