PrepZone Logo
PrepZone

Why Systems Need Async Messaging

Decouple services, absorb spikes, and survive partial failures — why VaultCommerce moved off synchronous HTTP fan-out.

Why this matters

  • Checkout used to chain inventory, payment, email, and analytics over HTTP — one slow dependency timed out the entire order even after payment succeeded.
  • Brokers absorb Black Friday spikes; producers stay fast while consumers drain the backlog at sustainable rates.
  • Failure isolation means a broken email worker does not roll back a captured payment — each consumer retries independently.
  • Interviewers probe coupling and backpressure before you name Kafka; this article frames the business case.
Synchronous
Order API
Inventory
Payment
EmailSlow = timeout
Asynchronous
Order API
Kafka topic
Inventory consumer
Payment consumer
Email consumer
Synchronous calls block on every downstream service. Async publish returns after the broker accepts the event.

The synchronous trap

VaultCommerce's first checkout flow made four sequential REST calls from a single thread. When the email service p99 hit 800ms during a marketing blast, customers saw spinner timeouts while inventory and payment had already committed. Moving to OrderPlaced events on Kafka let the API return in under 120ms after the order row was durable.

Key points

  • Producer — service that publishes an event after a business action completes (order-service after INSERT)
  • Consumer — independent worker that subscribes and processes events at its own pace
  • Broker — middleware that durably stores and forwards messages between producers and consumers
  • Decoupling — producer does not know consumer count, location, or availability
  • Backpressure — consumers signal overload via growing lag; producers are not forced to slow unless you add flow control

Events as contracts between teams

An event is a versioned fact: vaultcommerce.orders.placed.v1 carries orderId, customerId, line items, and total. Inventory subscribes to reserve stock; payments subscribes to authorize; analytics subscribes without the order API knowing any subscriber exists. New consumers (fraud scoring, loyalty points) attach without redeploying checkout.

When async is the wrong tool

Read-your-writes flows still need sync APIs — a customer checking order status expects immediate consistency from Postgres, not eventual projection lag. VaultCommerce keeps the order confirmation page on a synchronous read while downstream side effects run async.

Java
// VaultCommerce order-service — first event after Postgres commit
Properties props = new Properties();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "kafka-1:9092,kafka-2:9092,kafka-3:9092");
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
props.put(ProducerConfig.ACKS_CONFIG, "all");
props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, "true");

try (KafkaProducer<String, String> producer = new KafkaProducer<>(props)) {
    String payload = objectMapper.writeValueAsString(new OrderPlacedEvent(orderId, customerId, total));
    ProducerRecord<String, String> record =
        new ProducerRecord<>("vaultcommerce.orders.placed.v1", orderId, payload);
    producer.send(record, (meta, ex) -> {
        if (ex != null) log.error("Failed to publish order {}", orderId, ex);
    });
}

Quick recall

Everything you need if you only revisit this box.

  1. Sync chains fail together; async isolates failures per consumer.
  2. Brokers buffer spikes so producers stay fast.
  3. VaultCommerce moved to events when checkout p99 exceeded 2 seconds.

Test yourself

Answer these before moving on — recall is what makes it stick.