Skip to content

Repository files navigation

Microservices · Outbox / Inbox Pattern

Reference implementation of the Outbox / Inbox transactional-messaging pattern in .NET — a standalone study project built to internalize distributed-systems design end-to-end, beyond what tutorials typically cover.

What This Project Demonstrates

The Outbox pattern solves the dual-write problem: a service must atomically persist a state change and publish a domain event, but DB.Save() and MessageBroker.Publish() are not in the same transaction. Without the pattern, a crash between the two leaves the system inconsistent.

The fix:

  1. Inside the database transaction, write the event row to an outbox table alongside the business data.
  2. A background publisher polls the outbox table, dispatches each event to the message broker, and marks it sent.
  3. The receiving service uses an inbox table to deduplicate (idempotency) — events received twice are processed once.

The result: at-least-once delivery with idempotent consumption, all without distributed transactions.

Architecture

  Order.API                                                Stock.Service
  ┌─────────────────────────────┐                          ┌────────────────────────┐
  │  BEGIN TX                   │                          │                        │
  │  INSERT order              │                          │  receives event        │
  │  INSERT into outbox_table  │                          │  check inbox_table     │
  │  COMMIT                    │                          │  (dedup)               │
  │                            │                          │  insert inbox row +    │
  └─────────────────────────────┘                          │  process business     │
              │                                            └────────────────────────┘
              ▼                                                          ▲
  ┌─────────────────────────────┐                                        │
  │ Order.Outbox.Table.         │ ── publish event ─────▶ RabbitMQ ──────┘
  │  Publisher.Service          │
  │ (background polling worker)│
  └─────────────────────────────┘

Tech Stack

Layer Technology
Runtime .NET / ASP.NET Core
Persistence Entity Framework Core + outbox / inbox tables
Background BackgroundService polling publisher
Broker RabbitMQ (MassTransit)
Pattern Outbox + Inbox + idempotent consumer

Project Structure

.
├── Order.API/                              # Writes to DB + outbox in one TX
├── Order.Outbox.Table.Publisher.Service/   # Background publisher (polls outbox)
├── Stock.Service/                          # Consumer with inbox-based dedup
├── Shared/                                 # Event contracts
└── Microservices.Outbox.Inbox.Design.Pattern.sln

Why This Matters in Production

The Outbox pattern is one of the most-used patterns in real distributed systems (Microsoft, Stripe, Uber all use variants). It's a prerequisite for any reliable event-driven architecture where you can't afford to lose or duplicate events.


About

Built by Ali Kalantari — a Backend Developer specialising in regulated fintech systems (.NET, Python, multi-database, event-driven).

This repository is part of my Distributed Systems Reference Series: a set of standalone study projects, each focused on one pattern, that I keep as working references when implementing similar designs in production.

Browse the full series: github.com/Ali-Klnai?tab=repositories&q=Microservices.

About

Outbox/Inbox transactional-messaging pattern in .NET — atomic DB+message publishing using an outbox table + background publisher worker.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages