<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Preeti Sharma</title>
    <description>The latest articles on DEV Community by Preeti Sharma (@shpreeti).</description>
    <link>https://dev.to/shpreeti</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2256414%2Ff2cf2c56-5c32-4b20-a604-9e76a0f2120c.png</url>
      <title>DEV Community: Preeti Sharma</title>
      <link>https://dev.to/shpreeti</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shpreeti"/>
    <language>en</language>
    <item>
      <title>Building Production-Grade Resilience in Microservices with Resilience4j</title>
      <dc:creator>Preeti Sharma</dc:creator>
      <pubDate>Sun, 12 Apr 2026 17:07:16 +0000</pubDate>
      <link>https://dev.to/shpreeti/building-production-grade-resilience-in-microservices-with-resilience4j-147a</link>
      <guid>https://dev.to/shpreeti/building-production-grade-resilience-in-microservices-with-resilience4j-147a</guid>
      <description>&lt;p&gt;In the &lt;a href="https://dev.to/shpreeti/how-the-circuit-breaker-pattern-prevents-cascading-failures-in-microservices-3nbi"&gt;previous article&lt;/a&gt;, we explored how the Circuit Breaker Pattern prevents cascading failures in microservices and how to implement it using Resilience4j.&lt;/p&gt;

&lt;p&gt;In one real production scenario, a payment service slowdown didn’t fail immediately — it just became slower and slower.&lt;/p&gt;

&lt;p&gt;Within minutes, thread pools got exhausted, requests piled up, and multiple services went down — even though the service never “crashed.”&lt;/p&gt;

&lt;p&gt;This is where basic circuit breaker setups fall short.&lt;/p&gt;

&lt;p&gt;Production systems deal with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;unpredictable traffic spikes&lt;/li&gt;
&lt;li&gt;partial failures&lt;/li&gt;
&lt;li&gt;slow downstream services&lt;/li&gt;
&lt;li&gt;resource exhaustion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To truly build resilient microservices, we need to go beyond the basics.&lt;/p&gt;

&lt;p&gt;In this article, we will cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Limitations of basic circuit breaker setups&lt;/li&gt;
&lt;li&gt;Advanced Resilience4j configurations&lt;/li&gt;
&lt;li&gt;Handling slow calls and timeouts&lt;/li&gt;
&lt;li&gt;Combining multiple resilience patterns&lt;/li&gt;
&lt;li&gt;Observability and monitoring&lt;/li&gt;
&lt;li&gt;Real-world best practices&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🚨 Why Basic Circuit Breakers Fail in Production
&lt;/h3&gt;

&lt;p&gt;A simple setup like:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@CircuitBreaker(name = "paymentService", fallbackMethod = "fallback")&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;works in demos — but often fails in production.&lt;/p&gt;

&lt;p&gt;Common issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The circuit opens too early or too late&lt;/li&gt;
&lt;li&gt;Slow services are not treated as failures&lt;/li&gt;
&lt;li&gt;No visibility into system health&lt;/li&gt;
&lt;li&gt;Threads get blocked due to long waits&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Result: Either unnecessary failures or system overload.&lt;/p&gt;




&lt;h3&gt;
  
  
  ⚙️ Advanced Circuit Breaker Configuration
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Fine-tuning Failure Detection
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;resilience4j&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="na"&gt;circuitbreaker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;instances&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;paymentService&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="na"&gt;slidingWindowSize&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;
       &lt;span class="na"&gt;minimumNumberOfCalls&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
       &lt;span class="na"&gt;failureRateThreshold&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents the circuit breaker from reacting to small traffic bursts or temporary glitches.&lt;/p&gt;

&lt;p&gt;Key idea:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don’t react to very small sample sizes&lt;/li&gt;
&lt;li&gt;Tune based on real traffic patterns&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🐢 Handling Slow Calls (Critical in Real Systems)
&lt;/h3&gt;

&lt;p&gt;Not all failures throw exceptions.&lt;br&gt;
In many real systems, latency increases before failures happen — and ignoring this is one of the biggest mistakes engineers make.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;slowCallRateThreshold&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt;
&lt;span class="na"&gt;slowCallDurationThreshold&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If 60% of calls take more than 2 seconds&lt;/li&gt;
&lt;li&gt;Circuit breaker will treat it as a failure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 This is crucial for preventing &lt;strong&gt;thread pool exhaustion&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  ⏱️ Adding Timeouts with TimeLimiter
&lt;/h3&gt;

&lt;p&gt;Circuit breakers do not stop long-running calls.&lt;/p&gt;

&lt;p&gt;We need TimeLimiter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@TimeLimiter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"paymentService"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@CircuitBreaker&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"paymentService"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fallbackMethod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"fallback"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;processPayment&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; 
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; 
        &lt;span class="n"&gt;restTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getForObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/payment"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; 
    &lt;span class="o"&gt;);&lt;/span&gt; 
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Long calls are terminated&lt;/li&gt;
&lt;li&gt;System resources are protected&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🔄 Combining Resilience Patterns
&lt;/h3&gt;

&lt;p&gt;Real-world systems use &lt;strong&gt;multiple patterns together&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  1️⃣ Retry + Circuit Breaker
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Retry handles temporary failures&lt;/li&gt;
&lt;li&gt;Circuit breaker handles persistent failures
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;resilience4j.retry&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="na"&gt;instances&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;paymentService&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;maxAttempts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
   &lt;span class="na"&gt;waitDuration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;500ms&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2️⃣ Bulkhead Pattern
