afv-library/skills/integration-connectivity-generate/references/event-driven-architecture-guide.md

10 KiB

Event-Driven Architecture Guide

Source: Salesforce Architect Decision Guides — Event-Driven Architecture, Async Processing Related: event-patterns.md | callout-patterns.md


Overview

Event-Driven Architecture (EDA) decouples producers from consumers, enabling scalable, resilient integrations. Salesforce supports multiple event mechanisms — choosing the right one depends on volume, latency, and consumer location.


5 Core EDA Patterns

Pattern Comparison Matrix

Pattern Description Salesforce Implementation Best For
Pub/Sub Publisher emits, multiple subscribers consume Platform Events + Pub/Sub API Multi-consumer notifications, cross-system sync
Fanout One event → multiple independent consumers Platform Events + multiple subscribers Parallel processing, diverse downstream systems
Passed Messages Event carries data payload for consumer processing Platform Events with rich fields External systems needing full context in message
Streaming Continuous data feed for real-time consumers CDC + Pub/Sub API Data replication, real-time dashboards
Queueing Ordered, guaranteed-delivery message processing Platform Events (High-Volume) with checkpoints Sequential processing, backpressure handling

When to Use Each

Pub/Sub: Default choice for most event-driven integrations. Works for both internal (Apex triggers) and external (Pub/Sub API) consumers.

Fanout: When a single business event (e.g., "Order Placed") needs to notify billing, shipping, analytics, and notifications simultaneously.

Passed Messages: When the consumer needs all context in the event itself (no callback to Salesforce). Keep payloads lean — 1 MB limit.

Streaming: For data replication to warehouses or lakes. CDC + Pub/Sub API replaces legacy Streaming API.

Queueing: When processing order matters and you need backpressure handling. Use High-Volume Platform Events with resume checkpoints.


The Pub/Sub API is the recommended mechanism for external consumers subscribing to Platform Events and CDC events. It replaces the legacy Streaming API (CometD).

Key Characteristics

Feature Pub/Sub API Legacy Streaming API (Deprecated)
Protocol gRPC CometD (long-polling)
Authentication OAuth 2.0 Session-based
Event Types Platform Events, CDC, Custom Channels PushTopic, Generic Events, Platform Events
Performance High throughput, binary protocol Limited by long-polling overhead
Status Current — use for all new development Deprecated — no new investments

Subscription Modes

  • Subscribe: Stream events from a given replay ID forward
  • PublishStream: Bi-directional — publish events via gRPC (no Apex needed)
  • ManagedSubscribe: Salesforce manages replay state (simplest for external consumers)

External Consumer Architecture

Salesforce Org
  └── Platform Event / CDC Event
        └── Pub/Sub API (gRPC endpoint)
              └── External Consumer (Java, Python, Node.js, Go)
                    ├── Process event
                    ├── Commit replay ID
                    └── Handle failures with retry

LWC Subscription (Internal)

For Lightning Web Components subscribing to Platform Events, use empApi:

import { subscribe, unsubscribe, onError } from 'lightning/empApi';

const channelName = '/event/Order_Status__e';
let subscription = {};

connectedCallback() {
    subscribe(channelName, -1, (response) => {
        console.log('Event received:', JSON.stringify(response));
        this.handleEvent(response.data.payload);
    }).then((sub) => {
        subscription = sub;
    });

    onError((error) => {
        console.error('empApi error:', JSON.stringify(error));
    });
}

disconnectedCallback() {
    unsubscribe(subscription);
}

Event Relays to AWS EventBridge

Salesforce Event Relays forward Platform Events to AWS EventBridge, enabling cloud-native event processing.

Architecture

Salesforce Platform Event
  └── Event Relay Definition (Metadata)
        └── AWS EventBridge Partner Event Source
              ├── AWS Lambda
              ├── AWS SQS
              ├── AWS Step Functions
              └── Any EventBridge target

When to Use

  • AWS-native architecture needing Salesforce events
  • Complex event processing requiring AWS services (Step Functions, SQS, SNS)
  • Fan-out to multiple AWS consumers from a single Salesforce event
  • Event archival in AWS S3 or data lakes

Limitations

  • One-way only (Salesforce → AWS)
  • Adds latency (~seconds) compared to direct Pub/Sub API
  • Requires AWS account configuration and IAM setup
  • Platform Event limits still apply on the Salesforce side

