<div class="cs-rating pd-rating" id="pd_rating_holder_1819065_post_3105"></div>
<p class="wp-block-paragraph">I started the year using Gemini Pro to take our integration patterns and covert them into “playing card” style pattern library so that we can print and play! The content is mine, I used AI to generate the images with still a few issues with image text – oh well, maybe something to refine later in 2026 or next year. In this post we explore writes where we must deal with duplicates, retries, and partial failures as key design and architectural challenges. Using these we look at pros and cons to make writes safe under failure and concurrency.</p>
<h2 class="wp-block-heading">Included patterns</h2>
<ul><li><a href="#cp-1">CP-1 — Real-time Consistent Synchronous Write to Master</a></li><li><a href="#cp-2">CP-2 — Real-time Consistency Asynchronous Write to Master</a></li><li><a href="#cp-3">CP-3 — Buffered Write (Delayed Consistency)</a></li><li><a href="#cp-4">CP-4 — Shopping-cart / Draft Copy</a></li><li><a href="#cp-5">CP-5 — High-Available Shallow Copy + Later Sync</a></li><li><a href="#cp-6">CP-6 — Dual-copy Sync</a></li></ul>
<h2 class="wp-block-heading" id="cp-1">CP-1: Real-time Consistent Synchronous Write to Master</h2>
<figure class="wp-block-image size-large"><img src="https://alok-mishra.com/wp-content/uploads/2026/01/cp-1_real-time_consistent_synchronous_write_to_master.png?w=1024" alt="" class="wp-image-3153" /></figure>
<p class="wp-block-paragraph">Synchronous create/update; API returns only after the master transaction commits.</p>
<h3 class="wp-block-heading">When to use</h3>
<ul><li>Client needs immediate confirmation and canonical ID.</li><li>Single-entity or parent-child write fits in one transaction.</li><li>Client can handle validation errors inline.</li></ul>
<h3 class="wp-block-heading">Pros</h3>
<ul><li>Immediate correctness.</li><li>Simple for clients.</li><li>Good for transactional UX flows.</li></ul>
<h3 class="wp-block-heading">Cons</h3>
<ul><li>Higher latency.</li><li>Tight runtime coupling; failures cascade.</li><li>Can throttle master under burst writes.</li></ul>
<h3 class="wp-block-heading">PlantUML</h3>
<pre class="wp-block-code"><code>@startuml
title Real-time Consistent Synchronous Write to Master
actor "Client" as Client
participant "API/BFF" as API_BFF
participant "Master System" as Master_System
Client -> API_BFF: POST/PUT /resource (payload)
API_BFF -> Master_System: Validate + write (transaction)
Master_System -> API_BFF: 201/200 + canonicalId
API_BFF -> Client: 201/200 + canonicalId
@enduml</code></pre>
<h2 class="wp-block-heading" id="cp-2">CP-2: Real-time Consistency Asynchronous Write to Master</h2>
<figure class="wp-block-image size-large"><img src="https://alok-mishra.com/wp-content/uploads/2026/01/cp-2_real-time_consistency_asynchronous_write_to_master.png?w=1024" alt="" class="wp-image-3152" /></figure>
<p class="wp-block-paragraph">API accepts command and acknowledges before the master is consistent; backend completes later and may emit status events.</p>
<h3 class="wp-block-heading">When to use</h3>
<ul><li>Master write is workflow-driven or long-running.</li><li>You need fast acknowledgement to the client.</li><li>Client can handle eventual completion and status tracking.</li></ul>
<h3 class="wp-block-heading">Pros</h3>
<ul><li>Decouples client from master latency.</li><li>Better availability under load.</li><li>Supports long-running workflows.</li></ul>
<h3 class="wp-block-heading">Cons</h3>
<ul><li>Client must manage pending state.</li><li>Requires status model (submissionId).</li><li>Duplicates/retries need idempotency.</li></ul>
<h3 class="wp-block-heading">PlantUML</h3>
<pre class="wp-block-code"><code>@startuml
title Real-time Consistency Asynchronous Write to Master
actor "Client" as Client
participant "API/BFF" as API_BFF
participant "Command Queue/Stream" as Command_Queue_Stream
participant "Worker" as Worker
participant "Master System" as Master_System
Client -> API_BFF: POST/PUT command
API_BFF -> Command_Queue_Stream: Enqueue command
API_BFF -> Client: 202 Accepted (submissionId)
Worker -> Command_Queue_Stream: Consume command
Worker -> Master_System: Apply change
Master_System -> Worker: Success/Failure
@enduml</code></pre>
<h2 class="wp-block-heading" id="cp-3">CP-3: Buffered Write (Delayed Consistency)</h2>
<figure class="wp-block-image size-large"><img src="https://alok-mishra.com/wp-content/uploads/2026/01/cp-3_buffered_write_delayed_consistency.png?w=1024" alt="" class="wp-image-3151" /></figure>
<p class="wp-block-paragraph">High-volume commands are buffered in a queue/stream to protect the master; processed asynchronously in controlled batches.</p>
<h3 class="wp-block-heading">When to use</h3>
<ul><li>High-volume inbound writes (bulk uploads).</li><li>Client does not need immediate canonical ID.</li><li>Master must be protected from spikes.</li></ul>
<h3 class="wp-block-heading">Pros</h3>
<ul><li>Smooths bursts; protects master.</li><li>Enables back-pressure and rate limiting.</li><li>Improves resilience.</li></ul>
<h3 class="wp-block-heading">Cons</h3>
<ul><li>Eventual consistency.</li><li>Operational complexity (queues, DLQ).</li><li>Need strong idempotency + replay controls.</li></ul>
<h3 class="wp-block-heading">PlantUML</h3>
<pre class="wp-block-code"><code>@startuml
title Buffered Write (Delayed Consistency)
actor "Client" as Client
participant "Ingress API" as Ingress_API
participant "Buffer (Kafka/Queue)" as Buffer__Kafka_Queue_
participant "Bulk Processor" as Bulk_Processor
participant "Master System" as Master_System
Client -> Ingress_API: Upload/command batch
Ingress_API -> Buffer__Kafka_Queue_: Append write log
Ingress_API -> Client: 202 Accepted (jobId)
Bulk_Processor -> Buffer__Kafka_Queue_: Consume in batches
Bulk_Processor -> Master_System: Apply changes (rate-limited)
Master_System -> Bulk_Processor: Ack/Errors
@enduml</code></pre>
<h2 class="wp-block-heading" id="cp-4">CP-4: Shopping-cart / Draft Copy</h2>
<figure class="wp-block-image size-large"><img src="https://alok-mishra.com/wp-content/uploads/2026/01/cp-4_shopping-cart_-_draft_copy.png?w=1024" alt="" class="wp-image-3150" /></figure>
<p class="wp-block-paragraph">Draft state is stored near the consumer (BFF/local DB) and only the final submitted record is sent to the master.</p>
<h3 class="wp-block-heading">When to use</h3>
<ul><li>Users iteratively build a large request (forms, applications).</li><li>Master only accepts full records, not partial updates.</li><li>You want resilience while users edit over time.</li></ul>
<h3 class="wp-block-heading">Pros</h3>
<ul><li>Great UX (save/resume).</li><li>Reduces partial writes to master.</li><li>Works well with validation and review steps.</li></ul>
<h3 class="wp-block-heading">Cons</h3>
<ul><li>Dual state to reconcile.</li><li>Draft retention and privacy concerns.</li><li>Submit step needs strong validation/versioning.</li></ul>
<h3 class="wp-block-heading">PlantUML</h3>
<pre class="wp-block-code"><code>@startuml
title Shopping-cart / Draft Copy
actor "Client" as Client
participant "BFF/Draft Service" as BFF_Draft_Service
participant "Draft Store" as Draft_Store
participant "Master System" as Master_System
Client -> BFF_Draft_Service: Save draft changes
BFF_Draft_Service -> Draft_Store: Upsert draft
Client -> BFF_Draft_Service: Submit draft
BFF_Draft_Service -> Master_System: Create/Update full record
Master_System -> BFF_Draft_Service: CanonicalId + status
BFF_Draft_Service -> Client: Submission result
@enduml</code></pre>
<h2 class="wp-block-heading" id="cp-5">CP-5: High-Available Shallow Copy + Later Sync</h2>
<figure class="wp-block-image size-large"><img src="https://alok-mishra.com/wp-content/uploads/2026/01/cp-5_high-available_shallow_copy__later_sync.png?w=1024" alt="" class="wp-image-3149" /></figure>
<p class="wp-block-paragraph">Write first to a highly available local store (shallow copy), return quickly, then synchronise to master later (small sets or batch).</p>
<h3 class="wp-block-heading">When to use</h3>
<ul><li>Front-end requires high availability and low latency writes.</li><li>Master is slow/unavailable intermittently.</li><li>Shallow copy is sufficient for immediate downstream usage.</li></ul>
<h3 class="wp-block-heading">Pros</h3>
<ul><li>High availability at the edge.</li><li>Continues operating during master outages.</li><li>Supports offline/poor connectivity.</li></ul>
<h3 class="wp-block-heading">Cons</h3>
<ul><li>Conflict resolution required.</li><li>Sync pipeline and reconciliation needed.</li><li>Risk of diverging truths if governance is weak.</li></ul>
<h3 class="wp-block-heading">PlantUML</h3>
<pre class="wp-block-code"><code>@startuml
title High-Available Shallow Copy + Later Sync
actor "Client" as Client
participant "Edge API" as Edge_API
participant "HA Shallow Store" as HA_Shallow_Store
participant "Sync Worker" as Sync_Worker
participant "Master System" as Master_System
Client -> Edge_API: POST/PUT (payload)
Edge_API -> HA_Shallow_Store: Write shallow copy
Edge_API -> Client: 202/201 (tempId/ack)
Sync_Worker -> HA_Shallow_Store: Read pending changes
Sync_Worker -> Master_System: Upsert canonical record
Master_System -> Sync_Worker: CanonicalId/Status
@enduml</code></pre>
<h2 class="wp-block-heading" id="cp-6">CP-6: Dual-copy Sync</h2>
<figure class="wp-block-image size-large"><img src="https://alok-mishra.com/wp-content/uploads/2026/01/cp-6_dual-copy_sync.png?w=1024" alt="" class="wp-image-3148" /></figure>
<p class="wp-block-paragraph">Maintain a shallow or partial copy in a highly available system, then synchronise to master in batches or small sets.</p>
<h3 class="wp-block-heading">When to use</h3>
<ul><li>Immediate availability and responsiveness is required.</li><li>Later synchronisation is acceptable and governed.</li></ul>
<h3 class="wp-block-heading">Pros</h3>
<ul><li>Same as shallow copy: availability, resilience.</li><li>Allows local optimisation for UX and caching.</li></ul>
<h3 class="wp-block-heading">Cons</h3>
<ul><li>Same as shallow copy: conflicts and reconciliation.</li><li>More complex testing across two stores.</li></ul>
<h3 class="wp-block-heading">PlantUML</h3>
<pre class="wp-block-code"><code>@startuml
title Dual-copy Sync
actor "Client" as Client
participant "Local Service" as Local_Service
participant "Local Store" as Local_Store
participant "Batch Sync" as Batch_Sync
participant "Master System" as Master_System
Client -> Local_Service: Write request
Local_Service -> Local_Store: Commit locally
Local_Service -> Client: Ack (local)
Batch_Sync -> Local_Store: Extract changes
Batch_Sync -> Master_System: Sync batch
Master_System -> Batch_Sync: Ack/Errors
@enduml</code></pre>
<h2 class="wp-block-heading">Summary</h2>
<p class="wp-block-paragraph">We explored write patterns in this post, see related posts for reads, data patterns and AI patterns. Now before we implement writes we must remember to</p>
<ul class="wp-block-list">
<li>Define the contract first (schema, idempotency key, ordering expectations)</li>
<li>Make retries safe (idempotent handlers, dedupe, at-least-once assumptions)</li>
<li>Prefer explicit staleness windows over implicit “eventually consistent” windows for obvious reasons</li>
<li>Instrument job state and failure modes (metrics + searchable logs) because operability is always a key software quality</li>
</ul>
<p class="wp-block-paragraph">Let me hear from you:</p>
<p class="wp-block-paragraph">What is your favourite pattern? Have you composed simple integration patterns in a more complex end to end solution pattern? What were/are your key challenges?</p>
I started the year using Gemini Pro to take our integration patterns and covert them into “playing card” style pattern library so that we can print and play! The content is mine, I used AI to generate the images with still a few issues with image text – oh well, maybe something to refine later in 2026 or next year. In this post we explore writes where we must deal with duplicates, retries, and partial failures as key design and architectural challenges. Using these we look at pros and cons to make writes safe under failure and concurrency.
CP-1: Real-time Consistent Synchronous Write to Master
Synchronous create/update; API returns only after the master transaction commits.
When to use
Client needs immediate confirmation and canonical ID.
Single-entity or parent-child write fits in one transaction.
Client can handle validation errors inline.
Pros
Immediate correctness.
Simple for clients.
Good for transactional UX flows.
Cons
Higher latency.
Tight runtime coupling; failures cascade.
Can throttle master under burst writes.
PlantUML
@startuml
title Real-time Consistent Synchronous Write to Master
actor "Client" as Client
participant "API/BFF" as API_BFF
participant "Master System" as Master_System
Client -> API_BFF: POST/PUT /resource (payload)
API_BFF -> Master_System: Validate + write (transaction)
Master_System -> API_BFF: 201/200 + canonicalId
API_BFF -> Client: 201/200 + canonicalId
@enduml
CP-2: Real-time Consistency Asynchronous Write to Master
API accepts command and acknowledges before the master is consistent; backend completes later and may emit status events.
When to use
Master write is workflow-driven or long-running.
You need fast acknowledgement to the client.
Client can handle eventual completion and status tracking.
Pros
Decouples client from master latency.
Better availability under load.
Supports long-running workflows.
Cons
Client must manage pending state.
Requires status model (submissionId).
Duplicates/retries need idempotency.
PlantUML
@startuml
title Real-time Consistency Asynchronous Write to Master
actor "Client" as Client
participant "API/BFF" as API_BFF
participant "Command Queue/Stream" as Command_Queue_Stream
participant "Worker" as Worker
participant "Master System" as Master_System
Client -> API_BFF: POST/PUT command
API_BFF -> Command_Queue_Stream: Enqueue command
API_BFF -> Client: 202 Accepted (submissionId)
Worker -> Command_Queue_Stream: Consume command
Worker -> Master_System: Apply change
Master_System -> Worker: Success/Failure
@enduml
CP-3: Buffered Write (Delayed Consistency)
High-volume commands are buffered in a queue/stream to protect the master; processed asynchronously in controlled batches.
When to use
High-volume inbound writes (bulk uploads).
Client does not need immediate canonical ID.
Master must be protected from spikes.
Pros
Smooths bursts; protects master.
Enables back-pressure and rate limiting.
Improves resilience.
Cons
Eventual consistency.
Operational complexity (queues, DLQ).
Need strong idempotency + replay controls.
PlantUML
@startuml
title Buffered Write (Delayed Consistency)
actor "Client" as Client
participant "Ingress API" as Ingress_API
participant "Buffer (Kafka/Queue)" as Buffer__Kafka_Queue_
participant "Bulk Processor" as Bulk_Processor
participant "Master System" as Master_System
Client -> Ingress_API: Upload/command batch
Ingress_API -> Buffer__Kafka_Queue_: Append write log
Ingress_API -> Client: 202 Accepted (jobId)
Bulk_Processor -> Buffer__Kafka_Queue_: Consume in batches
Bulk_Processor -> Master_System: Apply changes (rate-limited)
Master_System -> Bulk_Processor: Ack/Errors
@enduml
CP-4: Shopping-cart / Draft Copy
Draft state is stored near the consumer (BFF/local DB) and only the final submitted record is sent to the master.
When to use
Users iteratively build a large request (forms, applications).
Master only accepts full records, not partial updates.
You want resilience while users edit over time.
Pros
Great UX (save/resume).
Reduces partial writes to master.
Works well with validation and review steps.
Cons
Dual state to reconcile.
Draft retention and privacy concerns.
Submit step needs strong validation/versioning.
PlantUML
@startuml
title Shopping-cart / Draft Copy
actor "Client" as Client
participant "BFF/Draft Service" as BFF_Draft_Service
participant "Draft Store" as Draft_Store
participant "Master System" as Master_System
Client -> BFF_Draft_Service: Save draft changes
BFF_Draft_Service -> Draft_Store: Upsert draft
Client -> BFF_Draft_Service: Submit draft
BFF_Draft_Service -> Master_System: Create/Update full record
Master_System -> BFF_Draft_Service: CanonicalId + status
BFF_Draft_Service -> Client: Submission result
@enduml
CP-5: High-Available Shallow Copy + Later Sync
Write first to a highly available local store (shallow copy), return quickly, then synchronise to master later (small sets or batch).
When to use
Front-end requires high availability and low latency writes.
Master is slow/unavailable intermittently.
Shallow copy is sufficient for immediate downstream usage.
Pros
High availability at the edge.
Continues operating during master outages.
Supports offline/poor connectivity.
Cons
Conflict resolution required.
Sync pipeline and reconciliation needed.
Risk of diverging truths if governance is weak.
PlantUML
@startuml
title High-Available Shallow Copy + Later Sync
actor "Client" as Client
participant "Edge API" as Edge_API
participant "HA Shallow Store" as HA_Shallow_Store
participant "Sync Worker" as Sync_Worker
participant "Master System" as Master_System
Client -> Edge_API: POST/PUT (payload)
Edge_API -> HA_Shallow_Store: Write shallow copy
Edge_API -> Client: 202/201 (tempId/ack)
Sync_Worker -> HA_Shallow_Store: Read pending changes
Sync_Worker -> Master_System: Upsert canonical record
Master_System -> Sync_Worker: CanonicalId/Status
@enduml
CP-6: Dual-copy Sync
Maintain a shallow or partial copy in a highly available system, then synchronise to master in batches or small sets.
When to use
Immediate availability and responsiveness is required.
Later synchronisation is acceptable and governed.
Pros
Same as shallow copy: availability, resilience.
Allows local optimisation for UX and caching.
Cons
Same as shallow copy: conflicts and reconciliation.
More complex testing across two stores.
PlantUML
@startuml
title Dual-copy Sync
actor "Client" as Client
participant "Local Service" as Local_Service
participant "Local Store" as Local_Store
participant "Batch Sync" as Batch_Sync
participant "Master System" as Master_System
Client -> Local_Service: Write request
Local_Service -> Local_Store: Commit locally
Local_Service -> Client: Ack (local)
Batch_Sync -> Local_Store: Extract changes
Batch_Sync -> Master_System: Sync batch
Master_System -> Batch_Sync: Ack/Errors
@enduml
Summary
We explored write patterns in this post, see related posts for reads, data patterns and AI patterns. Now before we implement writes we must remember to
Define the contract first (schema, idempotency key, ordering expectations)
Make retries safe (idempotent handlers, dedupe, at-least-once assumptions)
Prefer explicit staleness windows over implicit “eventually consistent” windows for obvious reasons
Instrument job state and failure modes (metrics + searchable logs) because operability is always a key software quality
Let me hear from you:
What is your favourite pattern? Have you composed simple integration patterns in a more complex end to end solution pattern? What were/are your key challenges?
Alok brings experience in engineering and architecting distributed software systems from over 20 years across industry and consulting. His posts focus on Systems Integration, API design, Microservices and Event driven systems, Modern Enterprise Architecture and other related topics
View all posts by alokmishra
Discover more from Alok Mishra
Subscribe now to keep reading and get access to the full archive.