&lt;/h4&gt;

&lt;p&gt;Prevents one failing service from consuming all resources.&lt;/p&gt;

&lt;p&gt;Two types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Thread pool isolation&lt;/li&gt;
&lt;li&gt;Semaphore isolation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Protects your system from overload&lt;/p&gt;

&lt;h4&gt;
  
  
  3️⃣ Rate Limiter
&lt;/h4&gt;

&lt;p&gt;Controls traffic to downstream services.&lt;/p&gt;

&lt;p&gt;Use when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;APIs have rate limits&lt;/li&gt;
&lt;li&gt;The downstream service is sensitive to load&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  📊 Observability: The Game Changer
&lt;/h3&gt;

&lt;p&gt;Without monitoring, circuit breakers are just guesswork.&lt;/p&gt;

&lt;p&gt;Enable actuator:&lt;br&gt;
&lt;code&gt;management.endpoints.web.exposure.include: health, metrics&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Track:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;failure rate&lt;/li&gt;
&lt;li&gt;slow call rate&lt;/li&gt;
&lt;li&gt;circuit state transitions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Integrate with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prometheus&lt;/li&gt;
&lt;li&gt;Grafana&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 This helps you tune configs based on real data&lt;/p&gt;


&lt;h3&gt;
  
  
  🧠 Designing Effective Fallbacks
&lt;/h3&gt;

&lt;p&gt;Fallbacks should be meaningful.&lt;/p&gt;

&lt;p&gt;Bad fallback:&lt;br&gt;
return null;&lt;/p&gt;

&lt;p&gt;Good fallback strategies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;return cached data&lt;/li&gt;
&lt;li&gt;return default response&lt;/li&gt;
&lt;li&gt;show user-friendly message&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;fallback&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Payment service temporarily unavailable. Please try again."&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  ⚠️ Common Production Mistakes
&lt;/h3&gt;

&lt;p&gt;❌ Same config for all services&lt;br&gt;
❌ Ignoring slow responses&lt;br&gt;
❌ No timeout configuration&lt;br&gt;
❌ Too aggressive retries&lt;br&gt;
❌ No monitoring setup&lt;/p&gt;




&lt;p&gt;🏗️ Real-World Flow&lt;br&gt;
Let’s revisit the earlier example:&lt;br&gt;
&lt;code&gt;Client → Order Service → Payment Service&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With resilience:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retry handles temporary issues&lt;/li&gt;
&lt;li&gt;The circuit breaker stops repeated failures&lt;/li&gt;
&lt;li&gt;TimeLimiter avoids long waits&lt;/li&gt;
&lt;li&gt;Bulkhead isolates resources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Result: System stays stable even under failure&lt;/p&gt;




&lt;h3&gt;
  
  
  🏁 Final Thoughts
&lt;/h3&gt;

&lt;p&gt;Circuit breakers are just one piece of the resilience puzzle.&lt;/p&gt;

&lt;p&gt;To build production-grade systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tune configurations carefully&lt;/li&gt;
&lt;li&gt;Combine multiple patterns&lt;/li&gt;
&lt;li&gt;Monitor everything&lt;/li&gt;
&lt;li&gt;Design meaningful fallbacks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not to eliminate failures.&lt;br&gt;
👉 The goal is to &lt;strong&gt;handle failures gracefully without impacting the entire system&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Failures are not rare events — they are inevitable.&lt;/p&gt;

&lt;p&gt;What separates a stable system from an outage is how well it is designed to handle those failures.&lt;/p&gt;

&lt;p&gt;Circuit breakers, timeouts, retries, and bulkheads are not optional optimisations — they are fundamental to building reliable systems.&lt;/p&gt;

</description>
      <category>java</category>
      <category>microservices</category>
      <category>springboot</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>Building Production-Grade Resilience in Microservices with Resilience4j</title>
      <dc:creator>Preeti Sharma</dc:creator>
      <pubDate>Sun, 12 Apr 2026 17:07:16 +0000</pubDate>
      <link>https://dev.to/shpreeti/building-production-grade-resilience-in-microservices-with-resilience4j-1cme</link>
      <guid>https://dev.to/shpreeti/building-production-grade-resilience-in-microservices-with-resilience4j-1cme</guid>
      <description>&lt;p&gt;In the &lt;a href="https://dev.to/shpreeti/how-the-circuit-breaker-pattern-prevents-cascading-failures-in-microservices-3nbi"&gt;previous article&lt;/a&gt;, we explored how the Circuit Breaker Pattern prevents cascading failures in microservices and how to implement it using Resilience4j.&lt;/p&gt;

&lt;p&gt;In one real production scenario, a payment service slowdown didn’t fail immediately — it just became slower and slower.&lt;/p&gt;

&lt;p&gt;Within minutes, thread pools got exhausted, requests piled up, and multiple services went down — even though the service never “crashed.”&lt;/p&gt;

&lt;p&gt;This is where basic circuit breaker setups fall short.&lt;/p&gt;

&lt;p&gt;Production systems deal with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;unpredictable traffic spikes&lt;/li&gt;
&lt;li&gt;partial failures&lt;/li&gt;
&lt;li&gt;slow downstream services&lt;/li&gt;
&lt;li&gt;resource exhaustion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To truly build resilient microservices, we need to go beyond the basics.&lt;/p&gt;

