I keep learning this in system design: one pattern alone rarely gives you a full solution.

I hit this again while working on a flight search system.

Initial State

The problem

  • Call multiple flight providers
  • Each responds at a different speed
  • Some fail
  • Users expect immediate results

No single pattern covered all of that.

What didn’t work

  • Synchronous calls → blocked by the slowest provider
  • Async + Task.WhenAll → still waits for everyone
  • Background threads + polling → fragile under restarts and scale

Each approach solved part of the problem.

What worked

The solution was possible when combining patterns, each covering a different concern:

  • Scatter–Gather → parallel provider calls
  • Publish–Subscribe → decouple dispatch from providers
  • Correlation ID → track one search across async boundaries
  • Aggregator → merge partial responses safely
  • Async Reply over HTTP → return immediately
  • Hexagonal Architecture → the code structure discipline

Together, they formed a stable flow.

Request Flow

User Interface

Progressive Results

I uploaded the code to github for those who want to explore.

— HH

Posted Jan 27, 2026, 1:53 PM UTC

459
Loading comments…