<?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: Clint Edwards</title>
    <description>The latest articles on DEV Community by Clint Edwards (@bithckr).</description>
    <link>https://dev.to/bithckr</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4008634%2Fd04bd433-ad90-4834-868f-c755008f2c06.jpeg</url>
      <title>DEV Community: Clint Edwards</title>
      <link>https://dev.to/bithckr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bithckr"/>
    <language>en</language>
    <item>
      <title>Everyone seems to be returning to the monolith, but event-driven microservices are still the right choice for high-scale infrastructure. We’ve built the tooling and aligned our teams. We’ll be here when the pendulum swings back.</title>
      <dc:creator>Clint Edwards</dc:creator>
      <pubDate>Tue, 30 Jun 2026 13:37:58 +0000</pubDate>
      <link>https://dev.to/bithckr/everyone-seems-to-be-returning-to-the-monolith-but-event-driven-microservices-are-still-the-right-5d9e</link>
      <guid>https://dev.to/bithckr/everyone-seems-to-be-returning-to-the-monolith-but-event-driven-microservices-are-still-the-right-5d9e</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/bithckr/the-microservices-exodus-why-were-not-leaving-1dh3" class="crayons-story__hidden-navigation-link"&gt;The Microservices Exodus: Why We’re Not Leaving&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/bithckr" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4008634%2Fd04bd433-ad90-4834-868f-c755008f2c06.jpeg" alt="bithckr profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/bithckr" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Clint Edwards
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Clint Edwards
                
              
              &lt;div id="story-author-preview-content-4024447" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/bithckr" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4008634%2Fd04bd433-ad90-4834-868f-c755008f2c06.jpeg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Clint Edwards&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/bithckr/the-microservices-exodus-why-were-not-leaving-1dh3" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jun 29&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/bithckr/the-microservices-exodus-why-were-not-leaving-1dh3" id="article-link-4024447"&gt;
          The Microservices Exodus: Why We’re Not Leaving
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/distributedsystems"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;distributedsystems&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/architecture"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;architecture&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/microservices"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;microservices&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/backend"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;backend&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/bithckr/the-microservices-exodus-why-were-not-leaving-1dh3#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            6 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>architecture</category>
      <category>discuss</category>
      <category>microservices</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>The Microservices Exodus: Why We’re Not Leaving</title>
      <dc:creator>Clint Edwards</dc:creator>
      <pubDate>Wed, 20 May 2026 17:40:08 +0000</pubDate>
      <link>https://dev.to/bithckr/the-microservices-exodus-why-were-not-leaving-1dh3</link>
      <guid>https://dev.to/bithckr/the-microservices-exodus-why-were-not-leaving-1dh3</guid>
      <description>&lt;h4&gt;
  
  
  Everyone seems to be consolidating. Here’s why we’re staying the course on microservices and event-driven architecture.
&lt;/h4&gt;

&lt;h3&gt;
  
  
  The Backlash Is Real
&lt;/h3&gt;

&lt;p&gt;Over the past two years, a quiet but growing chorus of engineering leaders have been publishing post-mortems with a familiar headline: &lt;em&gt;”We’re moving back to the monolith.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Amazon Prime Video made waves in 2023 when they detailed migrating a distributed microservices pipeline to a monolith, cutting infrastructure costs by 90%. Shopify doubled down on their “modular monolith.” Stack Overflow never left. DHH declared microservices a “cargo cult.” And a wave of CTOs nodded along.&lt;/p&gt;

&lt;p&gt;The critique is fair. Microservices, when done poorly, introduce a staggering amount of operational overhead: distributed tracing across dozens of services, network latency compounding at every hop, the cognitive burden of eventual consistency, and the sheer infrastructure cost of running hundreds of containers for what could be a simple CRUD app.&lt;/p&gt;

&lt;p&gt;These are legitimate complaints. And for many teams, the consolidation makes sense. A distributed architecture, in many of these cases, was simply the wrong choice.&lt;/p&gt;