&lt;p&gt;In this article, we will cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Limitations of basic circuit breaker setups&lt;/li&gt;
&lt;li&gt;Advanced Resilience4j configurations&lt;/li&gt;
&lt;li&gt;Handling slow calls and timeouts&lt;/li&gt;
&lt;li&gt;Combining multiple resilience patterns&lt;/li&gt;
&lt;li&gt;Observability and monitoring&lt;/li&gt;
&lt;li&gt;Real-world best practices&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🚨 Why Basic Circuit Breakers Fail in Production
&lt;/h3&gt;

&lt;p&gt;A simple setup like:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@CircuitBreaker(name = "paymentService", fallbackMethod = "fallback")&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;works in demos — but often fails in production.&lt;/p&gt;

&lt;p&gt;Common issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The circuit opens too early or too late&lt;/li&gt;
&lt;li&gt;Slow services are not treated as failures&lt;/li&gt;
&lt;li&gt;No visibility into system health&lt;/li&gt;
&lt;li&gt;Threads get blocked due to long waits&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Result: Either unnecessary failures or system overload.&lt;/p&gt;




&lt;h3&gt;
  
  
  ⚙️ Advanced Circuit Breaker Configuration
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Fine-tuning Failure Detection
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;resilience4j&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="na"&gt;circuitbreaker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;instances&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;paymentService&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="na"&gt;slidingWindowSize&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;
       &lt;span class="na"&gt;minimumNumberOfCalls&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
       &lt;span class="na"&gt;failureRateThreshold&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents the circuit breaker from reacting to small traffic bursts or temporary glitches.&lt;/p&gt;

&lt;p&gt;Key idea:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don’t react to very small sample sizes&lt;/li&gt;
&lt;li&gt;Tune based on real traffic patterns&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🐢 Handling Slow Calls (Critical in Real Systems)
&lt;/h3&gt;

&lt;p&gt;Not all failures throw exceptions.&lt;br&gt;
In many real systems, latency increases before failures happen — and ignoring this is one of the biggest mistakes engineers make.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;slowCallRateThreshold&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt;
&lt;span class="na"&gt;slowCallDurationThreshold&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If 60% of calls take more than 2 seconds&lt;/li&gt;
&lt;li&gt;Circuit breaker will treat it as a failure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 This is crucial for preventing &lt;strong&gt;thread pool exhaustion&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  ⏱️ Adding Timeouts with TimeLimiter
&lt;/h3&gt;

&lt;p&gt;Circuit breakers do not stop long-running calls.&lt;/p&gt;

&lt;p&gt;We need TimeLimiter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@TimeLimiter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"paymentService"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@CircuitBreaker&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"paymentService"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fallbackMethod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"fallback"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;processPayment&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; 
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; 
        &lt;span class="n"&gt;restTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getForObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/payment"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; 
    &lt;span class="o"&gt;);&lt;/span&gt; 
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Long calls are terminated&lt;/li&gt;
&lt;li&gt;System resources are protected&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🔄 Combining Resilience Patterns
&lt;/h3&gt;

&lt;p&gt;Real-world systems use &lt;strong&gt;multiple patterns together&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  1️⃣ Retry + Circuit Breaker
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Retry handles temporary failures&lt;/li&gt;
&lt;li&gt;Circuit breaker handles persistent failures
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;resilience4j.retry&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="na"&gt;instances&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;paymentService&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;maxAttempts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
   &lt;span class="na"&gt;waitDuration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;500ms&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2️⃣ Bulkhead Pattern
&lt;/h4&gt;

&lt;p&gt;Prevents one failing service from consuming all resources.&lt;/p&gt;

&lt;p&gt;Two types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Thread pool isolation&lt;/li&gt;
&lt;li&gt;Semaphore isolation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Protects your system from overload&lt;/p&gt;

&lt;h4&gt;
  
  
  3️⃣ Rate Limiter
&lt;/h4&gt;

&lt;p&gt;Controls traffic to downstream services.&lt;/p&gt;

&lt;p&gt;Use when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;APIs have rate limits&lt;/li&gt;
&lt;li&gt;The downstream service is sensitive to load&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  📊 Observability: The Game Changer
&lt;/h3&gt;

&lt;p&gt;Without monitoring, circuit breakers are just guesswork.&lt;/p&gt;

&lt;p&gt;Enable actuator:&lt;br&gt;
&lt;code&gt;management.endpoints.web.exposure.include: health, metrics&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Track:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;failure rate&lt;/li&gt;
&lt;li&gt;slow call rate&lt;/li&gt;
&lt;li&gt;circuit state transitions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Integrate with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prometheus&lt;/li&gt;
&lt;li&gt;Grafana&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 This helps you tune configs based on real data&lt;/p&gt;


&lt;h3&gt;
  
  
  🧠 Designing Effective Fallbacks
&lt;/h3&gt;

&lt;p&gt;Fallbacks should be meaningful.&lt;/p&gt;

&lt;p&gt;Bad fallback:&lt;br&gt;
return null;&lt;/p&gt;

&lt;p&gt;Good fallback strategies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;return cached data&lt;/li&gt;
&lt;li&gt;return default response&lt;/li&gt;
&lt;li&gt;show user-friendly message&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;fallback&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Payment service temporarily unavailable. Please try again."&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  ⚠️ Common Production Mistakes
&lt;/h3&gt;

