<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/33-60-days-system-design-questions-emnxrcvuc" -->

---
title: 33/60 Days System Design Questions | daily.dev
description: A practical system design scenario where an order service using Postgres with mutable state loses the ability to reconstruct order history, leading to a...
canonical: https://daily.dev/posts/33-60-days-system-design-questions-emnxrcvuc
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: 33/60 Days System Design Questions | daily.dev
og:description: A practical system design scenario where an order service using Postgres with mutable state loses the ability to reconstruct order history, leading to a...
og:url: https://daily.dev/posts/33-60-days-system-design-questions-emnxrcvuc
og:image: https://api.daily.dev/og/posts/EMnXrcVUC.png
og:image:alt: 33/60 Days System Design Questions
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# 33/60 Days System Design Questions

**[Joud Awad](https://daily.dev/sources/iac4jsbu0lv8wbsc85fsh)** · [@joudawad](https://daily.dev/joudawad) · 2 min read · 193 upvotes · 43 comments

## Summary

A practical system design scenario where an order service using Postgres with mutable state loses the ability to reconstruct order history, leading to a billing dispute. The post presents four architectural approaches to solve the problem: Event Sourcing (append-only log as source of truth), Change Data Capture via Kafka, trigger-based audit log tables, and dual-write patterns. Readers are prompted to choose the best approach and explain their reasoning.

## Content

Your order service takes 200 writes/sec at peak.

You audit 6 months of data. Something's off — two orders show the same ID, different totals.

You have the current state. You don't have how it got there.

Your DB is a graveyard of overwritten rows.

Here's the system:

• OrderService → Postgres (current state only)

• Events: placed, updated, cancelled, refunded

• Every UPDATE overwrites the previous row

• No audit log. No event history. No replay.

A billing dispute just landed. You need to reconstruct exactly what happened to Order #8471. You can't.

Instead of storing the current state, you store the sequence of events that produced it.

What's your approach when redesigning this service?

A) Event Sourcing — append-only event log as the source of truth, current state derived from replaying events.

B) Change Data Capture (CDC) — keep Postgres as-is, but stream all row changes to Kafka for an audit trail.

C) Add an audit_log table — trigger-based shadow writes on every INSERT/UPDATE/DELETE.

D) Dual-write — write to both the current-state table and a separate events table on every operation.

One of these gives you full replay, projection flexibility, and a real source of truth. The others are patches.

Pick one — A, B, C, or D — and tell me why. I'll drop the full breakdown in the comments.

If your team is arguing about audit trails or event-driven redesigns, tag someone who needs to see this.

Drop your answer 👇

#30DaysOfSystemDesign #SystemDesign #EventSourcing #SoftwareArchitecture

## Community discussion

Top comments from developers on daily.dev.

**@joudawad** · 18 upvotes

> **Answer: A — Event Sourcing ✅**
>
>
> Here's why, and why the other three look reasonable but miss the point:
>
>
> **Why A wins (Event Sourcing):**
>
> Event Sourcing flips the model entirely. Instead of storing the _latest state_ and losing how you got there, you store every event that ever happened. The current state is a projection — computed by replaying events from the beginning (or from a snapshot).
>
>
> For Order #8471: you don't query a row. You replay OrderPlaced, OrderUpdated, PaymentCaptured, RefundInitiated. Every mutation is preserved, timestamped, immutable. You can reconstruct state at any...

**@joudawad** · 4 upvotes

> **Why C is wrong (audit_log table):**
>
> Trigger-based audit logs are the classic band-aid. The problem: you're treating the row as source of truth and logging changes as a side effect.
>
>
> Side effects break. Triggers get disabled during migrations. Bulk imports skip them. Schema changes orphan the trigger. Six months later, the audit_log has gaps — exactly when you need it most. It's a shadow, not a foundation.

**@joudawad** · 4 upvotes