&lt;h3&gt;
  
  
  What the Backlash Is Actually About
&lt;/h3&gt;

&lt;p&gt;The teams retreating from microservices are overwhelmingly retreating from &lt;strong&gt;premature microservices&lt;/strong&gt; : services decomposed too early, too granularly, without the organizational structure or domain knowledge to justify the split.&lt;/p&gt;

&lt;p&gt;Conway’s Law cuts both ways. If your team isn’t structured to own independent services, your architecture will betray you. A microservices architecture operated by a monolithic team is the &lt;em&gt;worst of both worlds&lt;/em&gt;: distributed complexity with centralized bottlenecks.&lt;/p&gt;

&lt;p&gt;The problem was never microservices. The problem was applying microservices to problems that didn’t warrant them, or doing so without the event-driven infrastructure needed to make them compose cleanly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Event-Driven Architecture Changes the Calculus
&lt;/h3&gt;

&lt;p&gt;The teams that struggled most with microservices were the ones coupling services together synchronously. REST calls chaining through five services, each one a failure domain, each one compounding latency. That’s not a microservices problem; that’s a synchronous integration problem wearing microservices clothing.&lt;/p&gt;

&lt;p&gt;When services communicate through &lt;strong&gt;events&lt;/strong&gt; (asynchronous and durable), the failure modes change entirely. A service going down doesn’t cascade; it just falls behind. A new consumer can subscribe to an existing event stream without touching the producer. Business logic can evolve independently because the coupling point is the event schema, not a direct synchronous call to another service’s API.&lt;/p&gt;

&lt;p&gt;Event-driven microservices aren’t just a deployment strategy. They’re a different way of modeling your business domain. State changes become first-class citizens, and services are genuinely decoupled rather than nominally so.&lt;/p&gt;

&lt;p&gt;This is the architecture we’ve invested in, and walking away from it now would mean discarding the very properties that make it powerful.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Price of Admission
&lt;/h3&gt;

&lt;p&gt;We’re not naive about the tradeoffs. Here’s an honest accounting of what staying on this path requires:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Operational maturity is non-negotiable.&lt;/strong&gt; You need distributed tracing, structured logging, and health observability. Tooling has matured significantly here: OpenTelemetry, Grafana, and purpose-built messaging infrastructure make this tractable in a way it simply wasn’t five years ago.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get the boundaries wrong and nothing else matters.&lt;/strong&gt; The right service decomposition emerges from deep understanding of the business domain. Getting composition wrong is the original sin of microservices: a poorly drawn boundary forces two services to change in lockstep, which eliminates the independence you decomposed to achieve in the first place. Correct composition means each service maps to a genuine capability with a stable interface; one that can evolve, scale, and fail independently. The payoff, when you get it right, is services that rarely need to change together, which is the entire point.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Schema governance is load-bearing.&lt;/strong&gt; In a system where services communicate entirely through events, the schema is the ultimate contract between producers and consumers. Implementing robust schema registries, enforcing strict versioning strategies, and adhering to backward-compatibility disciplines are not optional overhead; they are structural requirements. Breaking a schema means silently breaking downstream consumers, an operational failure far worse than a compile-time error.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Idempotency must be a first-class citizen.&lt;/strong&gt; Because high-throughput, distributed event streams inherently rely on at-least-once delivery guarantees, messages &lt;em&gt;will&lt;/em&gt; be delivered more than once during network partitions, retries, or rebalances. Every consumer must be designed to handle duplicate events gracefully. Without this foundational discipline, transient network hiccups will inevitably manifest as silent data corruption bugs in production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Service boundaries enforce structural quality.&lt;/strong&gt; When a microservice is genuinely independent, the quality bar for that single deployment unit rises. You can no longer paper over poorly isolated boundaries with end-to-end integration tests that accidentally span multiple domains. This architecture forces engineering teams toward contract testing and isolated test suites; practices that surface architectural friction early, exactly where engineering flaws love to hide.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Distributed systems demand a different testing vocabulary.&lt;/strong&gt; Unit tests and end-to-end tests alone aren’t enough. Chaos engineering (deliberately injecting failures, partitions, and latency into a running system) is the only way to verify that partial failures degrade gracefully rather than cascade. Endurance testing matters just as much: a service that handles load correctly for five minutes but leaks memory or exhausts connection pools over hours will fail in production in ways that no short-lived test suite will catch. These disciplines are expensive to build but more expensive to skip, and they’re largely absent from the testing culture that forms around monolithic codebases.&lt;/p&gt;

