In a request-response design, one service calls another and waits for the answer. In an event-driven design, a service announces that something happened and moves on. Every service that cares reacts in its own time.

What is event-driven architecture?

AWS defines it as an architecture that “uses events to trigger and communicate between decoupled services” (AWS). An event is a change in state, such as an item placed in a shopping cart. An event can carry the state itself, like the item and its price. Or it can be a bare notice, like word that an order shipped.

AWS names three parts. Producers publish events. Routers filter the events and push them to consumers. Consumers act on them. Because producers and consumers are decoupled, each can be updated and scaled on its own (AWS). Microsoft calls the middle piece an event channel, often built as an event broker (Microsoft).

How does an event-driven system work?

The producer does not know who is listening. The consumers do not know about each other either (Microsoft). So a new consumer can join without a change to the producer or to the other consumers.

Events travel in one of two models.

  • Publish-subscribe. The broker tracks subscriptions and sends each event to every subscriber. Events are not kept in a durable log, so a new subscriber does not see past events (Microsoft).
  • Event streaming. Events are written to a durable log, in strict order within each partition. A client can read from any point and replay events, which supports reprocessing after a bug fix (Microsoft).

Apache Kafka is an event streaming platform. It keeps events in topics and does not delete them once they are read (Apache Kafka). Events with the same key, such as a customer ID, go to the same partition. Kafka guarantees that consumers read that partition’s events “in exactly the same order as they were written” (Apache Kafka).

What are the main event-driven patterns?

Martin Fowler found that when people talk about events, “they actually mean some quite different things” (Martin Fowler). He named four patterns.

PatternWhat the event carriesWhat it buysWhat to watch
Event notificationA note that something changed, often an ID and a link back to the senderLow coupling. Simple to set up.The flow across events is not written in any program text
Event-carried state transferThe changed data itself, such as a new addressReceivers keep working if the source is down. No remote call.Many copies of the data. More state to keep at each receiver.
Event sourcingEvery state change, stored as the source of truthA strong audit trail. Past states can be rebuilt by replay.Replay breaks when results depend on outside systems. Event schemas change over time.
CQRSSeparate models for reads and writes. It can exist with no events at all.Simpler models when reads and writes differTwo models to keep. Many of Fowler’s colleagues find it often misused.

Fowler flags one trap in the first pattern: an event used as a “passive-aggressive command” (Martin Fowler). The sender expects an action but sends a plain event. If a reaction must happen, send a command.

What are the benefits and trade-offs of event-driven architecture?

The main benefit is isolation. Services know the router and not each other, so when one service fails, the rest keep running. The router also soaks up surges in load (AWS). The costs show up in four places.

  • Eventual consistency. Right after an event goes out, services do not yet agree on the data. For a while, parts of the system hold different views (Microsoft).
  • Duplicates. Amazon SQS standard queues deliver each message at least once, and sometimes more than once (Amazon SQS). AWS Lambda event source mappings also process each event at least once. AWS strongly recommends idempotent code, which gives the same result when an event runs twice (AWS Lambda).
  • Ordering. SQS also says messages can arrive out of order (Amazon SQS). Microsoft notes that events sent back by an error handler run out of sequence (Microsoft).
  • Debugging. Fowler warns that a flow spread across events is hard to see. Often the only way to trace it is to watch a live system (Martin Fowler). Microsoft advises a correlation ID in every event (Microsoft).

When should you use request-response instead of events?

Use request-response when the caller needs an answer before it can go on. Microsoft names cases where the event-driven style is a poor fit. One is a simple flow where synchronous calls meet the speed target. Another is a transaction that needs strong consistency across services (Microsoft).

Loyalty needs both. In Toast’s loyalty API, “the redeem transaction occurs during the payment process” (Toast). The accrue transaction “occurs asynchronously after you complete the payment process” (Toast). A redemption needs a yes before the till closes. The points earned on the sale can follow as an event.

How does event-driven architecture work in a loyalty program?