&lt;p&gt;❌ Same config for all services&lt;br&gt;
❌ Ignoring slow responses&lt;br&gt;
❌ No timeout configuration&lt;br&gt;
❌ Too aggressive retries&lt;br&gt;
❌ No monitoring setup&lt;/p&gt;




&lt;p&gt;🏗️ Real-World Flow&lt;br&gt;
Let’s revisit the earlier example:&lt;br&gt;
&lt;code&gt;Client → Order Service → Payment Service&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With resilience:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retry handles temporary issues&lt;/li&gt;
&lt;li&gt;The circuit breaker stops repeated failures&lt;/li&gt;
&lt;li&gt;TimeLimiter avoids long waits&lt;/li&gt;
&lt;li&gt;Bulkhead isolates resources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Result: System stays stable even under failure&lt;/p&gt;




&lt;h3&gt;
  
  
  🏁 Final Thoughts
&lt;/h3&gt;

&lt;p&gt;Circuit breakers are just one piece of the resilience puzzle.&lt;/p&gt;

&lt;p&gt;To build production-grade systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tune configurations carefully&lt;/li&gt;
&lt;li&gt;Combine multiple patterns&lt;/li&gt;
&lt;li&gt;Monitor everything&lt;/li&gt;
&lt;li&gt;Design meaningful fallbacks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not to eliminate failures.&lt;br&gt;
👉 The goal is to &lt;strong&gt;handle failures gracefully without impacting the entire system&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Failures are not rare events — they are inevitable.&lt;/p&gt;

&lt;p&gt;What separates a stable system from an outage is how well it is designed to handle those failures.&lt;/p&gt;

&lt;p&gt;Circuit breakers, timeouts, retries, and bulkheads are not optional optimisations — they are fundamental to building reliable systems.&lt;/p&gt;

</description>
      <category>java</category>
      <category>microservices</category>
      <category>springboot</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>How the Circuit Breaker Pattern Prevents Cascading Failures in Microservices</title>
      <dc:creator>Preeti Sharma</dc:creator>
      <pubDate>Fri, 06 Mar 2026 11:12:40 +0000</pubDate>
      <link>https://dev.to/shpreeti/how-the-circuit-breaker-pattern-prevents-cascading-failures-in-microservices-3nbi</link>
      <guid>https://dev.to/shpreeti/how-the-circuit-breaker-pattern-prevents-cascading-failures-in-microservices-3nbi</guid>
      <description>&lt;p&gt;Modern microservice architectures improve scalability and team autonomy, but they also introduce a new challenge: service dependency failures.&lt;/p&gt;

&lt;p&gt;If one service becomes slow or unavailable, it can easily cascade across the system, bringing down multiple services.&lt;/p&gt;

&lt;p&gt;This is where the &lt;strong&gt;Circuit Breaker Pattern&lt;/strong&gt; becomes extremely important.&lt;/p&gt;

&lt;p&gt;In this article we will cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The cascading failure problem&lt;/li&gt;
&lt;li&gt;How circuit breakers solve it&lt;/li&gt;
&lt;li&gt;Circuit breaker states&lt;/li&gt;
&lt;li&gt;A working example using Resilience4j&lt;/li&gt;
&lt;li&gt;Best practices when using circuit breakers&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Cascading Failure Problem
&lt;/h2&gt;

&lt;p&gt;Imagine a simple microservice system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client → Order Service → Payment Service → Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now assume the &lt;strong&gt;Payment Service becomes slow or unavailable&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;What happens?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Order service keeps sending requests.&lt;/li&gt;
&lt;li&gt;Requests start waiting.&lt;/li&gt;
&lt;li&gt;Threads become blocked.&lt;/li&gt;
&lt;li&gt;System resources get exhausted.&lt;/li&gt;
&lt;li&gt;Eventually the &lt;strong&gt;Order Service also crashes&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is called a &lt;strong&gt;cascading failure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A single failure spreads across services.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Circuit Breaker Concept
&lt;/h2&gt;

&lt;p&gt;The concept is inspired by &lt;strong&gt;electrical circuit breakers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When electrical current becomes dangerous, the circuit breaker &lt;strong&gt;cuts the flow&lt;/strong&gt; to prevent damage.&lt;/p&gt;

&lt;p&gt;Similarly in microservices, a circuit breaker:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;monitors failures&lt;/li&gt;
&lt;li&gt;stops sending requests temporarily&lt;/li&gt;
&lt;li&gt;allows the system to recover&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of continuously calling a failing service, we &lt;strong&gt;fail fast&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Circuit Breaker States
&lt;/h2&gt;

&lt;p&gt;A circuit breaker typically has &lt;strong&gt;three states&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1️⃣ Closed State
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client → Order Service → Payment Service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Requests flow normally&lt;/li&gt;
&lt;li&gt;Failures are monitored&lt;/li&gt;
&lt;li&gt;If failures exceed threshold → state changes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2️⃣ Open State
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client → Order Service ✖ Payment Service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Calls are &lt;strong&gt;blocked immediately&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;No request is sent to failing service.&lt;/li&gt;
&lt;li&gt;System return a &lt;strong&gt;fallback response&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3️⃣ Half-Open State
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client → Order Service → Payment Service (limited test requests)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Only a &lt;strong&gt;few requests allowed&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;If they succeed → circuit closes.&lt;/li&gt;
&lt;li&gt;If they fail → circuit opens again&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Circuit Breaker Flow
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Closed → Failures detected → Open
Open → Cooldown period → Half-Open
Half-Open → Success → Closed
Half-Open → Failure → Open
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Implementing Circuit Breaker using Resilience4j
&lt;/h2&gt;

