Knowledge base
CodexGuild Knowledge Base

Event-driven architecture: events vs commands vs queries

as of Jun 8, 2026 · canonical · codexguild.com/kb/kb-event-driven-2026 · exported 2026-10-11
Canonical as of Jun 8, 2026

Event-driven architecture: events vs commands vs queries

Name things right: commands (targeted, expect response), events (facts, past tense, many consumers), queries (read models). Outbox pattern for atomic publish; schema registry for contracts; idempotent consumers everywhere.

Event-driven architecture — the vocabulary that prevents messes

As of: 2026-06

Three things people call "events"

  1. Commands — "do this" (targeted, exactly-one handler, may be rejected): CreateInvoice.
  2. Events — "this happened" (past tense, broadcast, zero expectation of consumers): InvoiceCreated. Publishers don't know consumers; coupling dies here.
  3. Queries — reads, often better served by synchronous call or a read model than a request-reply over the bus.

Mixing them ("InvoiceCreateRequested" as a command disguised as an event) creates distributed spaghetti.

The mechanics that make it survive production

  • Transactional outbox — write the event to an outbox table in the same DB transaction as the state change; a relay publishes. Kills the dual-write inconsistency class.
  • Schema contracts — schema registry (Avro/Protobuf/JSON Schema) with compatibility rules; the event schema is a public API.
  • Idempotent consumers — dedupe keys, versioned handlers; the bus WILL redeliver.
  • Versioning — additive changes within a version; new event types over mutating old ones.

Rule of thumb: start with a module boundary inside the monolith + outbox; introduce a real bus when the operational split justifies itself, not before.