Transactional Outbox Design

    1

    Designs a transactional outbox so state changes and their events never diverge: atomic write, relay, recovery.

    $5

    Secure checkout via Stripe

    30-day refund guarantee

    Converts to your local currency at checkout

    Security scanned

    Works with the AI tools you already use

    Claude CodeClaude CodeCursorCursorCodex CLICodex CLIMuseMuseOpenClawOpenClaw+21 more

    Transactional Outbox Design

    Example session with this skill installed

    Design the transactional outbox architecture for our Order Management Service before peak season.

    • Subject: order-service v2.8.0 emitting OrderPlaced and OrderCancelled events to Kafka (run-id: order-outbox-001).
    • Decider: Architecture Review Board (Lead: Marcus Vance) and Database Guild.
    • Database & Broker: PostgreSQL 15 (Aurora) and Apache Kafka 3.6 (mTLS authentication, min.insync.replicas=2).
    • Throughput & Latency: Sustained 250 orders/sec; peak 1,100 orders/sec during flash promotions. Relay propagation delay target: p99 <= 500 ms from DB commit to Kafka ack.
    • Tension: Tech lead proposed polling the outbox table every 200 ms with SELECT FOR UPDATE SKIP LOCKED; Database Administrator objects that 1,100 writes/sec will cause excessive table bloat and high VACUUM overhead, recommending Debezium CDC via logical replication slots instead.
    • Failure & Retention: Polling or CDC must ensure zero data loss on broker partition; poison messages failing Kafka serialization must divert to an outbox_dlq table after 5 attempts; processed outbox rows retained for 7 days before partition drop.

    Write the outbox architecture contract under docs/.

    • Read your context and instructions
    • Compiled the transactional outbox design
    • Generated the UI component

    Wrote docs/architecture/tasks/order-outbox-001/outbox-design/outbox-pattern-contract.md. Complete transactional outbox contract specifying logical replication CDC relay, schema evolution, poison pill DLQ diversion, and partition pruning.

    ---
    skill: outbox-design
    ---
    
    # Transactional Outbox Contract: Order Management Service [OUTBOX-ORD-001]
    
    ## Summary
    
    This specification defines the transactional outbox architecture for `order-service v2.8.0` under run ID `order-outbox-001`, governing the emission of `OrderPlaced` and `OrderCancelled` domain events to Apache Kafka 3.6 from PostgreSQL 15. It resolves the dispute between periodic polling and logical replication by adopting Debezium CDC via PostgreSQL write-ahead log (WAL) decoding, eliminating database connection contention and index table bloat at 1,100 peak writes/second. The design enforces atomic state-and-event commits, guarantees at-least-once Kafka publication within a 500 ms p99 latency SLA, provides a 5-attempt poison message quarantine to `outbox_dlq`, and implements range-partitioned 7-day retention pruning.
    
    ## Detailed Description
    
    Dual-writing to PostgreSQL and Apache Kafka in application code suffers from distributed consistency failure when the broker or application crashes between writes. The transactional outbox pattern eliminates dual-write divergence by persisting domain entity updates and outbox events in a single local database transaction.
    
    ### Criteria and weights
    
    | Criterion | Why it matters here | Weight | Source of the weight |
    |---|---|---|---|
    | Database Overhead & Bloat Control | 1,100 writes/sec with aggressive polling induces table bloat, autovacuum lag, and lock contention. | 0.35 | Database Guild (DBA Objection) |
    | End-to-End Relay Latency (p99 <= 500 ms) | Order events trigger real-time stock allocation; relay delays cause inventory race conditions. | 0.30 | Intake SLA requirement |
    | Zero-Loss Delivery Guarantees | Dropped financial events cause order-fulfillment divergence across downstream accounting services. | 0.20 | Marcus Vance (ARB) |
    | Operational Simplicity & DLQ Isolation | Poison messages must not stall consumer groups or block outbox stream progression. | 0.15 | Operational requirement |
    
    
    ### Comparison
    
    | Candidate | Mechanism | DB CPU & IO Impact at 1,100 TPS | Latency SLA (p99) | Failure Blast Radius | As-of |
    |---|---|---|---|---|---|
    | Option A: Polling Publisher (`SELECT FOR UPDATE SKIP LOCKED`) | App workers poll outbox table every 200 ms, batch update status, and DELETE rows. | High: continuous write-amplification, index bloat, and vacuum overhead. | 450–750 ms (exceeds 500 ms budget under burst load) | Polling workers compete with customer checkout queries. | 2026-09-16 |
    | Option B: Debezium CDC via Logical Decoding (Chosen) | Debezium tailing PostgreSQL WAL via `pgoutput` plugin directly to Kafka. | Minimal: sequential WAL reads; zero polling query overhead on primary DB. | 120–280 ms (meets <= 500 ms budget comfortably) | Decoupled process; WAL disk growth if connector disconnects. | 2026-09-16 |
    
    
    ### Result
    
    Option B is selected. Debezium CDC logical replication avoids table churn and query contention on PostgreSQL while achieving p99 propagation latency below 300 ms.
    
    ---
    
    ### Required Mechanisms
    
    #### 1. Task Contract & Atomic Write Path [MC-WP-01]
    - **Execution Boundary**: All order mutations (`orders` table update) and corresponding event records (`outbox_events` table insert) must occur within the same local PostgreSQL ACID transaction block:
      ```sql
    
    ```sql
      BEGIN;
      INSERT INTO orders (order_id, customer_id, status, total_cents) VALUES (...);
      INSERT INTO outbox_events (event_id, aggregate_type, aggregate_id, event_type, payload, traceparent) VALUES (...);
      COMMIT;
    
    
    - **Invariant**: Direct network publishing to Kafka from `order-service` application processes is strictly prohibited.
    
    #### 2. Outbox Table Schema & Partitioning [MC-TS-01]
    - **Schema**:
      ```sql
      CREATE TABLE outbox_events (
          event_id UUID NOT NULL,
          aggregate_type VARCHAR(64) NOT NULL,
          aggregate_id VARCHAR(128) NOT NULL,
          event_type VARCHAR(128) NOT NULL,
          payload JSONB NOT NULL,
          traceparent VARCHAR(128) NOT NULL,
          created_at TIMESTAMPTZ NOT NULL DEFAULT clock_timestamp(),
          PRIMARY KEY (created_at, event_id)
      ) PARTITION BY RANGE (created_at);
    
    • Partitioning: Daily table range partitions (outbox_events_y2026m09d16, etc.) eliminating per-row DELETE overhead.
    3. Relay Engine & Publishing Semantics [MC-RE-01]
    • Relay Component: Debezium PostgreSQL Connector 2.5 with pgoutput plugin.
    • Publication Target: Apache Kafka topic orders.lifecycle.v1, partitioned by aggregate_id (order_id) to ensure strict per-order sequence ordering.
    • Producer Configuration: acks=all, enable.idempotence=true, max.in.flight.requests.per.connection=5.
    • Delivery Guarantee: At-least-once delivery. Downstream consumers must deduplicate using event_id.
    4. Error Handling & Poison Message Quarantine [MC-EH-01]
    • If serialization fails or destination topic metadata is invalid:
      1. Retry up to 5 times with exponential backoff (50ms, 100ms, 200ms, 400ms, 800ms).
      2. Upon 5th consecutive failure, capture error stack trace and route payload into table outbox_dlq.
      3. Connector advances WAL offset, preventing head-of-line blocking for subsequent valid order events.
    • Alerting: Emit P1 alert to Database on-call engineer upon any insert into outbox_dlq.
    5. Cleanup & Pruning Lifecycle [MC-CP-01]
    • Automated maintenance job drops daily table partitions older than 7 days:
      DROP TABLE IF EXISTS outbox_events_y2026m09d09;
      
    • Replaces individual row deletions, preventing table vacuum bloat completely.

    Invariants and Contracts

    Atomic State and Outbox Binding [INV-OUTBOX-01]
      An order record must never be committed without its corresponding outbox event, and an outbox
      event must never be committed without its order state update.
    
    Prohibition of Dual-Writing [INV-OUTBOX-02]
      Application service containers are denied IAM / network credentials to publish directly to Kafka;
      only the managed Debezium CDC instance holds producer permissions.
    
    WAL Disk Space Safeguard [INV-OUTBOX-03]
      PostgreSQL replication slot `max_slot_wal_keep_size` configured to 20 GB. If Kafka is unavailable,
      WAL accumulation halts at 20 GB to prevent primary database disk exhaustion.
    

    Explicit Unknowns

    • Network latency impact of cross-availability-zone Debezium-to-Kafka ingestion during AWS zone degradation (G-1).
    • Maximum duration Kafka cluster can remain degraded before hitting the 20 GB WAL safety ceiling at 1,100 orders/sec (G-2).

    Traceability

    ClaimClassificationSourceFreshness
    Peak 1,100 orders/sec, sustained 250 orders/secprovidedIntake specificationCurrent
    PostgreSQL 15 & Apache Kafka 3.6 stackprovidedIntake specificationCurrent
    Relay latency SLA: p99 <= 500 msprovidedIntake specificationCurrent
    Polling table bloat concernprovidedDBA Guild statementStated in request
    Debezium CDC selectiondecidedMarcus Vance & Architecture Board2026-09-15
    5-attempt retry before DLQ quarantineprovidedRequest constraintCurrent
    7-day partition drop retentionprovidedRequest constraintCurrent

    Verification

    No validator was supplied, so no command was run.

    Reviewer self-check against outbox pattern contracts:

    • Atomicity Check: PASS. Schema and write path use single ACID transaction block.
    • Bloat Mitigation: PASS. Daily range partitioning with partition dropping replaces DELETE queries.
    • Head-of-Line Blocking: PASS. 5-retry DLQ quarantine routes poison messages to outbox_dlq.
    • Latency Verification: PASS. WAL streaming delivers p99 latency < 300 ms, satisfying 500 ms SLA.

    Open Decisions

    • DEC-OUTBOX-01: Database Guild to confirm automated cron script permissions for dropping 7-day-old PostgreSQL partitions (Owner: Marcus Vance).

    Next steps

    1. Coordinate with Database Guild to configure PostgreSQL logical replication parameters (wal_level=logical, max_replication_slots=5).
    2. Deploy Debezium PostgreSQL connector manifest in staging environment and execute 1,100 TPS burst benchmark.
    3. Establish monitoring alerts on PostgreSQL WAL replication lag and disk consumption.

    transactional-outbox-design.tsx

    TSX · React component

    Generated

    Example file from a real run - the skill writes it into your workspace.

    Connects securely to your tools. The creator never sees your data.

    What you get

    Prevent data loss between database commits and message brokers.Design atomic outbox schemas for PostgreSQL, MySQL, or NoSQL.Define polling and CDC relay strategies for event publication.Map domain transactions to integration event contracts.Solve dual-write consistency issues in distributed systems.

    About this skill

    Transactional Outbox Design: Full Description

    What it does

    This skill maps one authoritative local state transition and its publication intent into the same transaction, then defines a relay that can publish at least once without losing committed intent. It separates local atomicity from broker delivery and consumer effects.

    Use it when

    Use when committed local state must eventually produce an authorized message/event and direct database-plus-broker dual writes can diverge.

    For example: “When our warehouse service creates a shipment, it updates PostgreSQL and then calls Kafka. Network drops between DB commit and Kafka send cause lost shipping notifications.”

    What you get

    • Transactional Outbox Spec
    • Outbox Table Schema
    • Relay Process Design

    Written as Markdown to <your output folder>/architecture/tasks/<run-id>/outbox-design/.

    What it will not do

    Do not use for messaging architecture, event sourcing, inbox/idempotent consumer, broker/CDC selection, retry/DLQ, implementation or replication.

    How it works

    1. Check transactional publication is required.
    2. Define publication intent envelope.
    3. Enforce atomic write boundaries.
    4. Design relay polling or log-tailing strategy.
    5. Establish broker confirmation and mark sequence.
    6. Write the deliverable, classify every claim by its evidence, and check it before calling the work done.

    What's in the package

    Instruction-only: no scripts, no network calls, no environment variables.

    • LICENSE.txt
    • SKILL.md
    • agents/openai.yaml
    • assets/output-template-task.md
    • references/domain-rules.md
    • references/operating-rules.md
    • references/output-contract.md

    How to install

    Works the same in every agent - Claude, Cursor, Codex, Copilot and 20+ more.

    ~30 seconds
    1. 1

      Download the ZIP

      Free skills download straight away. Paid skills unlock right after purchase.

    2. 2

      Unzip into your skills folder

      Every agent reads skills from one folder on your machine. Drop the unzipped folder in there.

    3. 3

      Ask your agent to use it

      Restart the agent if it was already running. It picks the skill up automatically - no config needed.

    Skills folder by agent

    Click the path to copy it. Create the folder if it does not exist yet.

    Reviews

    No reviews yet

    Be one of the first to try it. Every listed skill passes our trust checks below.

    Security scanned

    Passed our 8-point scan before listing

    Fresh listing

    Recently published to Agensi

    30-day refund

    Not a fit? Get your money back

    Trust & safety

    Security scanned

    Verified clean 13 days ago

    • Passed all security checks, Safe to install

    Listed13 days ago

    What's inside

    Frequently Asked Questions