&lt;p&gt;One of the most popular circuit breaker libraries in Java is &lt;a href="https://resilience4j.readme.io/docs/getting-started" rel="noopener noreferrer"&gt;Resilience4j&lt;/a&gt;.&lt;br&gt;
It works very well with &lt;a href="https://spring.io/projects/spring-boot" rel="noopener noreferrer"&gt;Spring Boot&lt;/a&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Add Dependency
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.github.resilience4j&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;resilience4j-spring-boot3&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configure Circuit Breaker
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;application.yml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;resilience4j&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;circuitbreaker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;instances&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;paymentService&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;registerHealthIndicator&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="na"&gt;slidingWindowSize&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
        &lt;span class="na"&gt;minimumNumberOfCalls&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
        &lt;span class="na"&gt;failureRateThreshold&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt;
        &lt;span class="na"&gt;waitDurationInOpenState&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;slidingWindowSize&lt;/code&gt; → number of calls monitored&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;failureRateThreshold&lt;/code&gt; → percentage to trigger breaker&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;waitDurationInOpenState&lt;/code&gt; → time before retry&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Applying Circuit Breaker to a Service
&lt;/h2&gt;

&lt;p&gt;Example: calling a &lt;strong&gt;Payment Service&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Service&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentClient&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@CircuitBreaker&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"paymentService"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fallbackMethod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"fallbackPayment"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;processPayment&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// call external payment service&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;restTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getForObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"http://payment-service/pay"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;fallbackPayment&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Throwable&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Payment service unavailable. Please try later."&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What happens here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Calls go normally.&lt;/li&gt;
&lt;li&gt;If failure rate exceeds threshold → circuit opens.&lt;/li&gt;
&lt;li&gt;All calls go directly to &lt;strong&gt;fallback method&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  What a Fallback Response Looks Like
&lt;/h2&gt;

&lt;p&gt;Fallback responses prevent system crashes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"FAILED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Payment service temporarily unavailable"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of crashing, the system &lt;strong&gt;degrades gracefully&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  When Should You Use Circuit Breakers?
&lt;/h2&gt;

&lt;p&gt;Circuit breakers are useful when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;calling &lt;strong&gt;external APIs&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;calling &lt;strong&gt;slow microservices&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;interacting with &lt;strong&gt;unreliable networks&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Typical examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Order Service → Payment Service
Checkout Service → Inventory Service
API Gateway → User Service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  When NOT to Use Circuit Breakers
&lt;/h2&gt;

&lt;p&gt;Avoid using circuit breakers for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;database calls inside the same service&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;very fast local operations&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;in-memory calls&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Circuit breakers are best suited for &lt;strong&gt;remote network calls&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;p&gt;✔ Always define &lt;strong&gt;fallback responses&lt;/strong&gt;&lt;br&gt;
✔ Monitor breaker metrics&lt;br&gt;
✔ Combine with &lt;strong&gt;retry mechanism&lt;/strong&gt;&lt;br&gt;
✔ Use &lt;strong&gt;timeouts&lt;/strong&gt; with circuit breakers&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Microservices improve scalability and flexibility, but they also introduce reliability challenges when services depend on each other. A failure in one service can quickly propagate and lead to cascading failures across the system.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Circuit Breaker Pattern&lt;/strong&gt; helps prevent this by stopping repeated calls to failing services and allowing systems to fail fast with fallback responses. Tools like &lt;a href="https://resilience4j.readme.io/docs/getting-started" rel="noopener noreferrer"&gt;Resilience4j&lt;/a&gt; make it easy to implement this pattern in &lt;a href="https://spring.io/projects/spring-boot" rel="noopener noreferrer"&gt;Spring Boot&lt;/a&gt; applications.&lt;/p&gt;

&lt;p&gt;In the next article, we’ll explore building &lt;strong&gt;production-grade resilience using Resilience4j&lt;/strong&gt;, including retries, bulkheads, and other advanced patterns.&lt;/p&gt;

&lt;p&gt;Stay tuned for the next part of this series 🚀&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>springboot</category>
      <category>java</category>
      <category>backend</category>
    </item>
    <item>
      <title>Backpressure: Why “Just Handle More Traffic” Is the Wrong Mindset</title>
      <dc:creator>Preeti Sharma</dc:creator>
      <pubDate>Fri, 20 Feb 2026 10:11:30 +0000</pubDate>
      <link>https://dev.to/shpreeti/backpressure-why-just-handle-more-traffic-is-the-wrong-mindset-3j49</link>
      <guid>https://dev.to/shpreeti/backpressure-why-just-handle-more-traffic-is-the-wrong-mindset-3j49</guid>
      <description>&lt;p&gt;When we talk about scaling systems, the default thought is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“How do we handle more requests?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But the better question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“What happens when we receive more than we can handle?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s where &lt;strong&gt;backpressure&lt;/strong&gt; becomes important.&lt;/p&gt;

&lt;p&gt;Not as a buzzword.&lt;br&gt;&lt;br&gt;
As a stability mechanism.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Real Problem
&lt;/h2&gt;

&lt;p&gt;In any backend system, different components have different capacities.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API receives &lt;strong&gt;10k requests/sec&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Service layer handles &lt;strong&gt;6k/sec&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Database handles &lt;strong&gt;3k/sec&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That gap doesn’t disappear — it accumulates.&lt;/p&gt;