&lt;h3&gt;
  
  
  What This Means for Customers
&lt;/h3&gt;

&lt;p&gt;Architectural elegance means nothing if it doesn’t translate to a reliable experience for the end user. When we committed to event-driven microservices, a significant part of that decision was about what it would mean for the workloads running on top of the platform.&lt;/p&gt;

&lt;p&gt;The practical consequences are worth being specific about.&lt;/p&gt;

&lt;p&gt;Scalability in a microservices architecture is granular. Individual services scale independently, so a spike in one capability doesn’t force you to scale everything. That matters in an analytics platform where certain workloads are bursty and others are constant. Failover is similarly scoped: redundancy is a property of individual services, not the platform as a whole, which means a degraded component degrades gracefully rather than triggering a cascade.&lt;/p&gt;

&lt;p&gt;Because services are independently deployable, fixes and improvements can ship to a specific capability without a platform-wide maintenance window. For teams running our platform in production, that translates to shorter outage windows and lower risk per release. The architecture was designed with operational continuity as a constraint, not an afterthought.&lt;/p&gt;

&lt;p&gt;Extensibility follows the same pattern. The REST APIs that our services use to communicate with each other are the same APIs available to third-party developers. There’s no privileged internal interface. That consistency is deliberate: it means the integration model for external tooling is identical to the one for core platform components.&lt;/p&gt;

&lt;p&gt;The honest tradeoff is eventual consistency. In a distributed, event-driven system, reads don’t always reflect the latest write immediately. For analytics and data pipeline workloads (which represent the overwhelming majority of what runs on the platform), that’s not just an acceptable tradeoff, it’s the right one. Workloads that prioritize throughput and scale over strict read-after-write semantics are exactly what this architecture was designed to serve.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Honest Comparison
&lt;/h3&gt;

&lt;p&gt;The monolith advocates aren’t wrong that consolidation can reduce operational complexity for the right team working on the right problem. If you’re a team of 10 building a focused SaaS product with a well-understood domain, a well-structured monolith might genuinely serve you better for the next three years.&lt;/p&gt;

&lt;p&gt;But if you’re building infrastructure that must integrate with heterogeneous systems, scale individual capabilities independently, absorb spikes from external event sources, and evolve without coordinated release trains, then you need an architecture that was designed for those constraints.&lt;/p&gt;

&lt;p&gt;Microservices with event-driven communication is that architecture. The teams abandoning it, in most cases, are abandoning a poorly executed version of it.&lt;/p&gt;

&lt;p&gt;We’re not staying the course out of stubbornness. We’re staying the course because we’ve done the work to execute it correctly, and the results for the customers building on top of it speak for themselves.&lt;/p&gt;

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

&lt;p&gt;The pendulum swings in software architecture because most architectural failures are blamed on the pattern rather than the execution. Microservices didn’t fail those teams. Distributed systems operated without the right tooling, organizational alignment, or domain clarity failed those teams.&lt;/p&gt;

&lt;p&gt;We’ve built the tooling. We’ve aligned the teams. We’ve done the domain work.&lt;/p&gt;

