Blog

Event-Driven Architecture: The Essential Components Beyond Kafka 

Piotr Pękala

August 3, 2026
13 minutes

What Is an Event-Driven Architecture? And Why Kafka Alone Is Not an Event-Driven Platform

Event-driven architecture (EDA) enables applications to communicate through events, helping organizations build scalable, loosely coupled, and real-time systems. While Apache Kafka is often the foundation of these architectures, building an enterprise-ready event-driven platform requires much more than an event broker.

When teams adopt event-driven architecture, the first hard problem usually isn't Kafka. It's everything that has to sit around Kafka. The broker is a commodity: well understood, well instrumented, well supported. What separates an event-driven system from a "we have Kafka now" project is the supporting stack: discovery, contracts, observability, security, governance, and the developer experience that ties them together.

We've spent the last few years building a reference environment that takes those areas seriously. It isn't a product pitch. It's a battle-tested stack with end-to-end implementations of each concern. The point isn't the tooling. It's the shape of the problem and the trade-offs we keep coming back to at every layer. This post is a tour of those areas at the altitude of "what matters and why," with separate deep-dives to follow for each.

If your organization is moving from "we have a Kafka cluster" to "we have a democratized, self-service event-driven platform," what follows is the map of what you'll have to think about.

The Essential Components of an Event-Driven Platform

At the centre, an event-driven system is deceptively simple: producers publish to a streaming platform, consumers read from it, and schemas travel with every event. That core never changes. What grows around it is a set of concern areas, each one a discipline in its own right.



Essential Components of an Event-Driven Platform

We group those concerns into five areas, each splitting into two sub-concerns, plus one cross-cutting layer that sits over the rest:

  • Events Democratization: making events discoverable and explorable: a curated Event Catalog & Discovery surface, and a raw Kafka UI & Event Search surface.
  • Kafka Management: operating the platform: Governance & Self-Service for who can do what, and Monitoring for whether it's healthy.
  • Observability & Debugging: understanding runtime behaviour: Event Topology & Lineage (the static-ish map of who talks to whom) and Tracing (the per-request causal story).
  • Data Quality: keeping payloads trustworthy: Schema Registry & Evolution and Quality Checks & Contract Testing.
  • Data Security: protecting the data and access to it: Access Control & Encryption and GDPR / PII / Compliance.
  • Developer Portal / Marketplace (cross-cutting): a single self-service surface over all of the above: one catalog, one place to request access, one front door.

Each of these is a mix of discipline and tools. Picking a tool too early is the most common failure mode we see. Here's how we think about each area, and the two concerns inside it.

Event Democratization 

The most important shift event-driven teams make is treating events as products with owners, contracts, consumers, and lifecycles, and not as ephemeral messages on a bus. Democratization is what makes that real for the rest of the organisation: if people can't find an event, it isn't a product, it's a secret.

Event Catalog & Discovery 

You need a catalog of what events exist, who owns them, what they mean, and what flows are built on top. We build this around an auto-populated event catalog that listens to the schema registry's change-event stream: every time a schema or spec is registered, the catalog reflects it within seconds. Organisational metadata (teams, domains, ownership) flows in from version control, where it belongs.

The trade-off we keep in mind: a catalog that requires manual curation will be stale within a quarter. A catalog driven entirely by metadata leaks every internal topic to every developer. The sweet spot is auto-discovered, human-curated: the catalog learns about events from the registry, but only surfaces what producers explicitly declare, so teams stay in control of what's public.

Kafka UI & Event Search 

The catalog answers "what events exist and what do they mean?" It does not answer "what's actually on orders-completed right now, and why does this one message look wrong?" That's the operational counterpart: a UI to browse topics, inspect live messages, search by key or content, and check consumer-group offsets.

The distinction matters. The catalog is the curated, contract-level view: the product shelf. The operational UI is the raw, byte-level view: the loading dock. Teams reach for the first to design against an event and the second to debug one. Conflating them produces either a catalog cluttered with operational noise or a debugging tool that pretends payloads are always well-formed. We keep them as two surfaces serving two questions.

Kafka Management 

Once events are discoverable, the platform underneath them has to be operable: by many teams, without a central gatekeeper becoming the bottleneck, and without losing the plot on whether it's healthy.

Governance & Self-Service 

Every change to access ("can my new service read orders-completed?") is a potential friction point. If a human has to edit a YAML and ship a PR for every grant, you'll have a queue of pending requests within weeks. If anyone can grant themselves whatever they want, the security model collapses.

The answer is declarative governance plus a self-service workflow on top:

  • A single descriptor in git holds the governed topics, the access grants, and the team ownership. The artifacts actually applied to the cluster (the ACLs, the policy data, whatever your engine consumes) are derived from this descriptor; never hand-edited.
  • A self-service portal lets developers request access through a familiar UI; an approver clicks through; the result is reconciled back into the descriptor.
  • The applied state of the cluster is always traceable to a PR-reviewed declaration. Drift between the descriptor and the cluster is detectable in CI.

Monitoring

Governance decides who may use the platform; monitoring tells you whether it's coping. Watch broker health (throughput, partition counts, in-sync replicas, request latency, heap), and, the metric teams feel first, consumer lag per group: because a quietly falling-behind consumer is the most common way an event-driven system degrades without throwing an error.

The principle we hold here: the broker is part of the system, not just its substrate. Cluster metrics and application behaviour belong on the same pane of glass, because most "Kafka is slow" incidents are actually "a consumer stopped keeping up": a question you can only answer by looking at both at once.

Observability & Debugging 

Monitoring tells you the platform is healthy in aggregate. Observability answers the question every event-driven team has at 3am: "What just happened to this event?" The traditional answer, tail -f across many services, does not scale. Two complementary views do.

Event Topology & Lineage 

Before you can debug a flow, you have to know the flow exists. Who produces order-events? Who consumes it? What does it fan out into? We get this two ways that reinforce each other: producers and consumers declare their topics in their specs (intent), and the tracing layer observes real producer→consumer edges from live traffic (reality). Where the two disagree: a declared consumer that never reads, an observed edge nobody documented, that gap is itself a finding.

The principle: lineage should emerge from observed traffic, not be maintained by hand. A manually drawn topology diagram is wrong the day after someone deploys.

Tracing

For the per-request story, we thread an OpenTelemetry context across every hop, carried in a Kafka header. Crucially, we seed each trace ID from the business UUID at the root producer, so a trace ID isn't an opaque hex blob; it's the order ID, the event ID, the thing humans already use to talk about a transaction. Search the trace backend by business UUID and you get the full causal tree across services. The tracing layer is otherwise payload-agnostic; downstream services don't have to know the business field.

On top of tracing we layer RED metrics (rate, errors, duration per topic, per service) derived directly from spans; no separate instrumentation in each service. The principle: observe at the boundary (every produce, every consume) and let everything else fall out. Don't ask developers to instrument anything beyond what their framework gives them for free.

Ensuring Data Quality in Event-Driven Architecture