&lt;p&gt;It turns into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Growing queues
&lt;/li&gt;
&lt;li&gt;Thread pool exhaustion
&lt;/li&gt;
&lt;li&gt;Memory pressure
&lt;/li&gt;
&lt;li&gt;High GC
&lt;/li&gt;
&lt;li&gt;Increased latency
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eventually → failure.&lt;/p&gt;

&lt;p&gt;Backpressure exists to prevent that.&lt;/p&gt;


&lt;h2&gt;
  
  
  So What Is Backpressure?
&lt;/h2&gt;

&lt;p&gt;At its core:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Backpressure is a flow-control mechanism in which the consumer controls how much data it receives from the producer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of:&lt;br&gt;
Producer → pushes endlessly&lt;br&gt;
Consumer → keeps accepting&lt;/p&gt;

&lt;p&gt;We get:&lt;br&gt;
Consumer → “Give me 100. I’ll ask again when ready.”&lt;/p&gt;

&lt;p&gt;That simple shift changes system behaviour completely.&lt;/p&gt;


&lt;h2&gt;
  
  
  This Is Not Just a Reactive Concept
&lt;/h2&gt;

&lt;p&gt;Yes, it’s formally defined in the &lt;strong&gt;Reactive Streams&lt;/strong&gt; specification&lt;br&gt;&lt;br&gt;
and implemented in frameworks like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project Reactor
&lt;/li&gt;
&lt;li&gt;RxJava
&lt;/li&gt;
&lt;li&gt;Spring WebFlux
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the idea applies even in regular Spring Boot applications.&lt;/p&gt;

&lt;p&gt;Think about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tomcat thread pool → limited
&lt;/li&gt;
&lt;li&gt;DB connection pool → limited
&lt;/li&gt;
&lt;li&gt;CPU cores → limited
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If &lt;strong&gt;incoming rate &amp;gt; processing rate&lt;/strong&gt;, the excess work sits in memory.&lt;/p&gt;

&lt;p&gt;That’s uncontrolled buffering.&lt;/p&gt;

&lt;p&gt;Backpressure is about making that buffering &lt;strong&gt;intentional and bounded&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Push vs Pull (Practical View)
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Without Backpressure
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;sendEvent&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Consumer side:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Queue keeps growing…
Memory increases…
Latency increases…
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing crashes immediately.&lt;/p&gt;

&lt;p&gt;But performance degrades silently.&lt;/p&gt;




&lt;h3&gt;
  
  
  With Backpressure
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;subscription&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;request&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Producer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Send exactly 50.
Wait for next request.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system becomes predictable.&lt;/p&gt;

&lt;p&gt;And predictability is what makes systems reliable.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Important Insight
&lt;/h3&gt;

&lt;p&gt;Backpressure is not about slowing down traffic.&lt;/p&gt;

&lt;p&gt;It’s about &lt;strong&gt;aligning work with capacity&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If a service can process 2,000 requests per second,&lt;br&gt;
it should not accept 10,000 and “hope for the best.”&lt;/p&gt;

&lt;p&gt;That hope becomes technical debt.&lt;/p&gt;


&lt;h3&gt;
  
  
  Where This Matters in Real Systems
&lt;/h3&gt;
&lt;h4&gt;
  
  
  1. Kafka Consumers
&lt;/h4&gt;

&lt;p&gt;If consumer speed &amp;lt; producer speed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lag increases&lt;/li&gt;
&lt;li&gt;Memory grows&lt;/li&gt;
&lt;li&gt;Rebalances become frequent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Smart systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Control poll size&lt;/li&gt;
&lt;li&gt;Pause consumption&lt;/li&gt;
&lt;li&gt;Scale consumers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s practical backpressure thinking.&lt;/p&gt;


&lt;h4&gt;
  
  
  2. Database Writes
&lt;/h4&gt;

&lt;p&gt;If DB supports 2k writes/sec&lt;br&gt;
but API accepts 8k writes/sec:&lt;/p&gt;

&lt;p&gt;You don’t have a scaling problem.&lt;/p&gt;

&lt;p&gt;You have a flow-control problem.&lt;/p&gt;


&lt;h4&gt;
  
  
  3. Reactive APIs
&lt;/h4&gt;

&lt;p&gt;In Spring WebFlux, you can do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Flux&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;range&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1_000_000&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;limitRate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;subscribe&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It processes data in chunks instead of flooding the subscriber.&lt;/p&gt;

&lt;p&gt;That’s backpressure applied.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Most systems don’t fail instantly.&lt;br&gt;
They degrade first.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Final Thought
&lt;/h3&gt;

&lt;p&gt;Scaling isn’t just about handling more.&lt;/p&gt;

&lt;p&gt;It’s about knowing when to slow down.&lt;/p&gt;

&lt;p&gt;Backpressure is simply this principle:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Never accept more work than you can process safely.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And once you start thinking that way, you design systems differently.&lt;/p&gt;

&lt;p&gt;More stable.&lt;br&gt;
More predictable.&lt;br&gt;
And far less fragile under pressure.&lt;/p&gt;

