Skip to content
advanced Phase 102 · More Trade-offs

Synchronous vs Asynchronous Processing

45m
1 problems
Topic Progress 0%

Sync vs Async Overview

Synchronous Processing

// Synchronous: Wait for completion
public function saveProduct($product)
{
    // 1. Save to database (wait)
    $this->resourceModel->save($product);
    
    // 2. Update search index (wait)
    $this->searchIndexer->reindexProduct($product->getId());
    
    // 3. Send notification (wait)
    $this->notifier->sendProductUpdate($product);
    
    // 4. Return response
    return $product;
}
// Total time: 100ms + 200ms + 300ms = 600ms
// Customer waits 600ms

Asynchronous Processing

// Asynchronous: Queue for later processing
public function saveProduct($product)
{
    // 1. Save to database (wait)
    $this->resourceModel->save($product);
    
    // 2. Queue search reindex (don't wait)
    $this->queue->sendMessage('product_reindex', [
        'product_id' => $product->getId()
    ]);
    
    // 3. Queue notification (don't wait)
    $this->queue->sendMessage('product_notification', [
        'product_id' => $product->getId()
    ]);
    
    // 4. Return response immediately
    return $product;
}
// Total time: 100ms (database only)
// Customer waits 100ms
// Background workers process queue

Consistency Trade-offs

Strong Consistency (Sync)

// Synchronous: Guaranteed completion
public function processOrder($order)
{
    // All operations must succeed
    $this->db->beginTransaction();
    try {
        $this->saveOrder($order);
        $this->updateInventory($order);
        $this->processPayment($order);
        $this->sendConfirmation($order);
        $this->db->commit();
    } catch (\Exception $e) {
        $this->db->rollBack();
        throw $e;
    }
}
// Pros: Data always consistent
// Cons: Slow, single point of failure

Eventual Consistency (Async)

// Asynchronous: Eventual consistency
public function processOrder($order)
{
    // Save order (critical path)
    $this->saveOrder($order);
    
    // Queue other operations
    $this->queue->sendMessage('update_inventory', $order->getData());
    $this->queue->sendMessage('process_payment', $order->getData());
    $this->queue->sendMessage('send_confirmation', $order->getData());
    
    // Order is "saved" but not fully processed
    // Inventory, payment, confirmation happen later
}
// Pros: Fast response, better UX
// Cons: Temporary inconsistency possible

Consistency Scenarios

Scenario: Order placed, inventory not updated yet

Sync:
├── Order saved ✓
├── Inventory updated ✓
├── Payment processed ✓
└── Response sent (600ms)

Async:
├── Order saved ✓
├── Response sent (100ms)
├── Inventory updated (background)
├── Payment processed (background)
└── Confirmation sent (background)

Risk: Customer orders, another customer buys same item
Solution: Reserve inventory synchronously, fulfill async

Performance Characteristics

Response Time

// Synchronous: Cumulative response time
// Product save: 100ms
// Index update: 200ms
// Notification: 300ms
// Total: 600ms

// Asynchronous: Only critical path
// Product save: 100ms
// Queue messages: 10ms
// Total: 110ms

// Improvement: 82% faster response

Throughput

Synchronous:
├── 100 requests/sec
├── Each request: 600ms
├── Thread blocked for 600ms
└── Limited by slowest operation

Asynchronous:
├── 1000 requests/sec (critical path)
├── Each request: 110ms
├── Thread freed quickly
└── Queue workers process independently

// 10x throughput improvement

Resource Utilization

// Synchronous: Resources held during processing
// Database connection: 600ms
// Memory: 600ms
// CPU: 600ms

// Asynchronous: Resources released quickly
// Database connection: 100ms
// Memory: 100ms
// CPU: 100ms
// Queue worker: Separate resources

// Better resource efficiency with async

Failure Impact

Synchronous failure:
├── Payment gateway timeout (5s)
├── Customer waits 5 seconds
├── Request fails
└── User experience: Poor

