MicroservicesCommunicationintermediate
Updated:

Microservices Communication Interview Questions and Answers

5 min read

How microservices talk — synchronous vs asynchronous, REST vs gRPC vs messaging, and the failure handling interviewers really probe — answered properly.

TL;DR – Quick Answer

Microservices communication interviews center on one axis: synchronous request/response (REST, gRPC) versus asynchronous messaging (Kafka, RabbitMQ). Interviewers test whether you pick the right style for a use case, understand the failure modes of each — temporal coupling and cascading failure for synchronous, eventual consistency and duplicate delivery for asynchronous — and know how to make calls safe with timeouts, retries with backoff, and idempotency. Naming protocols is easy; reasoning about failure is what scores.

On This Page

How services talk to each other is the most consequential design choice in a microservices system, so it is one of the most heavily interviewed. The question is never really "which protocol?" — it is "do you understand what each communication style costs you when the network misbehaves?" This page covers the communication questions asked across levels, and the failure-handling follow-ups that decide the answer.

What are the two fundamental styles of inter-service communication?

Synchronous request/response, where the caller blocks until it gets an answer (REST over HTTP, gRPC), and asynchronous messaging, where the sender publishes a message and does not wait (Kafka, RabbitMQ, SQS). Everything else is a variation on these two.

The trade-off is the whole answer. Synchronous is intuitive and gives an immediate result, but it creates temporal coupling: if the callee is down or slow, the caller is down or slow too. Asynchronous removes that coupling and absorbs load spikes, but you pay with eventual consistency, more moving parts, and the need to handle duplicate messages.

Interview note: Trap: "which is better?" Neither — the senior answer names the use case. Immediate answer needed → synchronous. Fire-and-forget, fan-out, or decoupling → asynchronous.

REST vs gRPC — when would you choose gRPC?

Choose gRPC for internal, high-throughput, low-latency service-to-service calls: it uses HTTP/2, binary Protobuf serialization, and a strongly typed contract, and it supports streaming. Choose REST/JSON at the edge and where universality, human-readability, and browser support matter.

gRPC's typed contract catches breakage at compile time and its binary format is smaller and faster than JSON. The cost is that it is less approachable — you cannot curl it as easily, and browser support needs a proxy. A common architecture is gRPC between internal services and REST exposed through the gateway.

Interview note: Follow-up: "what does Protobuf give you over JSON?" A schema, smaller payloads, faster (de)serialization, and generated client/server stubs — with schema evolution rules that keep old and new clients compatible.

How do you handle a synchronous call to a service that is slow or down?

Every remote call gets a timeout; a circuit breaker stops sending requests to a failing dependency; and where sensible, a fallback returns a degraded response instead of an error. An unbounded blocking call is the root cause of most cascading failures.

@CircuitBreaker(name = "catalog", fallbackMethod = "fallback")
public Product getProduct(String id) {
    return webClient.get()
        .uri("/products/{id}", id)
        .retrieve()
        .bodyToMono(Product.class)
        .timeout(Duration.ofMillis(800)) // never wait forever
        .block();
}

private Product fallback(String id, Throwable t) {
    return Product.placeholder(id); // degrade gracefully
}

The point to make explicit: a circuit breaker without a timeout barely helps, because a call that never returns never trips the breaker.

What is a cascading failure, and how does async help avoid it?

One slow service causes callers to block and exhaust their thread pools, so they fail too, and the failure climbs the call graph. Timeouts, circuit breakers, and bulkheads contain it — and asynchronous messaging avoids it structurally, because the sender never blocks on the consumer.

If Orders publishes an event instead of calling Payments directly, a Payments outage means the event waits in the broker, not that Orders falls over. That resilience is the main reason teams push write-side workflows onto a message backbone.

Why is idempotency essential, and how do you implement it?

Because messaging is at-least-once and clients retry, the same operation can arrive twice — an idempotent operation makes duplicates harmless. Implement it with a unique key (request ID or event ID) that you record once processed, so a repeat is a no-op.

if (processed.putIfAbsent(event.getId(), Boolean.TRUE) != null) {
    return; // duplicate delivery — already handled
}
applyPayment(event);

