Event-Driven Microservices with Hazelcast: Series Index

This is a running index of the Building Event-Driven Microservices with Hazelcast series — a multi-part walkthrough of an event-sourced microservices framework built on top of Hazelcast. The series goes through the architectural patterns piece by piece: event sourcing as the source of truth, CQRS and materialized views for fast queries, Hazelcast Jet pipelines for processing, saga patterns for distributed transactions, resilience patterns for production, and observability for everything in between.

The framework itself is a working demo — not a toy, not a slideware reference — that I started years ago at Hazelcast and have been extending recently with the help of Claude Code. Every post in the series ties back to actual running code in the hazelcast-microservices-framework repository on GitHub. If you’d rather read the code first and the prose second, that’s a fine way to do it.

If you’re new here and not sure where to start: read the Foundation posts in order if you want the why before the how, or skip directly to The Series if you’d rather start with code.


Foundation

These three posts set up the context for the rest of the series — why event-driven matters, what the framework is, and how it got built.

  1. Event-Driven Microservices: Avoiding Distributed Monoliths — Why teams who set out to build microservices keep ending up with distributed monoliths, and what an event-driven architecture buys you that synchronous service-to-service calls can’t.

  2. Hazelcast Microservices Framework: Event Sourcing Demo — Introduction to the demo project: a working framework that implements the common microservices patterns on top of Hazelcast, with all the integration points you’d actually need in production.

  3. Launching a Claude Code Project: Design Before You Build — A meta post on the development process: how I went from a vague idea to nine design documents and an implementation plan before writing a single line of code, using Claude’s desktop interface for design and Claude Code for implementation.


The Series