</description>
      <category>java</category>
      <category>backend</category>
      <category>systemdesign</category>
      <category>microservices</category>
    </item>
    <item>
      <title>Sequential vs Parallel API Calls in Spring Boot</title>
      <dc:creator>Preeti Sharma</dc:creator>
      <pubDate>Fri, 13 Feb 2026 11:22:35 +0000</pubDate>
      <link>https://dev.to/shpreeti/sequential-vs-parallel-api-calls-in-spring-boot-4o3f</link>
      <guid>https://dev.to/shpreeti/sequential-vs-parallel-api-calls-in-spring-boot-4o3f</guid>
      <description>&lt;p&gt;In microservice architecture, it’s common for one service to call multiple downstream services.&lt;/p&gt;

&lt;p&gt;But what many developers miss is how those calls are executed — sequentially or in parallel.&lt;/p&gt;

&lt;p&gt;Let’s understand this with a simple example.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 Problem Statement
&lt;/h2&gt;

&lt;p&gt;Suppose Service A needs data from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Service B → takes 1 second
&lt;/li&gt;
&lt;li&gt;Service C → takes 1 second
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If Service A calls them one after another, what will be the total response time?&lt;/p&gt;

&lt;p&gt;👉 2 seconds.&lt;/p&gt;

&lt;p&gt;Why? Because it waits for B to finish before calling C.&lt;/p&gt;

&lt;p&gt;Let’s implement this in Spring Boot.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔴 Part 1 — Sequential Execution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Fake downstream endpoints
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/service-b"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;serviceB&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Response from service B"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/service-c"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;serviceC&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Response from service C"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sequential call
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt; &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/sequential"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;sequential&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;baseUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"http://localhost:8080/api"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;serviceBResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;restTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getForObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;baseUrl&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"/service-b"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;serviceCResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;restTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getForObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;baseUrl&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"/service-c"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Result: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;serviceBResponse&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" &amp;amp; "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;serviceCResponse&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" | Time Taken: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" ms"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ⏱ Output
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Result: Response from service B &amp;amp; Response from service C | Time Taken: 2065 ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🟢 Part 2 — Making It Asynchronous
&lt;/h2&gt;

&lt;p&gt;Instead of waiting for one call to finish, we can trigger both calls at the same time using &lt;code&gt;CompletableFuture&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parallel Implementation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/parallel"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;parallel&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;ExecutionException&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;baseUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"http://localhost:8080/api"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;responseB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;restTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getForObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;baseUrl&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"/service-b"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;responseC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;restTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getForObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;baseUrl&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"/service-c"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;allOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseB&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;responseC&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;join&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Result: "&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;responseB&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" &amp;amp; "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;responseC&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" | Time taken: "&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" ms"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ⏱ Output
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Result: Response from service B &amp;amp; Response from service C | Time taken: 1061 ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now total time equals the slowest service, not the sum of both.&lt;/p&gt;

&lt;p&gt;Mathematically:&lt;br&gt;
Total Time = max(Service B, Service C)&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Why This Matters
&lt;/h2&gt;

&lt;p&gt;Sequential execution:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Increases API latency&lt;/li&gt;
&lt;li&gt;Blocks threads longer&lt;/li&gt;
&lt;li&gt;Reduces throughput under load&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Parallel execution:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduces response time&lt;/li&gt;
&lt;li&gt;Improves user experience&lt;/li&gt;
&lt;li&gt;Utilises threads efficiently&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Sequential calls add up execution time.&lt;/li&gt;
&lt;li&gt;Parallel execution reduces total latency.&lt;/li&gt;
&lt;li&gt;Asynchronous programming is essential in microservice communication.&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;CompletableFuture&lt;/code&gt; helps coordinate multiple async tasks cleanly.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>springboot</category>
      <category>javaconcurrency</category>
      <category>microservices</category>
      <category>backenddevelopment</category>
    </item>
    <item>
      <title>Sequential vs Parallel API Calls in Spring Boot</title>
      <dc:creator>Preeti Sharma</dc:creator>
      <pubDate>Fri, 13 Feb 2026 11:22:34 +0000</pubDate>
      <link>https://dev.to/shpreeti/sequential-vs-parallel-api-calls-in-spring-boot-3nc5</link>
      <guid>https://dev.to/shpreeti/sequential-vs-parallel-api-calls-in-spring-boot-3nc5</guid>
      <description>&lt;p&gt;In microservice architecture, it’s common for one service to call multiple downstream services.&lt;/p&gt;

&lt;p&gt;But what many developers miss is how those calls are executed — sequentially or in parallel.&lt;/p&gt;

&lt;p&gt;Let’s understand this with a simple example.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 Problem Statement
&lt;/h2&gt;

&lt;p&gt;Suppose Service A needs data from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Service B → takes 1 second
&lt;/li&gt;
&lt;li&gt;Service C → takes 1 second
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If Service A calls them one after another, what will be the total response time?&lt;/p&gt;

&lt;p&gt;👉 2 seconds.&lt;/p&gt;

&lt;p&gt;Why? Because it waits for B to finish before calling C.&lt;/p&gt;

&lt;p&gt;Let’s implement this in Spring Boot.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔴 Part 1 — Sequential Execution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Fake downstream endpoints
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/service-b"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;serviceB&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Response from service B"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/service-c"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;serviceC&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Response from service C"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sequential call
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt; &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/sequential"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;sequential&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;baseUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"http://localhost:8080/api"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;serviceBResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;restTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getForObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;baseUrl&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"/service-b"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;serviceCResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;restTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getForObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;baseUrl&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"/service-c"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Result: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;serviceBResponse&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" &amp;amp; "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;serviceCResponse&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" | Time Taken: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" ms"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ⏱ Output
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Result: Response from service B &amp;amp; Response from service C | Time Taken: 2065 ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🟢 Part 2 — Making It Asynchronous
&lt;/h2&gt;