&lt;p&gt;The exodus is happening around us. We’ll be here when the pendulum swings back.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Have thoughts on event-driven architecture or microservices tradeoffs? Drop a comment below; we’d love to hear from teams on both sides of this debate.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>distributedsystems</category>
      <category>architecture</category>
      <category>microservices</category>
      <category>backend</category>
    </item>
    <item>
      <title>C++ Didn’t Get Slower — Go Got Better</title>
      <dc:creator>Clint Edwards</dc:creator>
      <pubDate>Fri, 24 Apr 2026 14:22:04 +0000</pubDate>
      <link>https://dev.to/bithckr/c-didnt-get-slower-go-got-better-539j</link>
      <guid>https://dev.to/bithckr/c-didnt-get-slower-go-got-better-539j</guid>
      <description>&lt;p&gt;&lt;em&gt;What a side‑by‑side gRPC benchmark reveals about modern concurrency, scheduling, and the real cost of performance&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;C++ didn’t lose its edge. It didn’t suddenly become slow, unsafe, or obsolete.&lt;/p&gt;

&lt;p&gt;What changed is that &lt;strong&gt;languages like Go — and increasingly Rust — got good enough that raw performance differences are often small&lt;/strong&gt; , while the &lt;strong&gt;cost of building, operating, and maintaining equivalent systems in C++ remains high&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That shift matters more than most benchmarks suggest.&lt;/p&gt;

&lt;p&gt;We benchmarked the same production gRPC proxy written twice: once in Go, once in C++. The results don’t show a clear performance winner — they show why runtime design, tail latency, and engineering economics now drive the decision more than peak throughput ever did.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The experiment&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We recently open sourced &lt;a href="https://github.com/sassoftware/arke" rel="noopener noreferrer"&gt;Arke&lt;/a&gt; — a production gRPC proxy for message brokers written in Go.&lt;/p&gt;

&lt;p&gt;The predictable response was:&lt;/p&gt;

&lt;p&gt;“Sure, but how much faster would this be in C++?”&lt;/p&gt;

&lt;p&gt;So we answered it directly.&lt;/p&gt;

&lt;p&gt;We ported arke to C++, kept the .proto files identical, and ran both implementations through the same benchmark harness. No synthetic loops, no micro‑benchmarks — just real gRPC clients exercising real concurrency and I/O.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What arke does (briefly)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Arke sits between your application and a message broker (RabbitMQ, etc.) and exposes a uniform gRPC API regardless of backend.&lt;/p&gt;

&lt;p&gt;It provides three services:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Producer&lt;/strong&gt;  — Connect, PublishOne, Publish (bidi), Disconnect&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consumer&lt;/strong&gt;  — Connect, Consume (bidi), SourceStats, Disconnect&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Healthz&lt;/strong&gt;  — Check (bidi heartbeat)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The differences are strictly runtime and ecosystem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Go:&lt;/strong&gt; amqp091-go, goroutines, zerolog&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C++:&lt;/strong&gt; librabbitmq, std::thread, spdlog&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both use the same generated gRPC interfaces.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Benchmark setup (short version)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Apple M1 Pro, localhost RabbitMQ&lt;/li&gt;
&lt;li&gt;grpc‑go vs grpc‑cpp&lt;/li&gt;
&lt;li&gt;Warm‑up runs, real clients&lt;/li&gt;
&lt;li&gt;Throughput plus p50 / p95 / p99 / p99.9 latency recorded&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal wasn’t micro‑performance. It was understanding behavior &lt;em&gt;under load&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Scenario 1 — Connection‑heavy paths&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Producer.Connect is called on existing connections, and negotiates AMQP sessions with the broker.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happened&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At &lt;strong&gt;low concurrency&lt;/strong&gt; , Go and C++ performed similarly.&lt;/li&gt;
&lt;li&gt;At &lt;strong&gt;moderate concurrency&lt;/strong&gt; , results fluctuated.&lt;/li&gt;
&lt;li&gt;At &lt;strong&gt;higher concurrency&lt;/strong&gt; , &lt;strong&gt;Go consistently showed better tail latency&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At 10 workers (p99.9 latency):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go: ~1.4 ms&lt;/li&gt;
&lt;li&gt;C++: ~3.5 ms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With raw throughput so similar, the focus is on &lt;em&gt;tail behavior&lt;/em&gt;. Goroutines park cooperatively. std::threads block in the kernel. Under burst load, that difference matters.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Scenario 2 — Steady‑state publishing&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Producer.PublishOne represents the typical case: established connections publishing messages as fast as possible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happened&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;C++ had a slight edge at very low concurrency.&lt;/li&gt;
&lt;li&gt;At ~10 workers, &lt;strong&gt;both saturated RabbitMQ&lt;/strong&gt; at ~16K requests/sec.&lt;/li&gt;
&lt;li&gt;Beyond that point, scheduling effects dominated.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key point:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
 Once the broker becomes the bottleneck, language choice largely disappears from the equation.&lt;/p&gt;