Apache Kafka on Heroku

For organizations needing long-retention, high-throughput event streaming beyond Platform Event limits.

Comparison with Platform Events

Feature Platform Events Kafka on Heroku
Retention 24h (HV) / 72h (SV) 1-6 weeks (configurable)
Throughput Millions/day (HV) Millions/second
Consumer groups Limited Unlimited
Replay ReplayId-based Offset-based, topic-level
Cost Included / Platform Event add-on Heroku Kafka add-on

When to Choose Kafka

  • Retention > 72 hours required
  • Need multiple independent consumer groups
  • Event throughput exceeds Platform Event limits
  • Existing Kafka ecosystem in organization
  • Need topic partitioning for ordered processing

Integration Pattern

Salesforce → Platform Event → Apex/Flow subscriber → Heroku Kafka producer
                                                        └── Consumer Group A (analytics)
                                                        └── Consumer Group B (data lake)
                                                        └── Consumer Group C (external CRM)

When NOT to Use Events

Events are not always the right choice. Prefer synchronous patterns when:

Scenario Why Not Events Better Alternative
Need synchronous response Events are async — no return value REST callout with Named Credential
Infrequent data changes Event infrastructure overhead not justified Scheduled batch sync
Target system lacks event support Consumer can't subscribe to events Outbound Messages or REST callout
Simple record sync Over-engineering for basic needs Salesforce Connect / External Objects
Data volume < 100 records/day Platform Event overhead unnecessary Scheduled Flow with REST callout

High-Volume Outbound Pattern

For scenarios requiring high-volume data push to external systems:

Do NOT use async Apex directly for high-volume outbound. Apex async limits (250K daily Queueable, 250K daily @future) are shared across all org operations. Consuming them for outbound sync starves other automation.

Salesforce Record Change
  └── After-Save Flow / Trigger
        └── Publish Platform Event (lightweight payload)
              └── External Middleware (MuleSoft, Pub/Sub API consumer)
                    ├── Enrich data (callback to Salesforce REST API if needed)
                    ├── Transform to target format
                    ├── Deliver to target system with retry logic
                    └── Report status back via Platform Event or REST callback

Benefits

  • No Apex async limit consumption — events don't count against daily limits
  • Middleware handles retries — exponential backoff, dead letter queues
  • Scalable — middleware scales independently of Salesforce
  • Observable — middleware provides logging, monitoring, alerting

Monitoring Event-Driven Systems

AsyncApexJob Monitoring

Query job status for async Apex that processes events:

List<AsyncApexJob> jobs = [
    SELECT Id, JobType, Status, NumberOfErrors, MethodName, CreatedDate
    FROM AsyncApexJob
    WHERE CreatedDate = TODAY
    AND Status IN ('Failed', 'Aborted')
    ORDER BY CreatedDate DESC
    LIMIT 50
];

Polling limit: AsyncApexJob queries are subject to SOQL limits. Max polling frequency: every 5 minutes.

Platform Event Metrics

  • Setup → Platform Events → Usage: View publish/subscribe counts
  • EventBusSubscriber: Query for subscriber status and position
  • Proactive Monitoring: Set up Flow or Apex to alert on failed event processing
// Check subscriber lag
List<EventBusSubscriber> subs = [
    SELECT Name, Position, Retries, LastError, Status
    FROM EventBusSubscriber
    WHERE Topic = 'Order_Status__e'
];

Key Metrics to Monitor

Metric Source Alert Threshold
Failed events EventBusSubscriber.Retries > 3 consecutive retries
Subscriber lag EventBusSubscriber.Position vs latest ReplayId Lag > 1000 events
Async job failures AsyncApexJob.NumberOfErrors Any failure
Event publish errors Database.SaveResult in publisher Any failure
Daily event usage Setup → Company Information → Platform Event Usage > 80% of allocation

Summary: EDA Decision Tree

Need real-time data sync?
  ├── YES → Is consumer external?
  │    ├── YES → Pub/Sub API + Platform Events (or CDC for record changes)
  │    └── NO → Platform Event trigger subscriber (or empApi for LWC)
  └── NO → Is volume high (>10K records/day)?
       ├── YES → Middleware + Platform Events (high-volume outbound pattern)
       └── NO → Scheduled batch sync (simplest, most maintainable)