&lt;p&gt;Instead of waiting for one call to finish, we can trigger both calls at the same time using &lt;code&gt;CompletableFuture&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parallel Implementation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/parallel"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;parallel&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;ExecutionException&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;baseUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"http://localhost:8080/api"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;responseB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;restTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getForObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;baseUrl&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"/service-b"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;responseC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;restTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getForObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;baseUrl&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"/service-c"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;allOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseB&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;responseC&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;join&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Result: "&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;responseB&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" &amp;amp; "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;responseC&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" | Time taken: "&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" ms"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ⏱ Output
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Result: Response from service B &amp;amp; Response from service C | Time taken: 1061 ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now total time equals the slowest service, not the sum of both.&lt;/p&gt;

&lt;p&gt;Mathematically:&lt;br&gt;
Total Time = max(Service B, Service C)&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Why This Matters
&lt;/h2&gt;

&lt;p&gt;Sequential execution:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Increases API latency&lt;/li&gt;
&lt;li&gt;Blocks threads longer&lt;/li&gt;
&lt;li&gt;Reduces throughput under load&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Parallel execution:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduces response time&lt;/li&gt;
&lt;li&gt;Improves user experience&lt;/li&gt;
&lt;li&gt;Utilises threads efficiently&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Sequential calls add up execution time.&lt;/li&gt;
&lt;li&gt;Parallel execution reduces total latency.&lt;/li&gt;
&lt;li&gt;Asynchronous programming is essential in microservice communication.&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;CompletableFuture&lt;/code&gt; helps coordinate multiple async tasks cleanly.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>springboot</category>
      <category>javaconcurrency</category>
      <category>microservices</category>
      <category>backenddevelopment</category>
    </item>
    <item>
      <title>Why APIs Are Contracts, Not Just Endpoints</title>
      <dc:creator>Preeti Sharma</dc:creator>
      <pubDate>Mon, 09 Feb 2026 10:26:37 +0000</pubDate>
      <link>https://dev.to/shpreeti/why-apis-are-contracts-not-just-endpoints-53c1</link>
      <guid>https://dev.to/shpreeti/why-apis-are-contracts-not-just-endpoints-53c1</guid>
      <description>&lt;h2&gt;
  
  
  Treating APIs as “just endpoints” is a costly mistake
&lt;/h2&gt;

&lt;p&gt;Early in my career, I thought of APIs mainly as &lt;em&gt;endpoints&lt;/em&gt; — URLs that return data so the frontend can move forward.&lt;/p&gt;

&lt;p&gt;Over time (and after a few production incidents), I learned this mental model doesn’t scale.&lt;/p&gt;

&lt;p&gt;APIs are not just endpoints.&lt;br&gt;
They are &lt;strong&gt;contracts&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  APIs live longer than features
&lt;/h2&gt;

&lt;p&gt;Frontend code changes fast.&lt;br&gt;
Backend APIs tend to &lt;strong&gt;outlive multiple UI versions, clients, and even teams.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When an API changes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mobile apps might not update immediately&lt;/li&gt;
&lt;li&gt;Older clients may still depend on previous behaviour&lt;/li&gt;
&lt;li&gt;Silent breakages can take weeks to surface&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once an API is public (even internally), it’s no longer “just code”.&lt;/p&gt;




&lt;h2&gt;
  
  
  Small changes can have big consequences
&lt;/h2&gt;

&lt;p&gt;Some examples that seem harmless but aren’t:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Changing a response field name&lt;/li&gt;
&lt;li&gt;Removing a field that “no one uses”&lt;/li&gt;
&lt;li&gt;Returning a different HTTP status code&lt;/li&gt;
&lt;li&gt;Reusing error messages for multiple failure cases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Break clients&lt;/li&gt;
&lt;li&gt;Cause unexpected UI behaviour&lt;/li&gt;
&lt;li&gt;Create hard-to-debug production issues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The backend may still be “correct”, but the system isn’t.&lt;/p&gt;




&lt;h2&gt;
  
  
  What changed in how I design APIs now
&lt;/h2&gt;

&lt;p&gt;A few shifts that helped:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Think in contracts, not implementations&lt;/strong&gt;&lt;br&gt;
What matters is what the client expects, not how the backend is built.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Be explicit about errors&lt;/strong&gt;&lt;br&gt;
Clear error codes and messages are more valuable than generic failures.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Prefer additive changes&lt;/strong&gt;&lt;br&gt;
Adding fields is safer than modifying or removing existing ones.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Assume clients won’t update immediately&lt;/strong&gt;&lt;br&gt;
Backward compatibility is part of API design, not a nice-to-have.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why this matters even more in product &amp;amp; fintech systems
&lt;/h2&gt;

&lt;p&gt;In product-driven and fintech systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;APIs often power money movement, identity, or critical workflows&lt;/li&gt;
&lt;li&gt;Correctness matters more than speed of change&lt;/li&gt;
&lt;li&gt;Breaking behaviour can directly impact users and trust&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here, API discipline is not over-engineering — it’s a responsibility.&lt;/p&gt;




&lt;p&gt;Treating APIs as contracts changed how I design, review, and evolve backend systems.&lt;br&gt;
It made my work slower at the start — and far safer in the long run.&lt;/p&gt;

</description>
      <category>backend</category>
      <category>api</category>
      <category>softwareengineering</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
