<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged eventdrivenarchitecture</title>
<link>https://coderlegion.com/tag/eventdrivenarchitecture</link>
<description>Powered by Question2Answer</description>
<item>
<title>Publish-Subscribe: How Modern Systems Scale Without Becoming a Monolith</title>
<link>https://coderlegion.com/23894/publish-subscribe-how-modern-systems-scale-without-becoming-a-monolith</link>
<description>&lt;p&gt;When an online order is placed, the customer sees a simple message:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&quot;Your order has been confirmed.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Behind that message, however, an entire chain of events begins.&lt;/p&gt;
&lt;p&gt;The inventory must be updated.&lt;/p&gt;
&lt;p&gt;The payment must be recorded.&lt;/p&gt;
&lt;p&gt;The customer should receive an email.&lt;/p&gt;
&lt;p&gt;Analytics dashboards need updating.&lt;/p&gt;
&lt;p&gt;Fraud detection systems may need to run.&lt;/p&gt;
&lt;p&gt;Loyalty points might need to be awarded.&lt;/p&gt;
&lt;p&gt;Shipping labels may need to be generated.&lt;/p&gt;
&lt;p&gt;In small systems, developers often connect these actions directly.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Order Service
 ├── Update Inventory
 ├── Send Email
 ├── Update Analytics
 ├── Create Invoice
 └── Start Shipping
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At first, this seems perfectly reasonable.&lt;/p&gt;
&lt;p&gt;Then the business grows.&lt;/p&gt;
&lt;p&gt;And everything starts breaking.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-architecture-that-works-until-it-doesn-t&quot;&gt;The Architecture That Works Until It Doesn't&lt;/h3&gt;
&lt;p&gt;Imagine an e-commerce platform processing 50 orders per day.&lt;/p&gt;
&lt;p&gt;A customer places an order.&lt;/p&gt;
&lt;p&gt;The Order Service directly calls:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Inventory Service
Email Service
Analytics Service
Billing Service
Shipping Service
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Everything succeeds.&lt;/p&gt;
&lt;p&gt;Everyone is happy.&lt;/p&gt;
&lt;p&gt;The architecture appears simple.&lt;/p&gt;
&lt;p&gt;The problem is that simplicity is deceptive.&lt;/p&gt;
&lt;p&gt;The Order Service now depends on every downstream service.&lt;/p&gt;
&lt;p&gt;If any one of them is slow, the entire workflow becomes slow.&lt;/p&gt;
&lt;p&gt;If any one of them fails, the customer experience can fail.&lt;/p&gt;
&lt;p&gt;The more business capabilities added, the larger this dependency chain becomes.&lt;/p&gt;
&lt;p&gt;Over time the Order Service quietly transforms into the center of the entire company.&lt;/p&gt;
&lt;p&gt;Every new feature adds another dependency.&lt;/p&gt;
&lt;p&gt;Every new dependency increases risk.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;a-real-failure-scenario&quot;&gt;A Real Failure Scenario&lt;/h3&gt;
&lt;p&gt;Consider this order workflow:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Customer
    ↓
Order Service
    ↓
Inventory Service
    ↓
Email Service
    ↓
Analytics Service
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;One day the Email Service experiences an outage.&lt;/p&gt;
&lt;p&gt;Now what happens?&lt;/p&gt;
&lt;p&gt;Many systems accidentally end up with behavior like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;create_order()

reserve_inventory()

send_confirmation_email()

update_analytics()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Email fails.&lt;/p&gt;
&lt;p&gt;The transaction stops.&lt;/p&gt;
&lt;p&gt;Analytics never updates.&lt;/p&gt;
&lt;p&gt;The customer may not even receive order confirmation.&lt;/p&gt;
&lt;p&gt;A problem in one subsystem cascades across the platform.&lt;/p&gt;
&lt;p&gt;This is known as &lt;strong&gt;tight coupling&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The services are technically separate.&lt;/p&gt;
&lt;p&gt;Operationally, they are not.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-postmortem-nobody-wants-to-write&quot;&gt;The Postmortem Nobody Wants to Write&lt;/h3&gt;
&lt;p&gt;A common production incident looks something like this:&lt;/p&gt;
&lt;h4 id=&quot;what-happened-&quot;&gt;What happened?&lt;/h4&gt;
&lt;p&gt;A third-party email provider experienced elevated latency.&lt;/p&gt;
&lt;h4 id=&quot;impact&quot;&gt;Impact&lt;/h4&gt;
&lt;p&gt;Order creation response times increased from:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;200ms
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;8-15 seconds
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;business-impact&quot;&gt;Business Impact&lt;/h4&gt;
&lt;p&gt;Customers abandoned checkout.&lt;/p&gt;
&lt;p&gt;Conversion rates dropped.&lt;/p&gt;
&lt;p&gt;Support tickets increased.&lt;/p&gt;
&lt;p&gt;Revenue was affected.&lt;/p&gt;
&lt;h4 id=&quot;root-cause&quot;&gt;Root Cause&lt;/h4&gt;
&lt;p&gt;The Order Service was waiting for Email Service completion before responding.&lt;/p&gt;
&lt;h4 id=&quot;architectural-problem&quot;&gt;Architectural Problem&lt;/h4&gt;
&lt;p&gt;The platform treated a non-critical operation as a critical dependency.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Notice something important.&lt;/p&gt;
&lt;p&gt;The email system wasn't actually required to create the order.&lt;/p&gt;
&lt;p&gt;The order should have succeeded regardless.&lt;/p&gt;
&lt;p&gt;The architecture created the outage.&lt;/p&gt;
&lt;p&gt;Not the email provider.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;enter-publish-subscribe&quot;&gt;Enter Publish-Subscribe&lt;/h2&gt;
&lt;p&gt;Instead of directly calling every service, the Order Service publishes an event.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Order Service
      ↓
Order Created Event
      ↓
Message Broker
      ↓
Inventory
Email
Analytics
Billing
Shipping
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the Order Service only has one responsibility:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Create Order
Publish Event
Done
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It no longer cares who needs the information.&lt;/p&gt;
&lt;p&gt;It simply announces:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Order Created
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Anyone interested can react.&lt;/p&gt;
&lt;p&gt;This changes everything.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;thinking-in-events-instead-of-calls&quot;&gt;Thinking in Events Instead of Calls&lt;/h3&gt;
&lt;p&gt;Traditional systems think:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Do this.
Then do that.
Then do another thing.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Event-driven systems think:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Something happened.
Whoever cares can respond.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That shift sounds small.&lt;/p&gt;
&lt;p&gt;Architecturally, it is enormous.&lt;/p&gt;
&lt;p&gt;The producer no longer knows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Who consumes the event&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How many consumers exist&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When consumers process it&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What consumers do with it&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The producer simply publishes facts.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-message-broker-becomes-the-traffic-controller&quot;&gt;The Message Broker Becomes the Traffic Controller&lt;/h3&gt;
&lt;p&gt;A message broker sits between producers and consumers.&lt;/p&gt;
&lt;p&gt;Examples include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Apache Kafka&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RabbitMQ&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Amazon SNS&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Amazon SQS&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The broker receives events and distributes them to interested systems.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Publisher
    ↓
Broker
 ├── Inventory
 ├── Email
 ├── Billing
 ├── Analytics
 └── Fraud Detection
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Services no longer communicate directly.&lt;/p&gt;
&lt;p&gt;The broker acts as the central nervous system.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;why-business-leaders-should-care&quot;&gt;Why Business Leaders Should Care&lt;/h2&gt;
&lt;p&gt;Most architectural decisions eventually become business decisions.&lt;/p&gt;
&lt;p&gt;Publish-Subscribe creates advantages that executives feel directly.&lt;/p&gt;
&lt;h3 id=&quot;faster-feature-delivery&quot;&gt;Faster Feature Delivery&lt;/h3&gt;
&lt;p&gt;Imagine marketing wants a loyalty points system.&lt;/p&gt;
&lt;p&gt;In a tightly coupled architecture:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Modify Order Service
Retest Order Service
Redeploy Order Service
Risk Order Service
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In Pub/Sub:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Create Loyalty Consumer
Subscribe to Order Created
Deploy Independently
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The order system remains untouched.&lt;/p&gt;
&lt;p&gt;New business capabilities can be added safely.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;reduced-revenue-risk&quot;&gt;Reduced Revenue Risk&lt;/h3&gt;
&lt;p&gt;If Analytics fails:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Orders continue.
Payments continue.
Customers continue.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Only analytics is affected.&lt;/p&gt;
&lt;p&gt;The failure is isolated.&lt;/p&gt;
&lt;p&gt;This dramatically reduces blast radius.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;better-organizational-scaling&quot;&gt;Better Organizational Scaling&lt;/h3&gt;
&lt;p&gt;As companies grow:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Payments Team
Inventory Team
Data Team
Growth Team
Customer Team
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each team can consume events independently.&lt;/p&gt;
&lt;p&gt;Teams become less dependent on one another.&lt;/p&gt;
&lt;p&gt;This increases development velocity.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;why-developers-love-event-driven-systems&quot;&gt;Why Developers Love Event-Driven Systems&lt;/h2&gt;
&lt;p&gt;Developers eventually discover a painful truth:&lt;/p&gt;
&lt;p&gt;The hardest part of scaling is not traffic.&lt;/p&gt;
&lt;p&gt;It's dependencies.&lt;/p&gt;
&lt;p&gt;Pub/Sub removes many of them.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;loose-coupling&quot;&gt;Loose Coupling&lt;/h3&gt;
&lt;p&gt;Without Pub/Sub:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Order Service
    ↓
Inventory
    ↓
Email
    ↓
Analytics
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With Pub/Sub:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Order Service
      ↓
Broker
      ↓