> Also, it would mean a lot to me if you could support my content and stay in touch 🙏
>
> - YouTube: [https://www.youtube.com/@system-design-lab](https://www.youtube.com/@system-design-lab)
> - LinkedIn: [https://www.linkedin.com/in/joud-awad/](https://www.linkedin.com/in/joud-awad/)
> - Medium Blog: [https://joudwawad.medium.com/](https://joudwawad.medium.com/)
> - Substack: [https://joudawad.substack.com/](https://joudawad.substack.com/)

**@joudawad** · 4 upvotes

> **Why B is the trap (CDC):**
>
> CDC is powerful and often underrated. Tools like Debezium + Kafka let you stream every Postgres row change downstream without touching your app. It looks like Event Sourcing from the outside — you have a sequence of changes.
>
>
> But here's the trap: CDC captures _state deltas_, not _business events_. You get total changed from 89.99 to 79.99 — not DiscountApplied by coupon SAVE10. The semantic meaning is lost. You can reconstruct what changed, not _why_ it changed. That distinction kills you during disputes and compliance audits.
>
>
> CDC is a great complement to...

**@joudawad** · 3 upvotes

> **The architecture lesson:**
>
>
> Event Sourcing isn't about logging. It's about choosing what your _source of truth_ actually is.
>
>
> The cost: more complex reads (you need projections/read models), snapshot strategy for performance, mindset shift for your team. Not free.
>
>
> The payoff: perfect audit trail, time-travel queries, new projections without schema migrations, and events as a first-class integration primitive.
>
>
> When you have regulatory requirements, financial data, or anything where "why did this change" matters — Event Sourcing is the only model that doesn't apologize later.

---

Tags: [#career](https://daily.dev/tags/career), [#architecture](https://daily.dev/tags/architecture), [#postgresql](https://daily.dev/tags/postgresql), [#change-data-capture](https://daily.dev/tags/change-data-capture)

[View this post on daily.dev](https://daily.dev/posts/33-60-days-system-design-questions-emnxrcvuc)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"DiscussionForumPosting","mainEntityOfPage":"https://daily.dev/posts/33-60-days-system-design-questions-emnxrcvuc","headline":"33/60 Days System Design Questions","text":"A practical system design scenario where an order service using Postgres with mutable state loses the ability to reconstruct order history, leading to a billing dispute. The post presents four architectural approaches to solve the problem: Event Sourcing (append-only log as source of truth), Change Data Capture via Kafka, trigger-based audit log tables, and dual-write patterns. Readers are prompted to choose the best approach and explain their reasoning.","url":"https://daily.dev/posts/33-60-days-system-design-questions-emnxrcvuc","datePublished":"2026-06-08T15:51:55.131Z","dateModified":"2026-06-09T15:57:03.934Z","author":{"@type":"Person","name":"Joud Awad","url":"https://daily.dev/joudawad","image":"https://media.daily.dev/image/upload/s--dOB9RaXY--/f_auto/v1773320801/avatars/avatar_iaC4JsBU0lV8wBsc85fSh?_a=BAMAMiiu0","description":"Principal Solution Architecture ","worksFor":{"@type":"Organization","name":"Metalab","logo":"https://www.google.com/s2/favicons?domain=metalab.com&sz=128"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"EndorseAction"},"userInteractionCount":81890}},"image":"https://media.daily.dev/image/upload/s--g15AMGc6--/f_auto/v1780933918/posts/EMnXrcVUC?_a=BAMAMiWQ0","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":193},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":43}],"comment":[{"@type":"Comment","text":"Answer: A — Event Sourcing ✅\nHere’s why, and why the other three look reasonable but miss the point:\nWhy A wins (Event Sourcing):\nEvent Sourcing flips the model entirely. Instead of storing the latest state and losing how you got there, you store every event that ever happened. The current state is a projection — computed by replaying events from the beginning (or from a snapshot).\nFor Order #8471: you don’t query a row. You replay OrderPlaced, OrderUpdated, PaymentCaptured, RefundInitiated. Every mutation is preserved, timestamped, immutable. You can reconstruct state at any point in time. You can build new projections (e.g., “total revenue by SKU last 90 days”) without changing the core model — just replay and project differently.\nThis is what Axon, EventStoreDB, and the event-sourced layers in most serious fintech/e-commerce systems do. It’s not a log — it’s the primary data model.","datePublished":"2026-06-08T15:52:17.918Z","url":"https://daily.dev/posts/EMnXrcVUC#c-jIHpTSP9H","author":{"@type":"Person","name":"Joud Awad","url":"https://daily.dev/joudawad","image":"https://media.daily.dev/image/upload/s--dOB9RaXY--/f_auto/v1773320801/avatars/avatar_iaC4JsBU0lV8wBsc85fSh?_a=BAMAMiiu0"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":18}},{"@type":"Comment","text":"Why C is wrong (audit_log table):\nTrigger-based audit logs are the classic band-aid. The problem: you’re treating the row as source of truth and logging changes as a side effect.\nSide effects break. Triggers get disabled during migrations. Bulk imports skip them. Schema changes orphan the trigger. Six months later, the audit_log has gaps — exactly when you need it most. It’s a shadow, not a foundation.","datePublished":"2026-06-08T15:52:26.528Z","url":"https://daily.dev/posts/EMnXrcVUC#c-RaP1ewdUa","author":{"@type":"Person","name":"Joud Awad","url":"https://daily.dev/joudawad","image":"https://media.daily.dev/image/upload/s--dOB9RaXY--/f_auto/v1773320801/avatars/avatar_iaC4JsBU0lV8wBsc85fSh?_a=BAMAMiiu0"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":4}},{"@type":"Comment","text":"Also, it would mean a lot to me if you could support my content and stay in touch 🙏\n\nYouTube: https://www.youtube.com/@system-design-lab\nLinkedIn: https://www.linkedin.com/in/joud-awad/\nMedium Blog: https://joudwawad.medium.com/\nSubstack: https://joudawad.substack.com/","datePublished":"2026-06-08T15:52:39.952Z","url":"https://daily.dev/posts/EMnXrcVUC#c-7tE0rlhgA","author":{"@type":"Person","name":"Joud Awad","url":"https://daily.dev/joudawad","image":"https://media.daily.dev/image/upload/s--dOB9RaXY--/f_auto/v1773320801/avatars/avatar_iaC4JsBU0lV8wBsc85fSh?_a=BAMAMiiu0"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":4}},{"@type":"Comment","text":"Why B is the trap (CDC):\nCDC is powerful and often underrated. Tools like Debezium + Kafka let you stream every Postgres row change downstream without touching your app. It looks like Event Sourcing from the outside — you have a sequence of changes.\nBut here’s the trap: CDC captures state deltas, not business events. You get total changed from 89.99 to 79.99 — not DiscountApplied by coupon SAVE10. The semantic meaning is lost. You can reconstruct what changed, not why it changed. That distinction kills you during disputes and compliance audits.\nCDC is a great complement to Event Sourcing for propagation. It’s not a substitute for it.","datePublished":"2026-06-08T15:52:20.792Z","url":"https://daily.dev/posts/EMnXrcVUC#c-sQfoSsUUh","author":{"@type":"Person","name":"Joud Awad","url":"https://daily.dev/joudawad","image":"https://media.daily.dev/image/upload/s--dOB9RaXY--/f_auto/v1773320801/avatars/avatar_iaC4JsBU0lV8wBsc85fSh?_a=BAMAMiiu0"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":4}},{"@type":"Comment","text":"The architecture lesson:\nEvent Sourcing isn’t about logging. It’s about choosing what your source of truth actually is.\nThe cost: more complex reads (you need projections/read models), snapshot strategy for performance, mindset shift for your team. Not free.\nThe payoff: perfect audit trail, time-travel queries, new projections without schema migrations, and events as a first-class integration primitive.\nWhen you have regulatory requirements, financial data, or anything where “why did this change” matters — Event Sourcing is the only model that doesn’t apologize later.","datePublished":"2026-06-08T15:52:59.586Z","url":"https://daily.dev/posts/EMnXrcVUC#c-8vcemomjc","author":{"@type":"Person","name":"Joud Awad","url":"https://daily.dev/joudawad","image":"https://media.daily.dev/image/upload/s--dOB9RaXY--/f_auto/v1773320801/avatars/avatar_iaC4JsBU0lV8wBsc85fSh?_a=BAMAMiiu0"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":3}}],"isPartOf":{"@type":"WebPage","url":"https://daily.dev/sources/iac4jsbu0lv8wbsc85fsh","name":"Joud Awad"}}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Joud Awad","item":"https://daily.dev/sources/iac4jsbu0lv8wbsc85fsh"},{"@type":"ListItem","position":3,"name":"33/60 Days System Design Questions"}]}
```

