It must conform to a shared-nothing architecture; that is, microservices don't share data in databases with each other!
It must only communicate through well-defined interfaces, either using APIs and synchronous services or preferably by sending messages asynchronously. The APIs and message formats used must be stable, well-documented, and evolve by following a defined versioning strategy.
It must be deployed as separate runtime processes. Each instance of a microservice runs in a separate runtime process, for example, a Docker container.
Microservice instances are stateless so that incoming requests to a microservice can be handled by any of its instances.