CQRS in Django: a denormalized read model without Event Sourcing

CQRS in Django: a denormalized read model without Event Sourcing

The four previous articles in the series laid the building blocks for a distributed system to stay consistent: Saga to orchestrate workflows, Outbox to publish reliable events, Inbox to consume them without duplicates, Idempotency Keys to protect the API. One question is left: what do you do with events once they are published? The most common answer: you use them to build read views. That is exactly what the CQRS pattern (Command Query Responsibility Segregation) proposes: separate the write model from the read model when both diverge enough that forcing them into a single structure costs more than splitting them. ...

June 5, 2026 · 7 min · Anthony
Inbox pattern: consuming events without replaying them twice

Inbox pattern: consuming events without replaying them twice

The previous article on the Transactional Outbox set a clear guarantee: every event written to the database will eventually be published. That guarantee is intentionally at-least-once. A consumer may receive the same event two times, three times, or more if the network behaves badly. The Outbox pattern never promises uniqueness. The consequence follows immediately: if the consumer applies the effect of the message twice, it bills twice, sends two emails, decreases stock twice. The consistency guaranteed on the producer side collapses on the reader side. ...

June 3, 2026 · 6 min · Anthony
Transactional Outbox: publishing events without losing consistency

Transactional Outbox: publishing events without losing consistency

When a service updates its database and wants to notify the rest of the system by emitting an event to Kafka, RabbitMQ or SQS, the naive code looks like this: write to the database, then publish. If publishing fails after the commit, the event is lost. If publishing succeeds but the commit fails, the event refers to a state that does not exist. Both cases define the dual-write problem. The Transactional Outbox pattern fixes that inconsistency with a simple idea: never publish directly. The event is written to an outbox table within the same SQL transaction as the business change. A separate process reads that table and publishes to the broker. As long as the SQL transaction is atomic, the database and the future event are consistent by construction. ...

June 2, 2026 · 7 min · Anthony
Saga pattern: handling distributed transactions without rollback

Saga pattern: handling distributed transactions without rollback

A business operation that spans several services raises a question SQL has been answering for fifty years inside a single database: what happens when one step succeeds and the next one fails? As long as everything lives in the same database, BEGIN ... ROLLBACK is enough. The moment you call an external service, a third-party API or another database, that safety net disappears. The Saga pattern answers that question. Rather than attempting an impossible ACID transaction, it breaks the operation into local steps, each paired with a compensating transaction that knows how to undo its effect. If step 4 fails, the compensations for steps 1, 2 and 3 are replayed in reverse order. ...

June 1, 2026 · 7 min · Anthony
Anti-corruption layer: isolating your code from external APIs

Anti-corruption layer: isolating your code from external APIs

Consuming an external API looks harmless at first. You run a requests.get, get a dictionary back, and use it directly throughout the code. The problem starts when that same JSON structure ends up scattered across ten files, and the API renames a field or switches price from float to string. Fixing it becomes a treasure hunt. The anti-corruption layer (ACL) addresses this problem. Borrowed from Domain-Driven Design, it acts as a translator between an external system and your business logic. One contact point, one place to update when the API changes. ...

May 27, 2026 · 4 min · Anthony
Why a blog about Python, Django, Architecture and best practices?

Why a blog about Python, Django, Architecture and best practices?

This blog is first and foremost a place to share: discoveries, thoughts, things that have been useful to me and might be useful to others. Python, Django, Architecture and best practices: the heart of this blog The heart of the blog is Python development, and more specifically the frameworks that shape my daily work: Django, FastAPI and Flask. Each has its strengths, its use cases, its pitfalls. We’ll dig into all of them. ...

May 4, 2026 · 2 min · Anthony

Newsletter

Get new articles delivered straight to your inbox.

No spam. Unsubscribe in one click.