&lt;p&gt;The saturation point is a product of the runtime environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario 3 — Pure gRPC overhead&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Healthz.Check removes the broker entirely, isolating the runtime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happened&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At very low concurrency, C++ was faster.&lt;/li&gt;
&lt;li&gt;At moderate and high concurrency, &lt;strong&gt;Go pulled clearly ahead on tail latency&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At 10 workers (p99.9 latency):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go: ~5.8 ms&lt;/li&gt;
&lt;li&gt;C++: ~14.6 ms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This gap exists with no I/O, minimal allocation pressure, and no GC involvement. It comes directly from scheduling and blocking behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;How big is the performance difference?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Smaller than it appears in isolation.&lt;/p&gt;

&lt;p&gt;Across the benchmarks, throughput numbers were often close, peak rates frequently aligned, and measured differences commonly fell within single‑digit percentages. In many cases, both implementations reached similar limits despite very different runtime designs.&lt;/p&gt;

&lt;p&gt;Which leads to the more &lt;strong&gt;consequential point&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The cost that &lt;em&gt;does&lt;/em&gt; differ significantly&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Performance gaps have narrowed, but &lt;strong&gt;C++ development and maintenance costs have not&lt;/strong&gt;. Extracting marginal gains typically requires more complex concurrency, stricter lifetime management, and ongoing vigilance against subtle correctness issues. These costs don’t appear in benchmarks, but they compound over time — and when performance gains are small, they dominate the trade‑off.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What this actually shows&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This benchmark isn’t saying &lt;em&gt;“Go is faster than C++.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It shows something more important:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;C++ excels when absolute control matters&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Go excels when concurrency and tail‑latency behavior dominate&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rust targets a similar space, trading simplicity for stronger safety guarantees&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Modern systems fail less often because of raw speed, and more often because of scheduling pathologies, queue buildup, and unpredictable tails.&lt;/p&gt;

&lt;p&gt;That’s where Go — and increasingly Rust — change the equation.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Should you rewrite a C++ system?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Maybe — if the gains justify the cost.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In most systems, the &lt;strong&gt;performance difference is small&lt;/strong&gt;. Throughput converges, saturation points align, and wins are often negligible.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;development and maintenance cost is not&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If C++’s added complexity isn’t buying you &lt;em&gt;meaningful&lt;/em&gt; gains in latency, reliability, or capacity, then Go or Rust can deliver near‑equivalent performance at a much lower long‑term cost.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The takeaway&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The modern trade‑off isn’t speed versus safety.&lt;/p&gt;

&lt;p&gt;It’s &lt;strong&gt;marginal performance gains versus ongoing engineering cost&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;C++ still defines the floor — but Go and Rust are reshaping the ceiling.&lt;/p&gt;




</description>
      <category>cpp</category>
      <category>architecture</category>
      <category>performance</category>
      <category>go</category>
    </item>
  </channel>
</rss>