Asynchronous failure:
├── Payment queued for processing
├── Customer gets immediate response
├── Payment processed in background
├── If fails: Retry, notification
└── User experience: Good (with fallback)

Implementation Patterns

Magento 2 Message Queue

// Producer: Send message
$this->queue->sendMessage('product.reindex', [
    'product_id' => $productId,
    'store_id' => $storeId
]);

// Consumer: Process message
class ProductReindexConsumer
{
    public function process(MessageInterface $message)
    {
        $data = json_decode($message->getBody(), true);
        $this->reindexer->reindexProduct($data['product_id']);
    }
}

// queue_consumer.xml
<config>
    <queue name="product.reindex">
        <consumer name="product.reindex.consumer"
                  queue="product.reindex"
                  handler="Vendor\Module\Consumer\ProductReindexConsumer::process"/>
    </queue>
</config>

Hybrid Approach

// Critical path: Sync
// Non-critical: Async
public function processOrder($order)
{
    // Sync: Save order (critical)
    $this->saveOrder($order);
    
    // Sync: Reserve inventory (critical)
    $this->reserveInventory($order);
    
    // Async: Process payment
    $this->queue->sendMessage('payment.process', $order->getData());
    
    // Async: Send confirmation
    $this->queue->sendMessage('email.confirmation', $order->getData());
    
    // Async: Update analytics
    $this->queue->sendMessage('analytics.order', $order->getData());
    
    return $order;
}

Error Handling

// Sync error handling
try {
    $this->processOrder($order);
} catch (\Exception $e) {
    $this->logger->error($e->getMessage());
    throw new \Magento\Framework\Exception\LocalizedException(
        __('Order processing failed')
    );
}

// Async error handling with retry
$this->queue->sendMessage('payment.process', $order->getData(), [
    'max_retries' => 3,
    'retry_delay' => 60,
    'dead_letter_queue' => 'payment.failed'
]);

// Dead letter queue processing
public function processFailedPayment($message)
{
    $this->logger->critical('Payment failed permanently', $message->getData());
    $this->adminNotifier->notify('Payment requires manual processing');
}

Practice Problems

0 / 1 solved
Order Processing Strategy

Design order processing with sync for critical operations and async for non-critical.

Solution
// Strategy:
// 1. Sync: Save order, reserve inventory, validate address
// 2. Async: Process payment, send confirmation, update analytics
// 3. Sync: Return order with 'processing' status
// 4. Async: Update status on payment success
// 5. Failure: Retry payment, notify admin

Quiz

1. When should you use synchronous processing?

Question 1 options

2. What is the main benefit of asynchronous processing?

Question 2 options

3. What is eventual consistency?

Question 3 options

4. How should you handle async failures?

Question 4 options

Flashcards

Question

Sync processing characteristic?

Answer

Wait for completion, strong consistency, slower response

Question

Async processing characteristic?

Answer

Queue for later, eventual consistency, faster response

Question

When to use sync?

Answer

Critical operations: order save, payment, inventory reserve

Question

When to use async?

Answer

Non-critical: notifications, indexing, analytics, reporting

Question

Async failure handling?

Answer

Retry with backoff, dead letter queue, admin notification

Revision Notes

Key Takeaways

  • 1. Sync: Wait for completion, strong consistency, slower response
  • 2. Async: Queue for later, eventual consistency, faster response
  • 3. Use sync for critical operations (order save, payment)
  • 4. Use async for non-critical (notifications, indexing)
  • 5. Hybrid: Critical sync, non-critical async

Interview Tips

  • Explain consistency vs performance trade-offs
  • Know when to use each approach
  • Discuss error handling patterns
  • Understand hybrid approaches

Cheat Sheet

Sync vs Async

  • Sync: Wait, consistent, slow
  • Async: Queue, eventual, fast
  • Sync: Order save, payment, inventory
  • Async: Notifications, indexing, analytics
  • Hybrid: Critical sync, rest async
  • Error: Retry + dead letter queue