A purchase is the event. AWS calls the next step fanout: the router pushes one event to many systems, and each handles it for its own purpose (AWS). In a loyalty engine, one earn event reaches five consumers.

  • Points. Credits the member’s balance.
  • Tier. Adds the spend to tier qualification.
  • Offers. Checks whether the purchase completes a challenge or triggers an offer.
  • Fraud. Scores the earn for unusual patterns.
  • Analytics. Logs the sale for reports.

Duplicates arrive from the till. Toast’s loyalty API retries a request when it gets no response, and it does not mark the repeat. The loyalty side “must return a cached, duplicate response” (Toast). The CloudEvents spec gives the fix. Producers must keep source plus ID unique for each distinct event, and consumers can treat a repeated pair as a duplicate (CloudEvents). CloudEvents is a graduated project of the Cloud Native Computing Foundation (cloudevents.io).

Refunds and reversals need order. Toast’s reverse call carries the ID of “the previous loyalty program transaction that needs to be reversed” (Toast). Key every event by member ID so one member’s events stay in one ordered partition. A reversal that lands before its purchase should be parked until the purchase arrives. Our entry on POS integration covers the till side.

For illustration, a program handles 3,000,000 earn events a month. Tills resend 0.2% after a timeout, so 6,000 events arrive twice. Each earn averages 400 points. With no duplicate check, members get 2,400,000 points with no purchase behind them. At $0.01 a point, that is $24,000 of liability a month, or $288,000 a year. With the check, the second copy is dropped.

What should you ask a loyalty vendor about events?

  1. What happens when the same earn event arrives twice? Ask to see the duplicate check run in a test.
  2. How are one member’s events kept in order? What happens to a refund that arrives before its purchase?
  3. Which calls answer at the till, and which run after payment?
  4. Can a new consumer, such as a partner feed, subscribe with no change to the POS link?
  5. How long are events kept, and can they be replayed after a bug fix?
  6. Can one ID trace a single purchase through every service?

Each answer you skip becomes a support ticket after launch. Our entry on real-time processing covers the speed side of the same choice.

How GRAVTY handles event-driven architecture

GRAVTY is built from serverless parts. Its tech page says “cloud-native, serverless microservices support the transaction load.” GRAVTY “runs entirely on AWS Lambda and DynamoDB” too. The same page names Delta Lake for data. It says Delta Lake “combines real-time ingestion with long-term storage.”

For airlines, GRAVTY links to reservation, departure control, revenue accounting, CRM and partner systems. It does so “through open APIs and real-time events” (airline). It has 150+ system integrations. It runs 500M+ members in production. The uptime SLA is 99.99%. Average API latency is under 50 ms. Test the duplicate check and the refund order on GRAVTY with your own till data.

Frequently asked questions

What is an example of event-driven architecture?

A store checkout is a clear example. AWS describes an item placed in a shopping cart as an event, a change in state (AWS). In a loyalty program, the purchase event goes out once. The points, tier, offer and fraud services each react to it on their own.

Is Kafka an event-driven architecture?

No, Kafka is a tool an event-driven system can run on. Its own docs call it “an event streaming platform” (Apache Kafka). The architecture is the choice to have services publish and react to events. Kafka is one way to move those events.

What is the difference between event-driven architecture and microservices?

Microservices are how a system is split into parts, and events are one way those parts talk. AWS notes that the event-driven style is common in apps built with microservices (AWS). The same parts can also call each other directly.

Is event sourcing the same as event-driven architecture?

No, event sourcing is one pattern inside the wider style. In event sourcing, every change to state is recorded as an event, and the system can be rebuilt by replaying them (Martin Fowler). Fowler adds that event sourcing does not need asynchronous processing.

What is idempotency in event-driven architecture?

Idempotency means processing the same event twice gives the same result as processing it once. It matters because services such as Amazon SQS deliver some messages more than once (Amazon SQS). AWS Lambda can also process a record twice, so AWS strongly recommends idempotent code (AWS Lambda). In loyalty, it is what stops a retried sale from paying points twice.