Interviewers use this to separate people who have run a broker from people who have only read about one. Exactly-once processing is achievable with idempotency plus dedup; exactly-once delivery across a network is essentially a myth.

How do retries make things worse, and how do you retry safely?

Naive immediate retries against an overloaded service multiply the load and cause a retry storm that deepens the outage. Retry only idempotent operations, use exponential backoff with jitter, cap the attempts, and let the circuit breaker cut retries off entirely when the dependency is clearly down.

Interview note: Trap: "add retries to make it reliable" — half right. Retries plus backoff plus idempotency plus a breaker is reliable; retries alone are a foot-gun.

How do you get data from another service without a shared database?

Call its API synchronously when you need it live, or subscribe to its events and maintain a local read model (data duplication) when you need it fast and can tolerate eventual consistency. You never reach into another service's database.

The event-carried-state-transfer approach — services publish their changes and interested services keep their own copy — removes runtime coupling entirely, at the price of managing stale data windows. Which you pick depends on freshness requirements.

How do you trace a request across several services?

Propagate a correlation/trace ID through headers so every service logs it, and use distributed tracing (Zipkin, Jaeger, OpenTelemetry) to see per-hop latency and causality. Without it, debugging a multi-hop call is grepping logs by timestamp and hoping.

What happens to in-flight requests during a deployment?

Use rolling deployments with health checks and graceful shutdown so a terminating instance drains in-flight requests before exiting, and clients retry idempotent calls against healthy instances. For async consumers, the broker simply redelivers unacknowledged messages to another consumer.

What interviewers really test

Communication questions are a proxy for one thing: do you design for the network being unreliable? Anyone can name REST and Kafka. The candidates who pass describe timeouts, backoff, idempotency, and eventual consistency without being prompted, because they have watched a missing timeout take down a system. Prepare to defend one synchronous choice and one asynchronous choice from real work.

Pair this with the API gateway questions, where edge communication and protocol translation come up, and the event-driven architecture set for the asynchronous half in depth. Ground the concepts with the microservices learning path, and use a focused mock interview to practice defending a communication design under follow-up pressure.

Frequently Asked Questions

What is the difference between synchronous and asynchronous communication?
Synchronous means the caller waits for a response (REST, gRPC) — simple but it couples the caller's availability to the callee's. Asynchronous means the sender publishes a message and moves on (Kafka, RabbitMQ) — decoupled and resilient, but the result is eventually consistent and duplicates can occur.
When should microservices use messaging instead of REST?
Use messaging when the work can happen later, when you want to decouple producer and consumer availability, or when multiple services need to react to the same event. Use synchronous REST or gRPC when the caller genuinely needs an immediate answer to proceed.
Is REST or gRPC better for microservices?
gRPC is faster and strongly typed over HTTP/2 with Protobuf — good for internal, high-throughput, low-latency service-to-service calls. REST/JSON is more universal, human-readable, and browser-friendly. Many systems use gRPC internally and expose REST at the edge.
Why is idempotency important in microservices communication?
Because networks fail and messages get delivered at least once, the same request or event can arrive twice. An idempotent operation produces the same result no matter how many times it runs, so retries and duplicates do not corrupt state — it is the safety net for unreliable delivery.
What is a cascading failure and how do you prevent it?
A slow or failing service causes its callers to block, filling their thread pools, which makes them fail too, propagating up the chain. You prevent it with timeouts on every call, circuit breakers to stop hammering a broken dependency, and bulkheads to isolate resources.

Want to Build Your Career in Java Full Stack with AI?

Join CodeBegun and train with working industry engineers — Explore the Java Full Stack program

Apply for Demo Class →
Siva Prasad Galaba
Founder, CodeBegun · Staff Engineer

Founder of CodeBegun. 15+ years building Java systems at companies like Crunchyroll. Teaches Java, Spring Boot and system design the way the industry actually works, and mentors students through projects, mock interviews and placement preparation.

Technically reviewed by CodeBegun Technical TeamLast reviewed 16 July 2026 LinkedIn
Chat with us