Should a new product start with microservices?
Usually not, and we say so on the first call. Most early products should not start with microservices: the boundaries between services are guesses until real users show where the load and the change actually are, and every wrong guess means moving data between databases. A modular monolith - one deployable application with strict internal modules, each owning its own tables - ships faster and costs less to run.
It is also the honest answer to "scalable application development": a well-built monolith scales a long way by running more copies behind a load balancer, adding read replicas and caching, and moving slow work onto queues. We recommend splitting when several teams block each other's releases, when one part needs very different scaling, or when one failure keeps taking everything down.
How do you break up an existing monolith without a rewrite?
With the strangler fig pattern, not a big-bang rewrite. A routing layer - an API gateway or reverse proxy - goes in front of the monolith first, so nothing changes for clients. Then one capability at a time moves into its own service, and the gateway sends that traffic to the new code while everything else still reaches the monolith. When the old module receives no traffic, it is deleted.
We usually start with a capability that changes often or scales differently - notifications, search, payments - rather than the core everything else depends on. Its data moves with it: change data capture keeps both sides in sync during the move, an anti-corruption layer stops the old data model leaking into the new service, and a feature flag can route traffic back if something goes wrong.
How do you draw service boundaries, and who owns the data?
Around business capabilities - what domain-driven design calls bounded contexts - such as ordering, payments, catalogue and identity, never around technical layers like "the database service". The test is change: a new feature should usually touch one service. If two services always have to be deployed together, the boundary is wrong and you have built a distributed monolith.
Each service owns its data in its own schema or database, and no other service reads its tables. Others get what they need through its API, or keep a local copy updated from its events. A workflow that spans services, such as placing an order and taking payment, runs as a saga with compensating steps instead of a distributed transaction, and the transactional outbox pattern publishes an event only when the change it announces was actually saved.
REST, gRPC or events - how should services talk to each other?
Split the question in two. At the edge, clients call one gateway, and the public contract is usually REST with OpenAPI - covered on our API development page - or a single graph when many client apps need different shapes of the same data, which our GraphQL API development team builds.
Inside, keep synchronous chains short. When a service needs an answer now, it calls another over gRPC or REST with a timeout, a limited retry and a circuit breaker. When it only needs to announce that something happened - an order placed, a payment settled - it publishes an event to Kafka or RabbitMQ, and interested services react in their own time. A request that waits on five services in a row is only as available as the weakest of them.
What observability does a microservices system need from day one?
More than logs. When one checkout request crosses the gateway, orders, inventory and payments, distributed tracing is the only way to see where it slowed down or failed. We instrument every service with OpenTelemetry, carry the trace ID through every HTTP call, gRPC call and event, and send traces, metrics and logs to one place - Grafana with Prometheus, or your cloud's managed tools.
- Structured logs that carry the trace ID, so one search shows a request's whole path
- Request rate, errors and duration per service and per endpoint
- Consumer lag on every Kafka topic or queue, so a stuck consumer is caught early
- Alerts tied to service-level objectives, not to CPU graphs
- A service map that shows which service calls which
What does a microservices architecture cost to run, and do you need Kubernetes?
More than the monolith it replaces, and the gap is mostly fixed cost: every service needs its own pipeline, database, dashboards and alerts, and the cluster, load balancers and observability data are billed whether traffic is high or low. Team size matters as much. Each service needs an owning team; if you have fewer engineers than services, the architecture is ahead of the organization. Custom work on a single service starts from $3,699, depending on the work. The build itself is typically $8,000-$25,000 over 2-8 weeks for a custom MVP.
Kubernetes is our default once a system has enough services to need scheduling, autoscaling and rolling deploys in one place, run as a managed cluster - EKS, GKE or AKS - so nobody operates the control plane. For three or four services, a managed container service such as AWS ECS or Google Cloud Run is cheaper. Our Docker and Kubernetes development team also takes on cluster work by itself.
What should you ask before hiring microservices developers?
Ask them to walk you through a monolith they split: which service came out first, why, how the data moved, and what they would change. Ask how a workflow across three services stays consistent when the second one fails - a good answer mentions sagas, idempotent consumers and an outbox, not a shared database. Ask how they stop one service's change from breaking another (consumer-driven contract tests), and what they open first when latency spikes (a trace, not a log file).
One strong backend developer is not a microservices team: a production system also needs someone on the cluster and pipelines, someone on the data model, and someone on call. Miracuves provides that as a fixed-scope custom build or a retainer from $2,299/month, with an NDA from day one and every service's code, Helm charts and runbooks handed over as yours.