Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

5 design principles for microservices

January 11, 2022
Bob Reselman
Related topics:
ContainersKubernetesMicroservices
Related products:
Red Hat OpenShift

Share:

    Microservices are becoming increasingly popular to address shortcomings in monolithic applications. This article is the first in a three-part series that explains the design principles for a microservices-oriented application (MOA), how companies tend to evolve to use microservices, and the trade-offs.

    Check out the other articles in this series:

    • How applications evolve from monolith to microservices
    • The disadvantages vs. benefits of microservices

    What is a monolithic application?

    The term monolithic applies to tightly integrated applications where it is hard to change one function without also recoding other parts of the application. Components in a monolithic application might be distributed among many machines, but they remain highly dependent on one another. Not only does the addition of a new feature have ripple effects throughout the code, but deploying the change requires retesting and redeploying the entire application. These upgrades can be labor-intensive and hazardous, particularly when an application has hundreds of thousands or even millions of users.

    When IT departments had the luxury of releasing software every six months, this type of upgrade process was tolerable. But modern business demands force releases to happen weekly, daily, or even more often, so the labor and risk inherent in upgrading monolithic applications become untenable.

    Something has to change. That change is the transformation to the microservices-oriented application (MOA).

    What is a microservices-oriented application?

    An MOA breaks its logic into small, well-encapsulated services that are distributed over several computing devices in a loosely coupled manner. Each service lives at a distinct IP address on the network and exposes a public interface that is language-agnostic. The most popular type of language-agnostic interface is a REST API, but other models for communication exist. Microservices also generally get deployed as containers when it's time to go live.

    Typically, some mechanism behind the scenes coordinates the microservices to create a unified application experience. Because each microservice is well-encapsulated, its code can be updated quickly with minimal side effects. This makes maintenance easier and scaling faster.

    The purpose of this series is to describe the principles involved in choosing the microservices architecture, along with the pros and cons. This first article presents the five basic principles of microservices-oriented application design. The next part of the series explains the evolution of modern applications and why they lead to an MOA, and the third part finishes the series with trade-offs that microservices make.

    Five design principles for microservices

    The benefits of an MOA can be significant, but they come with a price. You need to know a thing or two about microservice design to implement an MOA effectively—you can't make it up as you go along. A microservice application must follow these five principles:

    • Single concern
    • Discrete
    • Transportable
    • Carries its own data
    • Inherently ephemeral

    Let’s look at the details of each principle:

    1. Single concern microservice

    Having a single concern means that a microservice should do one thing and one thing only. For example, if the microservice is intended to support authentication, it should do authentication only. This means that its interface should expose only access points that are relevant to authentication. And internally, the microservice should have authentication behavior only. For example, there should be no side behavior such as providing employee contact information in the authentication response.

    Having a single concern makes the microservice easier to maintain and scale. This goes hand-in-hand with the next principle.

    2. Discrete microservice boundaries

    A microservice must have clear boundaries separating it from its environment. Another way to think about this principle is that a microservice must be well-encapsulated. This means that all logic and data relevant to a microservice's single concern must be encapsulated into a single deployment unit. Examples of units for discrete deployment are a Linux container, a WebAssembly binary, a .NET DLL, a Node.js package, and a Java JAR file, to name a few.

    Also, a discrete microservice is hosted in a distinct source control repository and is subject to its own CI/CD (continuous integration/continuous delivery) process. The microservice becomes part of a larger application after deployment. But from development through testing to release, each microservice is isolated from all other microservices. When a microservice is discrete, it becomes easily transportable, which is the next principle.

    3. Transportable microservice

    A transportable microservice can be moved from one runtime environment to another with little effort. Perhaps currently, the optimal form of a transportable microservice is a Linux container image.

    Usually, a Linux container image is hosted in an image repository such as Red Hat Quay.io. The container image can be targeted to any destination from that image repository, so a variety of applications can use the image. This is all possible because the microservice is encapsulated into a discrete deployment unit that can be transported to any destination. The encapsulation removes from developers all tasks except configuration and deployment.

    This transportable feature also makes microservices easier to use in an automated or declarative deployment process.

    4. Carry-its-own-data microservice

    A microservice should have its own data storage mechanism that is isolated from all other microservices. The only way data can be shared with other microservice is by way of a public interface that the microservice publishes.

    This principle imposes some discipline on data sharing: For instance, the particular data schema used by each microservice has to be well-documented. The design rules out behind-the-scenes hanky-panky that makes data hard to access or understand.

    The principle that a microservice carries its own data is hard for many developers to accept. The common argument against a microservice carrying its own data is that the principle leads to a proliferation of data redundancy.

    For example, imagine an e-commerce application. That application might have a microservice that manages customer profile information. The application has another microservice that handles purchases. When the principle that every microservice carries its own data is in force, it's quite possible that the purchases microservice might have data that is redundant with the customer profile microservice. Such data redundancy goes against the grain of developers who embrace the DRY principle (Don't Repeat Yourself).

    On the other hand, developers who embrace the carry-its-own-data principle understand the benefits and have adjusted accordingly. When a microservice carries its own data, any strange behavior is confined within the microservice.

    When microservices try to share data, one microservice can make a change that causes a side effect in another microservice. This is fundamentally a bad way of doing business.

    One of the key benefits of a microservice carrying its own data is that it enforces all of the other principles. This is particularly important when it comes to the final principle.

    5. Inherently ephemeral

    The principle that a microservice is ephemeral means that it can be created, destroyed, and replenished on-demand on a target easily, quickly, and with no side effects. The standard operating expectation is that microservices come and go all the time; sometimes due to system failure or scaling demands.

    This scenario is common in a Kubernetes environment that uses the Horizontal Pod Autoscaler (HPA) to accommodate scaling demands. The HPA creates and destroys containers according to momentary demands. Each time a container is created, an IP address is assigned dynamically. There are even situations where port numbers will be assigned dynamically too. Such are the impacts of ephemeral computing.

    As a result, this principle that a microservice is ephemeral has two basic implications. The first is that developers need to create microservices that are good citizens in the application domain. This means implementing graceful startup and shutdown behavior within the microservice.

    The second implication is that when programming their microservices, developers rely on runtime configuration settings to define external dependencies. This hand-off to an external configuration differs greatly from creating a monolithic application, where most dependencies are known at design time and are baked into the code. In microservice development, they are not. Instead, developers rely upon dynamic configuration to establish dependencies that are both internal and external to the microservice.

    As strange as it might sound, coding to an ephemeral environment requires developers to accept that there are known unknowns that will be apparent at runtime. Hence, the need to program accordingly.

    Conclusion

    The next article in this series explains how some companies incrementally move from a monolithic application to microservices. You can find additional resources on our microservices topic page.

    Last updated: September 20, 2023

    Related Posts

    • How applications evolve from monolith to microservices

    • Distributed transaction patterns for microservices compared

    • Patterns for distributed transactions within a microservices architecture

    • Application modernization patterns with Apache Kafka, Debezium, and Kubernetes

    • Top 10 must-know Kubernetes design patterns

    Recent Posts

    • How Kafka improves agentic AI

    • How to use service mesh to improve AI model security

    • How to run AI models in cloud development environments

    • How Trilio secures OpenShift virtual machines and containers

    • How to implement observability with Node.js and Llama Stack

    What’s up next?

    kubernetes patterns ebook

    The evolution of microservices and containers in recent years significantly changed the way we design, develop, and run software. In this e-book, you'll learn to create cloud-native applications with Kubernetes as a runtime platform and build container images directly within the cluster.

    Get the e-book
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue