{
    "componentChunkName": "component---src-templates-post-template-js",
    "path": "/en/passive_aggressive_events/",
    "result": {"data":{"post":{"id":"5beeb899-e69b-52c9-bed4-7c58b0d35c10","html":"<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px; height: auto\"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/ac3e8b12fe2538f089a41dbaca33a90f/7032b/2026-04-13-cover.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 54.49999999999999%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACqklEQVQozwGfAmD9AEI3I726r87Ry+3s5MjEt5yZiDEwHUs6IEovEEMrDGA/GG1IH2VCGWVBGlY2EE0vDTMhCEk1H2VMNl1GMAA4Lxy+ua3R1tP////r8vCxrqAgIRQxLyFQNRRQMhGAXjiMZjx9Vi1EMBQzKRNRQSkxKxxQPShrTzZcRCwAOioQrauZ1dza8fTs4+rdq6WVMiscblVBVTcTWDoWmXlXmHNLimEzSz0qIyIZYGBTcnZ0aFdEYD4fWT0iAH1sT7rCqY2hi7C8qrbFpJmaipNyW4VjTEAxGjgoEG5dRYdxVIBtUJl7YnJON2FdUYuOi3NrXGFPOFZGMACcmYy7wbydpZamqJiOjYRxeHdHSEEpLSQYIBljXlB3bFpzdmyJjoaYjX03KhoJGBlSWlliY11DQzZZU0QAW15Vc3d0c3ZweHx3d3pybHNzNTw3NTs1Z1pLmYl2SE1EFiAdJiwmPUZCDx4iAxMYCRQTQkY+RD4uPzYmACApJkxYWkRMST9HRG91cXF3eFBUUERKRlJEMltBJGdMK2xSMVhJMkBCQBElMAgWGQAGBS4qHFRDLDAnFgAzNi8vMyo8QTlUV040Ny5RWVkwNS0rMCVaVkdPNhx3XUF1ZlJNNh17X0kXJisACgkABgUdHhV2XD1UOx4AOx0AJRUBMzQneHpyfoJ8ZWljbmteeGBDkmxBhXdjjH5pcGteb11HakgiFxgPAAQBAQ0NBA4NQSkMRjEYAFdJNIiMhaWtq3R1baKbjJiKdTo7MSwtI25uZoiHfp+Ia5mKc19UQRcRBAEDAAIMDAMQEAAKCTQiCj4xGgCMdlqpmoWonIlURjBkSyqhgFuDcFZsWDuBbVOObUR5USM6Jw4DAgAAAAACCAcDExYBDQsODgQ3JAsvKRmdM9ZinUgEKgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"cover\"\n        title=\"cover\"\n        src=\"/static/ac3e8b12fe2538f089a41dbaca33a90f/a331c/2026-04-13-cover.png\"\n        srcset=\"/static/ac3e8b12fe2538f089a41dbaca33a90f/36ca5/2026-04-13-cover.png 200w,\n/static/ac3e8b12fe2538f089a41dbaca33a90f/a3397/2026-04-13-cover.png 400w,\n/static/ac3e8b12fe2538f089a41dbaca33a90f/a331c/2026-04-13-cover.png 800w,\n/static/ac3e8b12fe2538f089a41dbaca33a90f/8537d/2026-04-13-cover.png 1200w,\n/static/ac3e8b12fe2538f089a41dbaca33a90f/7032b/2026-04-13-cover.png 1408w\"\n        sizes=\"(max-width: 800px) 100vw, 800px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p>Have you ever heard phrases like.</p>\n<blockquote>\n<p>Just an update, the milk ran out. Someone finished it and put the empty carton back.</p>\n</blockquote>\n<p>Or</p>\n<blockquote>\n<p>So everyone is aware, the meeting started 15 minutes ago.</p>\n</blockquote>\n<p>Or</p>\n<blockquote>\n<p>Heads up: the coffee machine is empty again.</p>\n</blockquote>\n<p>Or</p>\n<blockquote>\n<p>It’s fine, I already walked the dog.</p>\n</blockquote>\n<p>I’m sure you either heard or used such phrases.</p>\n<p>We all know that there’s some intention behind it.</p>\n<p>The intention is not to inform, but to trigger some action.</p>\n<p>Formally, we’re reporting on events to announce the facts, but in practice, they’re passive-aggressive words. The real intention is to command someone.</p>\n<p>We don’t want to inform you that the trash bin is full, but we want someone to take it out. We don’t want to inform you that the coffee machine requires a coffee bean refill, but we want someone to do it.</p>\n<p>Passive-aggressive tone is the worst. It’s toxic for both sides of the communication. Usually, it’s just better to ask someone to do it.</p>\n<p>The same rule also works in Event-Driven Modelling. We should avoid passive-aggressive communication at all costs.</p>\n<p><strong>We should watch out for Passive-Agressive Events. So events that should be commands.</strong></p>\n<p>I already warned you in past: <a href=\"/en/dont_let_event_driven_architecture_buzzwords_fool_you/\">don’t let Event-Driven Architecture buzzwords fool you</a>.</p>\n<p>Event-Driven Architecture is an integration architecture style. We’re trying to model our business processes so they run smoothly. For that, we prefer a non-blocking communication flow, with things happening in parallel at their own pace. The goal is to achieve autonomous components that reduce the time needed to understand them. That helps <a href=\"/en/removability_over_maintainability/\">maintain, or even replace them</a> as your business evolves.</p>\n<p>And events are enablers for that. They notify of what has happened, allowing other components to interpret facts and take the next steps.</p>\n<p>But… Let me show one more photo.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px; height: auto\"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/7601e4c1d83592534cd7476672138d7d/6c738/2026-04-13-parliament.jpg\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 55.00000000000001%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAEDAgX/xAAVAQEBAAAAAAAAAAAAAAAAAAABAP/aAAwDAQACEAMQAAAB5qWBsRI//8QAFxAAAwEAAAAAAAAAAAAAAAAAAAIRAf/aAAgBAQABBQIpGHLRtm//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAXEAADAQAAAAAAAAAAAAAAAAAAARAh/9oACAEBAAY/ApiFMP/EABoQAQADAQEBAAAAAAAAAAAAAAEAESExQXH/2gAIAQEAAT8htDO/Zq3Ky9gmon2evr2K6iVJCf/aAAwDAQACAAMAAAAQ6z//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAWEQEBAQAAAAAAAAAAAAAAAAAAARH/2gAIAQIBAT8QZH//xAAaEAEBAQEBAQEAAAAAAAAAAAABESEAMUGh/9oACAEBAAE/EBgW4gmThwkKnd8n51JMcS+2xPWCXkIsW4TeSnQMF+nf/9k='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"parliament\"\n        title=\"parliament\"\n        src=\"/static/7601e4c1d83592534cd7476672138d7d/c60e9/2026-04-13-parliament.jpg\"\n        srcset=\"/static/7601e4c1d83592534cd7476672138d7d/37402/2026-04-13-parliament.jpg 200w,\n/static/7601e4c1d83592534cd7476672138d7d/4cda9/2026-04-13-parliament.jpg 400w,\n/static/7601e4c1d83592534cd7476672138d7d/c60e9/2026-04-13-parliament.jpg 800w,\n/static/7601e4c1d83592534cd7476672138d7d/6c738/2026-04-13-parliament.jpg 1200w\"\n        sizes=\"(max-width: 800px) 100vw, 800px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p>It’s parliament, per the official definition: a room full of angry, shouting people.</p>\n<p><strong>If we model our communication only in terms of events, our system will look just like that.</strong> We’d just announce new facts in a passive-aggressive style and not be interested in what happens next. Oh, wait, are we really not interested? Actually, we are. If someone won’t do what we expect with our information, we’ll be even angrier.</p>\n<p><a href=\"/en/whats_the_difference_between_event_and_command/\">What’s the difference between a command and an event?</a> Both are messages. They convey specific information: a command indicating intent to do something, or an event describing what happened. From the computer’s point of view, they are no different. Only the business logic and the interpretation of the message can distinguish between an event and a command.</p>\n<p>And that’s the main difference: commands can be rejected by the command handler. Events can only be ignored.</p>\n<p>If we send an event, we expect someone to be interested, but we don’t know who or how many components will. We just inform.</p>\n<p>This can easily change into passive-aggressive:</p>\n<blockquote>\n<p>I did my work, now it’s your turn.</p>\n</blockquote>\n<p>And here’s the crucial moment. If we’ll always have a single consumer for an event that needs to run the specific logic and expect to get the particular event back, then it should be a command. It’s not an event, we don’t inform. We just want someone to take the next specific step and let us know when they finish.</p>\n<p>But hey, aren’t we making our communication synchronous?</p>\n<p>What does it even mean, synchronous or asynchronous? That’s what <a href=\"https://www.youtube.com/watch?v=2LMEJ-WGFTk\">Sam Newman discussed in his great talk</a>. The main conclusion is that synchronous vs asynchronous discussion is actually about blocking or non-blocking. And that’s much broader than the technicalities of whether we call something in-process via an HTTP endpoint or a messaging system.</p>\n<p>It’s a common misconception that events are published through a messaging system (e.g. Kafka, RabbitMQ, SQS, WhateverQueue) and commands are sent through WebAPI.</p>\n<p>Those are technicalities. As said, both events and commands are messages; we can send them through a messaging system or via HTTP (e.g., events via webhooks).</p>\n<p>This misleading split stemmed from our expectation about handling, so we expected the command to wait for the result. For events, we don’t expect a specific result, at least in theory.</p>\n<p><strong>If we publish a specific event to the messaging system and expect a specific critical path of follow-up events, then we’re not making our communication non-blocking. It’s still sequential.</strong> We cannot proceed until the expected sequence occurs.</p>\n<p>Whether something is blocking or not is not established by the tools we use, but by how our business process looks.</p>\n<p>Speaking about it.</p>\n<p>Let’s get back to our favourite E-Commerce Order scenario (read more in <a href=\"https://www.architecture-weekly.com/p/predictable-identifiers-enabling\">Predictable Identifiers: Enabling True Module Autonomy in Distributed Systems</a>).</p>\n<p>We could model it so we just publish the <em>OrderConfirmed</em> event and passively-aggressively expect that others will take it from there. So:</p>\n<ul>\n<li>The payment module will initiate the payment.</li>\n<li>Inventory will start completing shipments.</li>\n<li>The notification module will send a confirmation e-mail.</li>\n<li>Fraud detection module will check if the order is not rigged.</li>\n</ul>\n<p>Once we receive information about a successful shipment or payment registration, we can complete the order.</p>\n<p><strong>You may notice two paths for order processing:</strong></p>\n<ol>\n<li><strong>Blocking</strong> - We need to wait for information about payments and shipments. This is our critical path.</li>\n<li><strong>Non-blocking</strong>- Order process shouldn’t stop if the notification wasn’t sent or the data warehouse wasn’t able to process events. We’d like that to happen, but it’s expected rather than critical.</li>\n</ol>\n<p>Now, both payments can fail (if our customer doesn’t have enough money), and the shipment may not be completed (if it’s Black Friday, and multiple people are competing for the same product).</p>\n<p>If that happens, as the ordering module, we also need to take action, for instance, do reimbursement if the shipment wasn’t completed, and eventually cancel the order.</p>\n<p>If we’re just focused on events, we tend to forget about <em>“negative”</em> scenarios. If all communication is through events, then it’s too easy to stay in I-Alread-Did-My-Job mode.</p>\n<p>We may not notice that another module can actually say no:</p>\n<ol>\n<li>Payment module can say: <em>Man, that’s not going to happen, you’ve already run out of money</em>.</li>\n<li>Shipment module can say: <em>Man, I’m sorry, but you weren’t fast enough and we’ve run out of product</em>.</li>\n</ol>\n<p>And both of those scenarios will block successful order completion.</p>\n<p>If we don’t foresee that and stay in passive-aggressive mode, this will have severe consequences: blocked orders, missed communication, and dissatisfied customers.</p>\n<p>How to find such scenarios? <a href=\"/en/intro_to_example_mapping/\">Doing Example Mapping during modelling can be a good option for that</a>.</p>\n<p>Most importantly, we need to embrace the fact that some scenarios require direct, blocking communication, and others don’t. Just like in real life, sometimes it’s just more effective to tell someone to do something. We should avoid micromanagement and aim for autonomy, but not end up with anarchy.</p>\n<p>In our case, it’d be better to have a coordinator (<a href=\"/en/how_to_have_fun_with_typescript_and_workflow/\">workflow</a>, <a href=\"/en/saga_process_manager_distributed_transactions/\">saga, process manager</a>, etc.) that publishes the <em>OrderConfirmed</em> event for modules not on the critical path and sends commands like <em>RecordPayment</em> and <em>InitiateShipment</em>.</p>\n<p>By that, we’re separating responsibilities and making explicit what should be explicit. This also helps in understanding the business process, as you have a central place to see the critical flow and get proper observability.</p>\n<p>Lacking tracing and observability of the business process is one of the most common issues <a href=\"/en/training/\">I see in my clients’ projects</a>. As said, if we don’t want to end up with parliament instead of proper communication in our system, we need to be explicit about our intention.</p>\n<p>Is that all? Not quite, there’s one more message type we model as events that should not be events.</p>\n<p><strong>Gregor Hohpe, in <a href=\"https://www.enterpriseintegrationpatterns.com/patterns/messaging/Message.html\">“Enterprise Integration Patterns”</a>, besides <a href=\"https://www.enterpriseintegrationpatterns.com/patterns/messaging/EventMessage.html\">Event</a> and <a href=\"https://www.enterpriseintegrationpatterns.com/patterns/messaging/CommandMessage.html\">Command</a> defines one more message type: <a href=\"https://www.enterpriseintegrationpatterns.com/patterns/messaging/DocumentMessage.html\">Document</a>.</strong></p>\n<p>What’s the Document? It’s a state. Or to be precise: self-contained data we have at a certain point in time. We can store it, but we can also publish information about its new value.</p>\n<p>That’s probably why Martin Fowler frames it as <a href=\"https://martinfowler.com/articles/201701-event-driven.html\">Event-Carried State Transfer</a>, and I don’t like that term. For me, it’s extremely misleading; it’s not an event, as it doesn’t tell of what has happened, but what has changed.</p>\n<p>It’s a common anti-pattern, a variation of <a href=\"/en/state-obsession/\">State Obsession</a>. Too many people believe it’s fine to connect the messaging system to the database, use tools like <a href=\"https://en.wikipedia.org/wiki/Change_data_capture\">Change Data Capture</a>, and publish it automatically to others.</p>\n<p>Still, we’re ending up again in passive-aggressive communication:</p>\n<blockquote>\n<p>You have all you need. The whole state is in the <em>events</em>, just interpret it.</p>\n</blockquote>\n<p>But how can you reason about what has happened if instead of <em>OrderConfirmed</em> you get <em>OrderCreated</em>, <em>OrderUpdated</em>, <em>OrderDeleted</em>?</p>\n<p>You not only deal with <a href=\"/en/clickbait_event/\">Clickbait Events</a> but also have a leaking business abstraction. All consumers need to understand the internals of your processing to detect a specific type of change. I wrote about it in detail in <a href=\"/en/internal_external_events/\">Internal and external events, or how to design event-driven API</a>.</p>\n<p>Again, the loose coupling of the event-driven processing is only loose for producers; consumers need to adapt. This can lead to hidden coupling, where a change in the producer breaks consumer flows. And that’s the worst type of coupling you can get.</p>\n<p><strong>If we’re making commands explicit, we’re also making an explicit relationship between components.</strong> It’s no longer flattened to producer &#x3C;=> consumer, where the producer always shapes the communication. Now, if the other component exposes a command, that’s the driving force behind its behaviour. This helps to shape autonomy. In our case, we could make the Payment Module a generic module with a stable public API for registering payments, and an ordering module that requests them, in accordance with the Shipment Module. Fraud Detection could continue subscribing to events, as it already does. <a href=\"https://github.com/ddd-crew/context-mapping\">Context Mapping</a> can greatly help in finding those relationships.</p>\n<h2 id=\"tldr\" style=\"position:relative;\"><a href=\"#tldr\" aria-label=\"tldr permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>TLDR</h2>\n<p>We tend to be all about events these days, but they’re not the only message types. In our systems, messages take various forms: Events, Commands, and Documents, each serving distinct purposes:</p>\n<ul>\n<li><strong>Documents are all about state transitions</strong>, which are essential for syncing data across services but missing deeper business insights.</li>\n<li><strong>Commands represent a clear intent to act</strong>, directed with an expectation of execution, and can be accepted or rejected.</li>\n<li><strong>Events are immutable facts</strong>, announced without waiting for a response. They’re like broadcasting news, hoping it catches the right ears.</li>\n</ul>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px; height: auto\"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/7fbe63cf6b9ff88cc94828c5025f409d/58e7d/2026-04-13-message_types.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 56.49999999999999%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACaUlEQVQozx2S20uTcRzG3z+hq266DvoDug+KECKD6EqEsBOFdMCLriSTJCPEi1kmKpuSlpbLA02d07WDm4dVouIYc2ytd+f93vd3Puzd0uoVvrcfng/P89UorzFhlQFMZfSqgQ1IKwY2ES2UQK5QLVVhoQSqJkVEmJgDxMoAVQCkXGGqNMIUk41EMj396YtvLRha3/AH1gOhaDiyGVzfWPB4XeOTXt+3ldWAZ8m3vOKfnfvq9fmBSaiwNANzSCThFpMNSAQkgkmrDLBeACaRQtaYUIYB8/nCb72Y1UvZXAlAColAVGmYKcJr9jFFhWUgSgnbi6c7e4bdq7vL4fiHhQ3/dmo7aRYBl9YRV38It5ANSxvGVGEqEZFMNnK54tiQc2Up0N/RPjU5PzjkfvKw+3bP/IPWO7FwiFvHJuYniLRhJiwm61RYTFjKOtLz5ZA/2Pdq4OLZczOjQ9HlwGfnzOaP5GjHo3g0rI7+2gXLOuE1zJSGiJ2JmEJUElHL5sCv796Wq9dOnzrz8tmL8d4+V9/IQSzi+Ti7u7XFVANiWxhhAYnU4IkAJBJSyWQdYdb1tPvS+QuO+1cGH7e1NjX33GzeGXuddg+moiGijhGRmNcwlfZUkCp0QkLCAaSYytHh912dvQsTI/HwXP5wP7jkSS1OmQexSqVMRYNQW5gwZWsTKgmz/6RosPbxSNvEz3vTe5sZs8ZAwnUj5rh86GwCenKnmG1xXb8713prumU/neC8bhKuRRIgm6+WK4aBpTOYGPAd9C/u7Waq1KwkPL077ufx+S5YyGZA0bHW/zboeBd6o1dKXNT/t/0PRSkdITeJTJEAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"message types\"\n        title=\"message types\"\n        src=\"/static/7fbe63cf6b9ff88cc94828c5025f409d/a331c/2026-04-13-message_types.png\"\n        srcset=\"/static/7fbe63cf6b9ff88cc94828c5025f409d/36ca5/2026-04-13-message_types.png 200w,\n/static/7fbe63cf6b9ff88cc94828c5025f409d/a3397/2026-04-13-message_types.png 400w,\n/static/7fbe63cf6b9ff88cc94828c5025f409d/a331c/2026-04-13-message_types.png 800w,\n/static/7fbe63cf6b9ff88cc94828c5025f409d/58e7d/2026-04-13-message_types.png 1188w\"\n        sizes=\"(max-width: 800px) 100vw, 800px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p>Event-Driven Architectures enable loose coupling, but only for producers. To make consumers loosely coupled, we need to take extra steps, embrace different message types, and have them participate in modelling business processes.</p>\n<p>If we go too far with an event-all-the-things communication style, we’ll make our system a room full of shouting people, with a passive-aggressive communication style. Or just aggressive.</p>\n<p>In consequence, we won’t know what’s happening in our system, will see only noise, and will have a hard time making it reliable, observable and predictable. We should treat our messages as a communication contract, API and model their flow in a way that shapes our regular communication.</p>\n<p><strong>So next time, ask yourself if your event shouldn’t be a command. If it has always had a single consumer and you expect a specific event back, then it’s probably so.</strong> It’s all about being clear about the intention, not lying to yourself and others.</p>\n<p>I hope this article will equip you with the knowledge to fix that.</p>\n<p><strong>If you’re dealing with such issues, I’m happy to help you through consulting, <a href=\"/en/training\">training</a> or mentoring. <a href=\"mailto:oskar@event-driven.io\">Contact me</a> and we’ll find a way to unblock you!</strong></p>\n<p><strong>See also more in series about <a href=\"/en/anti-patterns/\">event modelling anti-patterns</a>:</strong></p>\n<ul>\n<li><a href=\"/en/state-obsession/\">State Obsession</a>,</li>\n<li><a href=\"/en/property-sourcing/\">Property Sourcing</a>,</li>\n<li><a href=\"/en/i_will_just_add_one_more_field/\">I’ll just add one more field</a>.</li>\n<li><a href=\"/en/clickbait_event/\">Clickbait event</a>,</li>\n<li><a href=\"/en/passive_aggressive_events\">Passive Aggressive Events</a>,</li>\n<li><a href=\"/en/one_or_more_event_that_is_the_question/\">Should you record multiple events from business logic?</a>,</li>\n<li><a href=\"/en/on_putting_stream_id_in_event_data/\">Stream ids, event types prefixes and other event data you might not want to slice off</a>.</li>\n</ul>\n<p><strong>Check also more general considerations:</strong></p>\n<ul>\n<li><a href=\"/en/events_should_be_as_small_as_possible/\">Events should be as small as possible, right?</a>,</li>\n<li><a href=\"/en/whats_the_difference_between_event_and_command/\">What’s the difference between a command and an event?</a>,</li>\n<li><a href=\"/en/internal_external_events/\">Internal and external events, or how to design event-driven API</a>,</li>\n<li><a href=\"/en/event_streaming_is_not_event_sourcing/\">Event Streaming is not Event Sourcing!</a>,</li>\n<li><a href=\"/en/dont_let_event_driven_architecture_buzzwords_fool_you/\">Don’t let Event-Driven Architecture buzzwords fool you</a>,</li>\n<li><a href=\"/en/how_to_design_software_architecture_pragmatically/\">How to design software architecture pragmatically</a>,</li>\n<li><a href=\"/en/gdpr_in_event_driven_architecture/\">How to deal with privacy and GDPR in Event-Driven systems</a>.</li>\n</ul>\n<p>Cheers!</p>\n<p>Oskar</p>\n<p>p.s. <strong>Ukraine is still under brutal Russian invasion. A lot of Ukrainian people are hurt, without shelter and need help.</strong> You can help in various ways, for instance, directly helping refugees, spreading awareness, putting pressure on your local government or companies. You can also support Ukraine by donating e.g. to <a href=\"https://www.icrc.org/en/donate/ukraine\">Red Cross</a>, <a href=\"https://savelife.in.ua/en/donate/\">Ukraine humanitarian organisation</a> or <a href=\"https://www.gofundme.com/f/help-to-save-the-lives-of-civilians-in-a-war-zone\">donate Ambulances for Ukraine</a>.</p>","excerpt":"Have you ever heard phrases like. Just an update, the milk ran out. Someone finished it and put the empty carton back. Or So everyone is…","fields":{"slug":"/passive_aggressive_events/","prefix":"2026-04-13","langKey":"en"},"frontmatter":{"title":"Anti-patterns in event modelling - Passive-Aggressive Events","author":"oskar dudycz","category":"Event Sourcing","disqusId":null,"useDefaultLangCanonical":null,"cover":{"childImageSharp":{"resize":{"src":"/static/ac3e8b12fe2538f089a41dbaca33a90f/2a4de/2026-04-13-cover.png"}}}}},"authornote":{"id":"f1fb8a26-256d-5b24-9b06-ad19a0c2961b","html":"<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px; height: auto\"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/f748655e118b2b9d5ce6b7dd6f9f4f85/d2429/2021-10-13-cover.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 55.99999999999999%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAA6cAAAOnAEHlFPdAAAChUlEQVQozyXOTU/acBwA4J+FFmgp/5RCX2AlFVgUgxTCYZNA6KZMooPSiAoaZ8bLjTmEbALRePAygyaLBEl0lyWePGji1YsnT8YDBxMTE+9+iiXu+QQPPDw8nJ2dtVqtZrNZr9cbjUYul8tkMvl8vt1un5yc3Nzc3N7eDofDu7u74+Pj+/v7x8fH6+vr8/NzGA6HOzs73W53f3+/0+mUSqVisbi3t3d0dNTv9w8PDy8uLnq93sHBQblcrtfrp6enl5eXrVarUqnA8/OzruvLy8uDwUDTtJmZmWw22+12Nzc3q9VqKpUqFovT09OFQsHr9SaTyZWVlVgspmlaoVCAl5cXRVE4jotGowghiqJIkpybm/N4PAsLCwghRVF0Xff5fHa7HQDi8Xg6nQaASCQCT09PwWAQXrEsa7VaZVlOp9NjY2Nut1uWZYIgWJYVRZEkSYZhLBaL0WgkCCIUCkGv1xMEAcMwo9EIABRFEQQhSVI0GhUEwWAw0DQ9OjqK4zhFUQzD2O12HMc5jhMEAa6urmRZRgglEgmHwzEyMuJyuXZ3d2u12tTUFAAQBOF0Onmep2mae2V6heM4bG1tIYR4nk8kEqIoAkAgEOh0OvF4XJIkADCZTDzPu1wuk8lks9kQQhiGmc1mkiTB65U5zun3+xFCPp+P5znaRquqGg6HcdyIYRiO4+VyeWlp6f+CpmmDwWAxm0VRAFX9kM3mVlfXJidDPv/bN24pHI4kkyrDMCRJjo8HJMnz6dNsq9W2WmmzhWRZB2W1BSaCmqbDxrfK9naj/r2az2fWvxTfvY98La2pakxRJuY/zy4u5jLZtPox/uPnxvp6YTalLurz7WZt8PvX3z/9f7APp/oT02NdAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"cover\"\n        title=\"cover\"\n        src=\"/static/f748655e118b2b9d5ce6b7dd6f9f4f85/a331c/2021-10-13-cover.png\"\n        srcset=\"/static/f748655e118b2b9d5ce6b7dd6f9f4f85/36ca5/2021-10-13-cover.png 200w,\n/static/f748655e118b2b9d5ce6b7dd6f9f4f85/a3397/2021-10-13-cover.png 400w,\n/static/f748655e118b2b9d5ce6b7dd6f9f4f85/a331c/2021-10-13-cover.png 800w,\n/static/f748655e118b2b9d5ce6b7dd6f9f4f85/d2429/2021-10-13-cover.png 805w\"\n        sizes=\"(max-width: 800px) 100vw, 800px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p>Through my window, I see the result of good plans but poor execution. Opposite my flat, there is a partially completed construction place. Buildings were supposed to be eye-catching Mediterranean style apartments.  Delivery date? Two years ago. Actual? More and more unknown.</p>\n<p>Some time ago, I heard that using Event Sourcing makes creating Event-Driven Architecture easier. The arguments were correct, that if we’re already publishing events to trigger business workflows, then at some point, we may want to also store events to not lose information. Agreed. However, I also heard that keeping the state as events will simplify things. We’ll have a source of truth with a record of the system behaviour. This will allow, e.g. to confront the results of the operations with the recorded state. I’d agree with that, with one distinction. It’s easier as long as you already know Event Sourcing.</p>\n<p>Many people in the DDD community claim that the essential is to properly break down the system into autonomous parts called bounded contexts. Once we have it, the rest is secondary and will sort itself out. For sure.</p>\n<p>Many seasoned programmers speak similarly about new technologies. They claim that they can translate past experience into new technologies. That’s true that by analogy, they can catch the big picture quicker. But isn’t it a bold assumption to say that Win.Forms specialist will learn Angular quickly?</p>\n<p>The end result may differ a lot from the initial ideas. I saw the plan of those buildings next to me. Now I can see the effects of the execution. Or actually, the lack.</p>\n<p>I believe that we should carefully acknowledge not only the point of view of our authorities but also their seating point. If we want to find out how to form a wall, do we ask an architect or a foreman? An architect may know the theory, but the practice is what we’re looking for. On the other hand, if you want to know where to put the wall, you prefer the architect to do measurements. At least if you don’t want to have the roof falling to your head.</p>\n<p>After I had torn a ligament in my knee, I went to two qualified orthopedists. One said I should have surgery and do a reconstruction. The second stated that there is no need for that; rehabilitation should be enough. Guess which one had a specialization in surgery and which in rehabilitation?</p>\n<p>People usually give us advice from the point where they’re currently standing. They are entitled to a biased view. An architect who rarely does programming will tend to downplay the value of implementation and tactical patterns. Midlevel developers will focus on technicalities instead of the global system impact. The team manager or consultant will emphasize the importance of soft skills (or esoteric techniques known only to them).</p>\n<p>The truth is that we need all of them. The excellent plan will fall on the bad execution. The best execution for the wrong case will be just a waste of time. We should carefully evaluate the advice considering what we need and what an expert can give us.</p>\n<p>Therefore, when we’re reading an article, watching a talk, let’s also pay attention to the place where the person is standing. The perspective from there may be much different from where we are right now. That can be good, as it may push us in the right direction. But it may also be misleading, as we accidentally take biases of this person without understanding the tradeoffs. Personally, I prefer to follow not only people from pedestal but also those that are closer to my position. A bit further in the journey, but not too far. That helps me to calibrate my view as those people are more relative to my daily struggles.</p>\n<p>Polish historical leader <a href=\"https://en.wikipedia.org/wiki/J%C3%B3zef_Pi%C5%82sudski\">Józef Piłsudzki</a> reportedly used to say: <em>“Right is like an ass, everyone has its own”</em>.</p>\n<p>Cheers!</p>\n<p>Oskar</p>"},"site":{"siteMetadata":{"facebook":{"appId":""}}}},"pageContext":{"slug":"/passive_aggressive_events/","lang":"en","langKey":"en","prev":{"id":"759c3674-3d52-5530-a074-502fbe9fab4a","fields":{"slug":"/intro_to_example_mapping/","prefix":"2026-03-30","source":"posts","langKey":"en"},"frontmatter":{"title":"The one where Oskar explains Example Mapping","category":"Software Architecture"}},"source":"posts"}},
    "staticQueryHashes": ["2742854296"]}