Platform Events are Salesforce's native event-driven messaging layer. They decouple publishers from subscribers, work across Apex, Flow, LWC, and external systems, and are built on the CometD (Bayeux) protocol. This tutorial covers everything from creating your first event to debugging missed messages.

What Platform Events Are Good For

  • Trigger asynchronous processing without governor limit bleed from the originating transaction
  • Stream data changes to an external system in real time (e.g., notify a warehouse system when an Order is confirmed)
  • Push real-time UI updates to LWC components without polling
  • Log errors and diagnostic messages without DML in trigger context

Step 1: Define a Platform Event

Setup → Platform Events → New Platform Event. Name it with a clear noun: Order_Confirmed__e, Integration_Error__e. Add fields just like a custom object. Two delivery options:

  • Publish After Commit — event fires only if the transaction commits successfully (safest for most use cases)
  • Publish Immediately — event fires even if the transaction rolls back (use for error logging where you need the event even on failure)

Step 2: Publish from Apex

Order_Confirmed__e evt = new Order_Confirmed__e(
    Order_Id__c   = orderId,
    Amount__c     = 1500.00,
    Customer__c   = 'ACME Corp'
);

Database.SaveResult sr = EventBus.publish(evt);
if (!sr.isSuccess()) {
    // log error
}

You can publish a list of up to 150 events per transaction. Events are stored for 72 hours (High Volume) or 24 hours (Standard Volume) for replay.

Step 3: Subscribe via Apex Trigger

trigger OrderConfirmedTrigger on Order_Confirmed__e (after insert) {
    for (Order_Confirmed__e evt : Trigger.new) {
        // process each event
        System.debug('Order received: ' + evt.Order_Id__c);
    }
}

Platform Event triggers run asynchronously. They have their own governor limit context — separate from the publishing transaction.

Step 4: Subscribe via LWC

import { subscribe, MessageContext } from 'lightning/empApi';

// channel name matches your Platform Event API name
const CHANNEL = '/event/Order_Confirmed__e';

subscription = await subscribe(CHANNEL, -1, (message) => {
    const payload = message.data.payload;
    this.orderId = payload.Order_Id__c;
    // update component state
});

Use -1 as replayId to receive only new events. Use a stored replayId to replay missed events (up to the retention window).

Step 5: Subscribe via Flow

In Flow Builder, create a new Autolaunched Flow triggered by a Platform Event. Select your event as the trigger. The flow receives event fields as input variables. Use this for declarative responses to events — no Apex needed for simple cases.

External System Subscription (CometD)

External systems subscribe using a CometD client authenticated with a Connected App. The channel is /event/YourEvent__e. Libraries exist for Java, Node.js, Python, and .NET. Salesforce also supports Pub/Sub API (gRPC-based, replacing CometD for high-throughput scenarios).

Debugging Tips

  • Use the Event Monitoring app to see published events and delivery status
  • Failed trigger subscriptions are retried up to 3 times before the event is marked failed
  • Use a dedicated Integration_Error__e event (Publish Immediately) to log errors — it survives transaction rollbacks
  • ReplayId = 0 replays all stored events; -1 = new only; specific ID = replay from that point
SK

Sumit Kumar Singh

Independent Salesforce Consultant

I use Platform Events as the backbone of every real-time integration I build. They've replaced outbound messages on every project since 2021.

About the Author