The numbered parts walk through the framework’s architecture one component at a time. Interludes — the shorter, reflective detours — are slotted in at the point in the sequence where they belong rather than collected off to the side.

  • Interlude — How Baseball Invented Event Sourcing 150 Years Ago — a short detour into why the pattern feels familiar to anyone who’s ever kept score at a ballgame. Useful framing before the technical parts begin. Read →
  1. Part 1 — Event Sourcing on Hazelcast: A Practical Introduction — Every UPDATE statement destroys information. Event sourcing flips the model: store the events that produced your state, not the state itself. This post walks through how Hazelcast handles the whole stack — fast event writes, Jet pipelines for processing, sub-millisecond materialized views — without bolting together five different technologies.
  2. Part 2 — Hazelcast Jet Event Pipelines: A Six-Stage Walkthrough — A close look at the Jet pipeline that does the heavy lifting: six stages that turn an inbound event into a persisted record, an updated view, and a published notification, all in under a millisecond. Covers the partitioned-sequence-key design, the ServiceFactory pattern for distributed lambdas, and the lock-free concurrency model that makes the whole thing fast.

  3. Part 3 — Hazelcast Materialized Views: CQRS for Sub-ms Reads — If everything is stored as a sequence of events, how do you actually query anything? Part 3 introduces CQRS and the materialized view layer — pre-computed projections built by the Jet pipeline that give sub-millisecond reads, cross-service denormalization without HTTP fan-out, and free view rebuilds from the event stream.

    • Interlude — A Note on Observability — why the observability post got pushed back to later in the series, and why that didn’t change anything about when to instrument the code. Instrument early; you’ll thank yourself at 2 AM on phase 3. Read →
  4. Part 4 — Saga Pattern: Distributed Transactions Without 2PC — When a business operation spans four services, a single database transaction can’t span them — and two-phase commit’s distributed locks are worse than the problem they solve. Part 4 walks through the saga pattern: a sequence of local transactions coordinated through events, compensation when steps fail, a saga state machine in Hazelcast, and timeout detection for stuck flows.

    • Interlude — On Debugging by Assumption — the saga timeouts I blamed on a maxed-out laptop turned out to be four real bugs, starting with a circuit breaker that tripped on ordinary out-of-stock errors. Measure before you assume. Read →
  5. Part 5 — Vector Similarity Search on Hazelcast with HNSW — Full-text search matches keywords, so “portable computer for games” never finds the gaming laptop sitting in your catalog. Part 5 adds semantic “more like this” search: a local all-MiniLM embedding model (no API key), Hazelcast’s VectorCollection holding the vectors, and HNSW indexing that turns an O(n) scan into an O(log n) lookup — with a brute-force fallback that keeps it fully working on Community Edition.

    • Interlude — On the Vector Store I Didn’t Ask For — I asked Claude for Hazelcast’s VectorCollection and got a from-scratch brute-force store instead. It worked well enough to become the Community Edition fallback — a small parable about AI and enterprise software. Read →
  6. Part 6 — MCP Server for Microservices: AI-Powered Debugging — Five posts of infrastructure later, investigating a failed saga still meant chaining five or six curl commands by hand. Part 6 adds an MCP server — a thin REST proxy with no Hazelcast dependency, exposing ten tools — so an AI assistant can query the views, submit events, inspect sagas, run demo scenarios, and replay failures off the dead-letter queue. The five-command debugging session collapses into a single sentence.

  7. Part 7 — Circuit Breakers and Retry: Resilient Hazelcast Sagas — A slow downstream service shouldn’t take the whole saga down with it, but in a distributed system it will. Part 7 adds circuit breakers and Resilience4j retry: each saga step gets its own breaker that trips when failures spike, exponential backoff that staggers retries to dodge a thundering herd, and a one-line marker interface that sends non-retryable failures — a declined payment — straight to compensation instead of burning the retry budget.

  8. Part 8 — Hazelcast Transactional Outbox: Guaranteed Delivery — After a service processes an event it republishes it for the rest of the saga — and if the shared cluster is unreachable at that instant, fire-and-forget publishing drops the event with nothing left to retry. Part 8 adds the transactional outbox: every event is written to a durable local IMap first, then a separate publisher delivers it to the shared cluster and retries until it lands, trading instant delivery for guaranteed delivery.

  9. Part 9 — Dead Letter Queue + Idempotency: Exactly-Once on Hazelcast — Guaranteed delivery has a tail nobody mentions: at-least-once is also sometimes-twice, and some events fail for good. Part 9 closes both gaps — a dead letter queue that captures failed events with their full payload, failure reason, and saga context for inspect-and-replay, and an idempotency guard built on an atomic putIfAbsent that delivers exactly-once processing cluster-wide. Together with the outbox, the result is effectively-once semantics.

  10. Part 10 — Saga Orchestration vs Choreography on Hazelcast — Part 4’s saga was pure choreography: services reacting to each other’s events with nobody in charge. Part 10 adds the other pattern — an orchestrated saga that drives each step over synchronous HTTP, with per-step timeouts, retries, and reverse-order compensation. It covers when to reach for each, and how both run side by side in one system, told apart by a single sagaType field.

  11. Part 11 — Hazelcast Write-Behind MapStore: Durable Event Sourcing — Everything in the framework lived in memory, which meant a cluster restart erased the event log, the views, and the saga state. Part 11 adds durable persistence through Hazelcast’s write-behind MapStore: IMap.put() still returns immediately, PostgreSQL is written seconds later in batches, and LRU eviction with on-demand MapLoader reloads keeps memory bounded — all without changing a line of service business logic.

  12. Part 12 — Event Sourcing Observability: Prometheus, Grafana, Jaeger — A single API call now fans out across an event store write, a view update, a publication, and a four-service saga — so “HTTP latency went up” tells you nothing about where the time went. Part 12 instruments the whole thing: roughly 70 Micrometer metrics with per-stage pipeline timings and saga lifecycle counters, Prometheus scraping every 15 seconds, five auto-provisioned Grafana dashboards, six alerts, and Jaeger traces for the “why” that metrics can’t answer.

  13. Part 13 — Event Sourcing Performance: Profiling Hazelcast at Scale — The framework worked — but did it work under load? Part 13 puts it through serious performance engineering: async-profiler flame graphs that expose a background outbox poller eating a quarter of the CPU, JMH micro-benchmarks showing framework code is under 1% of pipeline latency, an A-B test of Enterprise features that don’t earn their keep at this scale, and a run up to a 5-node AWS EKS cluster where per-service clustering cut saga latency by 95% — more than every code optimization combined. The recurring lesson: measure first, because your intuition about what’s slow is usually wrong.


What’s Next

That wraps the planned arc of the series — thirteen parts, plus a handful of interludes, taking the framework from a first stored event all the way to performance engineering on a production-scale cluster. The scheduled run ends here.

The framework itself isn’t finished, though. As Hazelcast ships new features worth demonstrating — or as the demo picks up capabilities that are worth writing about — I’ll add the occasional new part. There’s no fixed cadence from this point; just new posts when there’s something genuinely worth showing. This index will stay current as they land.


The Code

All of the code referenced in the series lives in github.com/myawnhc/hazelcast-microservices-framework. Clone it, run the Docker Compose stack, and the framework boots locally in a couple of minutes with sample data preloaded.