If events are products, their payloads have to be trustworthy: both structurally (does this conform to a contract?) and over time (can I evolve the contract without breaking a consumer who isn't in the room?).

Schema Registry & Evolution

Schemas are the interface contract of an event. The hard part is evolution: once you publish a contract, you cannot break it without breaking somebody. A schema registry holds the source of truth and enforces compatibility on registration: backward, forward, full; pick the rule per topic and enforce it at the boundary, so a breaking change is rejected at the door rather than discovered in production.

We also keep the contract and the code in the same repository. A producer's spec lives next to its source; schemas register at startup. There's no "spec drift" because the spec is the build.

Quality Checks & Contract Testing

Registry compatibility is necessary but not sufficient: it checks that a new schema is compatible, not that it's good. The second concern catches the rest, mostly in CI: spec linting (does every topic declare an owner? are operation IDs consistent? do consume operations declare a consumer group?) and breaking-change diffing against the base branch, so problems surface before code merges, not after producers ship.

The direction this naturally points is runtime validation. Linting and diffing prove the contract is well-formed; they can't prove that the messages actually flowing over a topic honour it: that amount is really greater than zero, that a cross-field invariant holds, that a producer hasn't quietly started emitting nulls in a field it promised to fill. The good-practice next step is to move validation onto live traffic: a contract monitor or validating gateway that checks semantic rules on real events and alerts on (or quarantines) violations, so a bad payload is caught the moment it's published, not three hops downstream when a consumer falls over. Think of it as two tiers of the same discipline: structural contracts enforced at merge time, semantic contracts enforced at runtime; and treat the runtime tier as where a maturing platform is heading, even if you start with the CI tier.

Securing an Event-Driven Platform 

This is the area where we see the most "we'll get to it later," and the most regret six months later. Security in event-driven systems is layered, and a weak link at any layer voids the rest.

Access Control & Encryption

The table-stakes layers, each a distinct gate:

  • Transport: TLS on every application listener. Not negotiable.
  • Identity: service identities issued by an identity provider, so the principal that authorises an operation traces back to a real client, not a static credentials file.
  • Authorisation: explicit per-principal grants for who can produce to or consume from each topic. Default-deny, never default-allow. The choice between native broker ACLs and an external policy engine is a real trade-off (a separate post); both can be done well, but only when grants are managed declaratively, not by manual operator commands.
  • Encryption at rest: the broker's log directory should be unreadable to anyone with disk access who isn't the broker.

A cross-cutting point: identity, authorisation, and decryption are three different gates. A service can authenticate, get past the broker's ACL, and still be unable to read sensitive fields because its key-management token lacks decrypt permission. Each gate exists for a reason; collapsing them creates blind spots.

GDPR / PII / Compliance

This is where most teams stop too early. A topic protected by ACLs still has plaintext payload bytes that any authorised consumer can read. If an analytics consumer legitimately needs the action and timestamp from a user event, why does it need to see the user's email? It doesn't, and field-level encryption for PII-tagged fields, with a KMS-backed envelope gated by per-service decrypt permissions, is how you enforce least privilege on the payload itself.

Tag the sensitive fields, encrypt them at the boundary, and the same event carries different readable content depending on who's reading it. The crypto foundation also sets up the harder compliance work: right-to-erasure via per-subject key destruction (crypto-shredding), which we have a design for but have not yet implemented.

The Cross-cutting Layer: Developer Portal / Marketplace 

Each of the five areas brings its own UI: an event catalog, a schema browser, a governance portal, an operational Kafka UI, dashboards, traces. For a single team this is fine. For a multi-team organisation it's six tabs to find one thing.

The umbrella layer, variously called an internal developer portal, a service catalog, or an event marketplace, exists to make every service discoverable in one place, with its owners, contracts, dashboards, runbooks, and access requests linked together. It sits over discovery, governance, quality, and security as a single self-service front door: one catalog, one subscription flow, one access-request path.

We treat this layer as valuable at organisational scale, not at team scale: small teams gain little, but a hundred-engineer org gains compounding benefits from a single searchable catalog and a single self-service story. The investment shape differs from the rest of the stack: less about adding new substance, more about aggregating what's already there.

Cross-cutting Principles 

Some patterns recur across every area we've built:

  • Source of truth in git: for schemas, governance, topology. The cluster is the applied state of what's in the repo. Anything else drifts.
  • Contracts at the boundary: specs alongside source code; registration on startup; compatibility enforced at the registry; breaking changes caught in CI.
  • Observability is not a feature: it's a property of how the system is built. Trace context propagates by default; metrics derive from spans; lineage emerges from observed traffic.
  • Default-deny everywhere: authorisation, encryption, and field access all start closed. Grants are explicit and reviewable.
  • Self-service with guardrails: humans request what they need through a portal, but the request flows through approval and ends up declaratively recorded.
  • Honest about scope: we don't pretend everything is implemented. Knowing what you haven't solved is part of the discipline.

Why This Matters 

The pattern across every area is the same: the easy path is to pick a tool. The valuable path is to first understand the shape of the problem you're solving, the trade-offs you're making, and the guardrails you're putting in place. Tools change every two years. Trade-offs don't.

What we've built isn't a product. It's a blueprint architecture that captures dozens of decisions, made deliberately, with the reasoning. That reasoning is what travels, into your context, your tools, your team, when we talk.

If you're standing up an event-driven platform, or running one that's outgrown its original assumptions, we'd be happy to compare notes.

Frequently Asked Questions 

Written by

Piotr Pękala

Contact

Let’s discuss how we can support your journey.