If you have ever heard the phrase “event-driven architecture” thrown around in a Salesforce conversation and quietly nodded along, this is the article that makes it click. Platform Events are how Salesforce announces, in real time, that something has changed — inside the platform and out to the wider world.
Instead of external systems constantly polling Salesforce (“anything new yet? …how about now?”), Platform Events let Salesforce broadcast a message the moment a change happens. Anyone who cares about that change subscribes once and gets notified automatically. It is one of Salesforce's native integration patterns, built on the Streaming API and a classic publish/subscribe model.
The payoff is huge: fewer brittle point-to-point integrations, far less pressure on your API limits, and reusable, modular components that scale as your architecture grows more complex.
Start here · the intuition
The “dinner's ready” analogy
Before any jargon, picture this. Three couples share a holiday house. One person is cooking; everyone else is hungry and scattered around the house — one by the pool, one upstairs — and nobody can see the kitchen.
So people start knocking on the kitchen door: “Is food ready?” “No.” A minute later, another knock: “Is it ready now?” “No.” Knock after knock, the cook's patience drains. Every interruption is wasted effort, and eventually they hit their limit.
That is polling. Now swap the cook for Salesforce and the hungry friends for external systems, all repeatedly asking “Have any account records changed?” Salesforce keeps answering “no, no… no,” burning API calls on questions with no news.
The smarter move? The cook creates a group chat and shares the link: join if you want to know when food's ready. When dinner is done, one broadcast goes out and everyone knows instantly. The cook never gets interrupted, and nobody wastes a trip to the kitchen.
Platform Events are Salesforce broadcasting that something has changed — like one group-chat message when dinner's ready, instead of fielding the same question over and over.
The model
How the publish/subscribe model actually works
Every Platform Event flows through three roles. Once you internalise these, the rest of the topic is mostly detail.
- Event producer (publisher) — the app, flow, or piece of code that creates an event when something meaningful happens.
- Event bus (the channel) — a queue that receives events and broadcasts them in strict chronological order, executing one after another. Salesforce calls this the event bus.
- Event consumer (subscriber) — anything that has subscribed to the channel. The instant an event lands on the bus, every subscriber is notified.
The beauty is the decoupling: a consumer never needs to know who the producer is or how it works. It only needs to know about the event record arriving on the bus. That single idea is what dissolves the tangle of point-to-point connections.
The vocabulary, decoded
- Event — a change in state that matters to a business process.
- Event message / notification — the payload that carries the data about what changed.
- Channel / event bus — the conduit the producer transmits over and consumers subscribe to.
- ReplayId — an identifier that lets a subscriber replay a specific event from the stream.
- Window — a defined period of time over which events are retained (24 hours in the standard event bus).
Salesforce rebuilt its event bus in 2020 to support a growing portfolio — Tableau and MuleSoft were cited as key drivers in that decision.
Anatomy
What a Platform Event is made of
A Platform Event looks and feels a lot like an sObject or custom object — but it is built from a distinct set of moving parts.
Platform Events are immutable. Once published they cannot be updated or rolled back — there is only “insert” (publish), never update or delete. That is the single biggest behavioural difference from an sObject.
The difference that matters
sObject vs. Platform Event
They share a look, but they behave like opposites. Notice the suffix too: a Platform Event's API name ends in __e, the way a custom object ends in __c.
| Capability | sObject __c | Platform Event __e |
|---|---|---|
| data ops | Insert, Update, Delete (DML) | Publish only (insert) |
| retrieval | SOQL / SOSL queries | Streaming API — no querying |
| automation | Triggers (before & after) | Subscribers (after-insert only) |
| execution | Parallel contexts | Guaranteed order of execution |
| UI | Tabs, list views, reports | None — no page layout, not reportable |
| fields | Full data-type range | Checkbox, Date, Date/Time, Number, Text, Text Area only |
| mutability | Editable records | Immutable; all fields read-only by default |
You won't find Platform Event records in the Salesforce UI — there's no tab and no page layout. To inspect what came through, subscribers typically write the data into a regular custom object.
Timing
Two ways an event can fire
When you define a Platform Event you choose its publishing behaviour — when, exactly, the event gets pushed onto the bus relative to the database transaction.
- Publish after commit — the event fires only once the transaction commits successfully. Use it when the subscriber should react to a completed outcome (e.g. send a confirmation email after a process finishes).
- Publish immediately — the event fires regardless of whether the transaction succeeds. Use it when the signal is valuable even if the work fails (e.g. flag a suspicious login attempt right away).
Hands on
Defining, publishing & subscribing
You define Platform Events from Setup → Integrations → Platform Events. The interface feels like building a custom object: you add fields and relationships, then save. It's a “fire and forget” integration, much like outbound messaging.
Publishing — getting an event onto the bus
You can publish three ways:
- Declaratively — with Flow (Process Builder also works, but it's being retired, so don't build new ones on it).
- Programmatically — with Apex, using
EventBus.publish(). - From outside Salesforce — via the Salesforce API from any external app.
A minimal Apex publish looks like this:
// Build the event record(s)
List<Order_Shipping__e> events = new List<Order_Shipping__e>();
events.add(new Order_Shipping__e(
Order_Number__c = '12345',
Status__c = 1
));
// Publish to the event bus
List<Database.SaveResult> results = EventBus.publish(events);
for (Database.SaveResult sr : results) {
if (sr.isSuccess()) {
System.debug('Event published.');
} else {
for (Database.Error err : sr.getErrors())
System.debug('Error: ' + err.getStatusCode());
}
}
Subscribing — reacting when an event lands
- Apex trigger — write an
after inserttrigger on the event object. (Only after-insert is supported.) - Flow — a Platform Event–triggered flow, fully declarative.
- Lightning components — use the
lightning/empApimodule in LWC, or thelightning:empApicomponent in Aura. - External apps — subscribe over CometD long-polling, or use the Pub/Sub API.
The Apex subscriber is as small as it gets:
trigger OrderShippingTrigger on Order_Shipping__e (after insert) {
// react to each incoming event here
}
And the LWC import:
import { subscribe, unsubscribe, onError }
from 'lightning/empApi';
Why it matters
From integration spaghetti to a single broadcast
Take something ordinary: Web-to-Lead. A web form creates a lead, the lead gets assigned and converted, and that conversion kicks off a chain of downstream work — order management, fulfilment, billing, notifications. In a point-to-point world, every one of those systems is wired directly to the others, each polling and pushing on its own. The result is a tangle that's painful to change and quick to hit API limits.
Publish a single “create order” event instead, and the knot loosens. Order management doesn't need every system poking it for updates; it simply broadcasts the change once, and whoever cares reacts.
Worked example
Lead in → Marketing Opportunity out
Here's a concrete, fully clicks-based build. The goal: whenever a Lead is created, automatically create a “Marketing Opportunity” record — so the marketing team learns what products people are asking about, without ever touching the Lead object the sales team owns.
Define the event
Setup → Platform Events → New. Name it Lead Platform Event and add text fields: Lead Name, Lead Salesforce ID, Product Interest.
Publish on Lead creation
Build a record-triggered flow on the Lead object. On create, map the Lead's fields into a new Lead Platform Event record, then activate. The event is now broadcast every time a Lead is born.
Create a landing object
Because you can't query event records, make a custom object — Marketing Opportunity — with matching fields to capture the data.
Subscribe and write
Build a Platform Event–triggered flow on Lead Platform Event. It creates a Marketing Opportunity record and maps the event fields across. Activate it.
Test
Create a Lead with a Product Interest. A Marketing Opportunity record appears — carrying the Lead ID, name, and product interest — visible to a team that never had Lead access.
Decision guide
When to reach for Platform Events
They shine in two situations especially. First, real-time sync between Salesforce and another system — for example, when a portal creates leads that must mirror into Salesforce instantly, and changes need to flow back without either side polling. Second, classic pub/sub use cases — think of a “Notify me when back in stock” button: you've subscribed to an event that fires when inventory returns.
There's also a powerful side-benefit for developers: Platform Events can help you sidestep governor limits. Mixed-DML errors, too many SOQL queries or DML statements, CPU timeouts — moving work onto an event and processing it in a fresh, asynchronous context is often the cleanest way out.
Strengths
- Real-time, near-instant integration
- Replaces many point-to-point links — multiple systems subscribe to one event
- More clicks, less code
- Decoupled: producers and consumers stay independent
- Events retained ~24 hours; replayable by ReplayId
Trade-offs
- No native email action inside an event-triggered flow
- Limited logging and durability
- Replaying events after a failure is fiddly
- Can't query, report on, or view event records in the UI
- Daily event allocations vary by org edition — monitor them
Each org has a daily event allocation tied to its edition. Blow past it and you'll see 403 :: Organisation total events daily limit exceeded. Monitor usage proactively — exhausting the allocation causes real performance issues and service disruption.
Before you build
Things to keep in your back pocket
- The API name always carries the
__esuffix. - You can't use Platform Events in SOQL, SOSL, reports, list views, or search — there's no tab.
- Published events can't be rolled back, and the definition, once deleted, is gone permanently.
- All fields are read-only by default, with a limited set of allowed data types.
- Only after-insert triggers are supported on the subscribe side.
- You can manage access through profiles and permissions, and work with events both via API and declaratively.
- Platform Events pair beautifully with Salesforce DX — compact, modular code bases that deploy cleanly.
The takeaway
Bringing it home
Salesforce has invested heavily in this technology, so it's mature, robust, and genuinely transformative for an architecture under strain. Platform Events let you exchange data in real time — inside Salesforce and out to external platforms — without the cost and fragility of point-to-point wiring.
Strip away the vocabulary and it's the group-chat principle: rather than fielding the same question over and over, Salesforce sends one message to everyone who's listening the moment something changes. That's the whole idea — Salesforce, broadcasting change.
Producer publishes → event lands on the ordered bus → every subscriber is notified instantly. Immutable, decoupled, real-time. When you next hear “event-driven architecture” in a Salesforce room, you'll know exactly what's on the table.