Consumers
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The producer has one dependency.&lt;/p&gt;
&lt;p&gt;Instead of ten.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;independent-deployments&quot;&gt;Independent Deployments&lt;/h3&gt;
&lt;p&gt;A team can deploy:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Recommendation Engine
Fraud Detection
Customer Segmentation
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;without touching the ordering system.&lt;/p&gt;
&lt;p&gt;This dramatically reduces deployment risk.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;better-resilience&quot;&gt;Better Resilience&lt;/h3&gt;
&lt;p&gt;Suppose Billing Service crashes.&lt;/p&gt;
&lt;p&gt;The broker stores events.&lt;/p&gt;
&lt;p&gt;When Billing returns:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Order Created Event #1001
Order Created Event #1002
Order Created Event #1003
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;can still be processed.&lt;/p&gt;
&lt;p&gt;The platform recovers automatically.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;but-publish-subscribe-creates-new-problems&quot;&gt;But Publish-Subscribe Creates New Problems&lt;/h2&gt;
&lt;p&gt;Many architecture articles stop at benefits.&lt;/p&gt;
&lt;p&gt;Production systems do not.&lt;/p&gt;
&lt;p&gt;Every architectural gain introduces tradeoffs.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;problem-1-eventual-consistency&quot;&gt;Problem #1: Eventual Consistency&lt;/h3&gt;
&lt;p&gt;In synchronous systems:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Order Created
Inventory Updated
Response Returned
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Everything happens immediately.&lt;/p&gt;
&lt;p&gt;In Pub/Sub:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Order Created
Response Returned

Inventory Updated Later
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is now a time gap.&lt;/p&gt;
&lt;p&gt;Systems may temporarily disagree.&lt;/p&gt;
&lt;p&gt;This is called:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Eventual Consistency&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One of the most misunderstood realities of distributed systems.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;problem-2-duplicate-events&quot;&gt;Problem #2: Duplicate Events&lt;/h3&gt;
&lt;p&gt;Networks fail.&lt;/p&gt;
&lt;p&gt;Retries happen.&lt;/p&gt;
&lt;p&gt;Consumers crash.&lt;/p&gt;
&lt;p&gt;The same event may arrive twice.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Order Created #123
Order Created #123
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Consumers must be idempotent.&lt;/p&gt;
&lt;p&gt;Otherwise:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Inventory reduced twice
Customer charged twice
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Production incidents happen.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;problem-3-observability-becomes-hard&quot;&gt;Problem #3: Observability Becomes Hard&lt;/h3&gt;
&lt;p&gt;In monolithic workflows:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Request → Response
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Easy to trace.&lt;/p&gt;
&lt;p&gt;In event-driven systems:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Order Created
    ↓
Inventory Updated
    ↓
Billing Created
    ↓
Email Sent
    ↓
Analytics Updated
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A single customer action can generate dozens of events.&lt;/p&gt;
&lt;p&gt;Tracking failures becomes significantly harder.&lt;/p&gt;
&lt;p&gt;This is why mature organizations invest heavily in:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Distributed tracing&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Correlation IDs&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Event monitoring&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Audit logs&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;how-large-platforms-actually-think&quot;&gt;How Large Platforms Actually Think&lt;/h2&gt;
&lt;p&gt;The most successful architectures do not ask:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&quot;Which service should call which?&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Instead they ask:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&quot;What business events exist?&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Examples:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Order Created
Payment Authorized
Shipment Created
Invoice Generated
User Registered
Subscription Renewed
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These events become the language of the business.&lt;/p&gt;
&lt;p&gt;Systems are then built around reacting to those events.&lt;/p&gt;
&lt;p&gt;The result is an architecture that grows with the company instead of fighting it.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;the-real-lesson&quot;&gt;The Real Lesson&lt;/h2&gt;
&lt;p&gt;Publish-Subscribe is not primarily about messaging.&lt;/p&gt;
&lt;p&gt;It is about organizational scalability.&lt;/p&gt;
&lt;p&gt;It allows systems to evolve without every team depending on every other team.&lt;/p&gt;
&lt;p&gt;It reduces blast radius.&lt;/p&gt;
&lt;p&gt;It improves resilience.&lt;/p&gt;
&lt;p&gt;It accelerates feature delivery.&lt;/p&gt;
&lt;p&gt;But it also introduces complexity, eventual consistency, and operational challenges that teams must be prepared to handle.&lt;/p&gt;
&lt;p&gt;The companies that scale successfully are rarely the ones with the most services.&lt;/p&gt;
&lt;p&gt;They are the ones with the clearest events.&lt;/p&gt;
&lt;p&gt;Because once systems start speaking in events instead of direct dependencies, growth becomes far easier to sustain.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;key-takeaway&quot;&gt;Key Takeaway&lt;/h4&gt;
&lt;p&gt;A mature architecture doesn't ask:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&quot;Who should I call next?&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It asks:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&quot;What happened?&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That single shift from commands to events is one of the biggest architectural transitions in modern software systems.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/23894/publish-subscribe-how-modern-systems-scale-without-becoming-a-monolith</guid>
<pubDate>Fri, 31 Jul 2026 16:57:53 +0000</pubDate>
</item>
</channel>
</rss>