Mainly because I get asked all the time about microservices and I'm tired of having to remember on the spot:

What is a microservice?

A microservice is a service with a design focus towards the smallest autonomous boundary.

What is a service?

(From Clemens) A service is software that:

  • is owned, built, and run by an organization
  • is responsible for holding, processing, and/or distributing particular kinds of information within the scope of a system
  • can be built, deployed, and run independently, meeting defined operational objectives
  • communicates with consumers and other services, presenting information using conventions and/or contract assurances
  • protects itself against unwanted access, and its information against loss
  • handles failure conditions such that failures cannot lead to information corruption

In short, a service is software that exhibits autonomy. It's built, deployed, and run independently from other services. It manages its own information and how it communicates to/from the outside world. It handles failures so that its information isn't lost.

Do microservices require containers/Docker?

No.

Do microservices require Go/node.js/Elixir/.NET Core?

No.

Do microservices require any specific technology or stack?

No.

I put my app in a container, is it a microservice?

Containers have no bearing on whether or not software is a microservice or not.

Why do people talk about microservices along with containers/serverless/PaaS?

Those are technologies that can help remove technical barriers for the size of services.

What is a monolith?

A monolith is software whose design, information model, and interface combine multiple competing and interfering domains into one single application and data model. There is no longer consensus from users and designers of the software on terms, modeling, information design, or interface. The coupling between competing models makes future changes to the system difficult or impossible.

If I'm not doing microservices, am I building monoliths?

No, not necessarily. You can build services without a focus on the smallest but still autonomous boundary.

If I have a single application and database, is it a monolith?

No, not necessarily. You may have a single software system whose model is cohesive enough that there aren't competing/interfering domains. If that application meets the defined operational and business needs of the organization, then it does have the negative indicators of a monolith.

Similarly, not all data models are "anemic domain models". A domain model is only anemic if it's a data model masquerading as a domain model.

Can a microservice be too small?

Yes, if it no longer meets the characteristics of a service, the software is no longer a service, but a module, function, or data store.

Can a microservice be too big?

A microservice is a service with a design focus on the smallest possible autonomous boundary. What is possible and desirable is highly contextual on the domain, people, technology, and goals of the business.

Should I start with microservices or a monolith?

Microservices focus on the smallest autonomous boundary for a service. If the domain is ambiguous enough or business goals volatile enough, you may wind up building modules that can be independently deployed but not run because they depend on other modules to function.

Perhaps a better question is "should I start with a single application or modular architecture?" The answer is highly dependent on the team, business, and domain maturity.

How should microservices communicate?

In a manner and medium that does not violate the fundamental definition of a service. If a communication protocol introduces coupling that violates the design traits of a service, then you must re-evaluate that protocol, or re-evaluate your service boundaries.

As an example, services that solely communicate via RPC introduce process (and likely temporal) coupling such that the services are no longer autonomous and independent services, but modules within a larger service boundary.

Should I have a single repository (monorepo) or repository per service?

This depends on your delivery pipeline. If you can own, build, deploy, and run your service in a single source control repository independent of others, this may be an option. You may decide to organize repositories around systems, applications, organizations, services, modules, etc. Repository boundaries are (somewhat) orthogonal to service boundaries. But it may make your life easier to just have repositories per service.

If you feel forced to build a single repository to host your services to enable changes easier, then you don't have microservices, but modules. Your services aren't independent or loosely coupled to other services, and therefore aren't services.

Should I do RESTful services or async, durable messaging?

These choices are orthogonal to microservices. Choose what makes sense for the communication protocol you are designing and the constraints you have, keeping in mind the fundamental definition of a service.

I typically chose event-driven architectures as inter-service communication, but this can be achieved via a variety of transport protocols, and is never a universal decision. Avoid making universal decisions such as "everything must use RESTful web services", especially because most "RESTful APIs" are merely RPC-over-HTTP.

Should I use streams or queues/brokers to dispatch events to others?

You can do both, as both have quite different designs and constraints, benefits and drawbacks. Fundamentally, though, just as your service should avoid strongly coupling yourself to others, you should avoid directly exposing internal state changes as external events. Contracts exposed to outside your service boundary will change at a different pace and reason than internal state/communication.

For example, exposing your event-sourced aggregate's events directly to outside subscribers is not much different than giving out a database connection string to a read-only view of your database.

Should I do microservices?

It depends, building services as small as their autonomy allows is a different way of building services, that usually results in more of them. It affects more than just a developer, to the entire value delivery chain from concept to production. It usually involves imbuing a DevOps culture and mentality, but the ramifications stretch upstream as well.

The bigger question to ask is - is our software delivery value stream delivering its value at the speed the business needs? And if not, is the cause of our bottleneck in delivery that we don't have small enough services to align agility more closely? If so, then microservices are a good choice to consider.