Platform Event Trap: Salesforce Events Explained

A customer places an order, the order system publishes a message that says "order paid," and nothing else happens. No shipping label appears, no warehouse task opens, and no error shows up anywhere the team normally looks. The sender did its job, the message left the building, and the work it was supposed to trigger simply never arrived. That silent gap has a name in Salesforce work: a platform event trap. It is not one bug with one fix. It is a family of failure patterns where event driven work stalls, loops, or vanishes, while every individual part reports success.
To understand the trap, start with the normal pattern. A platform event, in Salesforce terms, is a message that describes something that happened, such as an order payment or a case closure. A publisher, which is the program that creates the message, sends it to the event bus, which is the delivery channel that holds messages and routes them to listeners. A subscriber, which is the program that listens for messages, receives the event and does the follow up work. The publisher and the subscriber never talk directly, and that loose coupling, which means the two sides depend on the message format rather than on each other, is the whole point: either side can change, scale, or pause without breaking the other.
The trap grows out of that same loose coupling. When the publisher and subscriber stop sharing a direct call, they also stop sharing errors. A failed direct call returns an error to the caller at once, but a failed event subscriber fails far away from the publisher, in a different process, minutes later, or not at all. This guide explains each trap in plain language: lost events, silent subscriber failures, endless loops, duplicate handling, ordering surprises, and retention expiry. It also covers the monitoring, replay, and design habits that catch traps early. Salesforce documents platform events as the base pattern, and our guide to API design covers the contracts that keep message formats stable. Our workflow automation work applies the same event discipline to client systems.
How Platform Events Normally Flow
A normal flow has four steps, and naming them helps you spot where a trap can form. First, something happens in a system, such as a payment clearing or a record changing, and the publisher builds an event message with the facts the subscriber will need. Second, the publisher sends the message to the event bus, which stores it and assigns it a position, like a number in a queue. Third, each subscriber reads the event from the bus and runs its own logic, such as creating a shipment or updating an external system. Fourth, the subscriber records its progress, so it can resume from the right position after a restart instead of reprocessing everything or skipping ahead.
Two properties of this flow matter most for traps. Events are delivered on a best effort basis with retries, which means the bus tries hard to deliver, but it cannot guarantee that every subscriber finishes every event exactly once. A subscriber may receive the same event twice after a retry, and a subscriber that crashes mid task may leave half finished work behind. Also, subscribers run independently, so a slow subscriber does not slow the publisher, but a broken subscriber does not alert the publisher either. The publisher sees a successful publish and moves on, while the subscriber struggles alone. That independence is a feature for scale and a hazard for visibility.
Teams choose events for good reasons: they connect systems without tight coupling, they absorb bursts of work, and they let new subscribers join without changing the publisher. An order event can feed shipping, billing, analytics, and a partner system, and each subscriber evolves on its own schedule. The trap appears when teams enjoy those benefits without paying the visibility cost. Events need the same care as any critical path, which is a chain of steps that must all succeed for the business outcome to happen, including error handling, monitoring, and a plan for missed work. Connecting systems this way is a core case in enterprise application integration, which joins separate business systems so data flows between them.
Trap One: The Event Nobody Handles
The simplest trap is an event with no working subscriber. A team renames an event field, deploys a subscriber to a different environment, or disables a subscriber during maintenance and forgets to re-enable it. The publisher keeps publishing, the bus keeps accepting messages, and no program ever acts on them. Business users notice first, usually as missing shipments or stale dashboards, days after the break. By then, the missed events may sit beyond the retention window, which is the limited time the bus keeps events before deleting them, and recovery turns into manual repair.
Prevent this trap with a subscriber registry, which is a simple list of every event type, its active subscribers, and its owner. Review the registry on every deploy, and alert when an event type receives publishes but no subscriber deliveries for a set period. That alert catches the rename case, the disabled subscriber case, and the environment mix up case in one check. Also give every event a version, and treat a field rename as a new version rather than a silent edit, so old subscribers fail loudly during testing instead of silently ignoring a field they no longer recognize.
Testing deserves a specific note here. A subscriber that passes tests against a mock event, which is a fake message built for testing, can still fail against a real event with a missing optional field or an unexpected value. Test with real shaped events, including empty fields, long text, and values at the edges of allowed ranges. Record a sample real event for each type, scrubbed of private data, and replay it in staging, which is a pre production system that mirrors live settings, before every release. A trap that testing catches costs an hour. A trap that customers catch costs trust.
Trap Two: Loops That Never Stop
A loop trap starts innocently. A subscriber reacts to an event by updating a record, and that update publishes the same event again, which wakes the subscriber again, which updates the record again. Each cycle looks like normal work, so no error appears, but the system burns through limits, which are caps on how much work a platform allows in a set period, and it can flood downstream systems with duplicate tasks. Loops often hide behind two subscribers that trigger each other: subscriber A updates a field that subscriber B watches, and subscriber B updates a field that subscriber A watches, so the pair ping pongs forever.
Break loops with three habits. First, make subscribers check before they act: if the record already holds the desired state, do nothing and stop. Second, mark events that a subscriber itself caused, and skip reprocessing of your own echoes, or route internal updates through a separate path that does not publish. Third, set a hard stop: count how many times one business item has been processed, and send the item to a human review queue after a small threshold, such as three attempts. A loop with a stop rule becomes a visible incident. A loop without one becomes a bill and a mess.
Loops also expose a design smell, which is a sign that the design itself invites trouble. If two subscribers constantly retrigger each other, the event design probably mixes two responsibilities into one message, or the subscribers share state they should not share. Split the events so each one describes one fact, and let each subscriber own one outcome. Cleaner event boundaries mean fewer accidental triggers, and they make the system easier to explain to the next developer, which matters because the next developer inherits every loop you leave behind.
Trap Three: Duplicates and Ordering Surprises
Duplicates form the third trap, and they follow from retries. When a subscriber crashes after doing its work but before recording progress, the bus redelivers the event, and the subscriber does the work twice. Two shipments, two refunds, or two welcome emails follow, and customers notice duplicates faster than they notice missing work. The fix is idempotency, which means designing an operation so repeating it has the same effect as doing it once. A subscriber that checks "did I already process event id 12345" before acting turns a duplicate delivery into a harmless no-op, which is an action that safely does nothing.
Ordering adds a subtler trap. Events for one business item usually arrive in order, but events for different items, or events replayed after an outage, can arrive out of order. A subscriber that processes a "case closed" event before the "case reopened" event that actually happened later will end with the wrong state. Guard against this with a timestamp or sequence check: ignore an event older than the latest state already applied, or hold out of order events briefly until their predecessors arrive. Not every system needs strict ordering, but every system needs a stated ordering rule, so developers do not assume order the bus never promised.
Partial failure completes the picture. A subscriber that updates three systems in one run can succeed on two and fail on the third, leaving the business in a half done state with no single error to chase. Design subscribers to do one outcome per run where possible, or to record progress step by step so a retry resumes from the failed step instead of redoing finished steps. When a subscriber cannot finish, it should park the event in a dead letter queue, which is a holding area for messages that repeatedly fail, with the error and the event id attached, rather than retrying forever or dropping the event quietly.
| Trap | Symptom | First defense |
|---|---|---|
| No subscriber | Work never happens, no error | Publish versus delivery alert |
| Loop | Repeated work, limit warnings | Check before acting, hard stop |
| Duplicate | Double shipments or emails | Idempotent handling by event id |
| Out of order | Wrong final state | Timestamp or sequence check |
| Partial failure | Half done business outcome | Dead letter queue with details |
What Monitors Platform Event Traps Best
Monitoring answers the question "what monitors platform event traps best" with a layered answer, not a single tool. Start with bus metrics: published count, delivered count, and subscriber error count per event type, shown side by side. A growing gap between published and delivered points at a stalled or missing subscriber. A rising error count points at a subscriber that keeps failing. A flat delivered count during business hours points at a publisher that stopped publishing. These three signals catch most traps within minutes, while a dashboard that shows only total events will hide all three.
Add business outcome checks on top of bus metrics, because the bus can look healthy while the business outcome fails. Count orders that reached fulfillment, cases that reached closure, and partner records that reached sync, and compare those counts with the events published. When the business count falls behind the event count, something between publish and outcome broke, even if every delivery technically succeeded. Business checks catch the trap where a subscriber runs, reports success, and writes to the wrong record, which bus metrics alone cannot see.
Finally, alert on the right things and keep alerts actionable. Alert when a subscriber error rate crosses a threshold, when a dead letter queue gains entries, when a replay position falls far behind the newest event, and when an event type goes quiet during hours it should be busy. Each alert should name the event type, the subscriber, the last successful position, and a link to the logs, which are time ordered records of system activity. An alert that only says "something failed" sends an engineer hunting through logs at midnight. An alert that names the trap sends the engineer straight to the fix, and that difference decides whether a trap costs minutes or days.
Replay, Retention, and Recovery
Replay is the safety net that makes event systems forgiving, within limits. When a subscriber goes down for maintenance or crashes for an hour, it can resume from its saved position and reprocess the events it missed, in order, once it returns. Salesforce documents event subscription and replay options, including replay from a stored position. The key discipline is saving that position only after work completes, not before. A subscriber that saves its position first and then crashes will skip events it never processed, and no replay will bring them back, because the system believes they are done.
Retention sets the hard limit on replay. The bus keeps events only for a defined window, and events older than that window disappear. Teams must know their window and design around it: a subscriber outage longer than the window cannot be fixed by replay alone. For those cases, keep a recovery path that rebuilds state from source records, such as re-reading orders changed since a given time and republishing the derived events. Test that recovery path before you need it, because an untested recovery plan fails exactly when the team is already under pressure and short on sleep.
Recovery also needs a decision rule for duplicates. Replaying events after an outage can redeliver events the subscriber already processed before the crash, so idempotent handling from the duplicates section matters twice as much during recovery. Log every replay with its start position, end position, and item counts, and compare the replayed outcome counts with the business counts afterward. A recovery that nobody verifies can quietly create the duplicate trap it was meant to fix, and the team will discover the duplicates from customers, which is the worst possible reviewer.
Design Habits That Prevent Traps
Prevention beats monitoring, because monitoring only shortens a trap, while design avoids it. Keep events small and factual: one event should describe one thing that happened, with the identifiers a subscriber needs to fetch details, rather than a giant snapshot of everything that might matter. Small events stay stable when systems change, and stable events break fewer subscribers. Name events and fields clearly, version them when they change, and never reuse an old event name for a new meaning, because subscribers built for the old meaning will misread the new one with confidence.
Give every subscriber one clear owner and one clear outcome. A subscriber that updates shipping, billing, and analytics in one run becomes the single point where three traps can form at once, and no single owner feels responsible for all three outcomes. Split it into three subscribers, each owned by the team that cares about its outcome, each with its own error handling and its own alert. The bus makes splitting cheap, because the publisher never changes. Teams that resist splitting usually fear extra work, but they trade a small amount of extra code for a large amount of shared confusion later.
Document the contract for each event where developers actually look: the event name, the version, each field and its meaning, which systems publish it, which systems subscribe, the retention window, and the recovery path. A contract that lives only in one engineer's memory will break when that engineer leaves or goes on leave. Review contracts when a new subscriber joins, because each new subscriber adds a new way for the event to be misread. Salesforce Apex docs for platform events show the subscriber code patterns these habits support, and our guide to safe test spaces explains how to test subscribers without risking live data.
Platform Events Versus Triggers: Choosing the Right Tool
Teams sometimes reach for platform events when a simpler tool fits better, and that choice itself becomes a trap. A trigger, in Salesforce terms, is code that runs directly when a record changes, in the same transaction, which is a single unit of work that either fully succeeds or fully rolls back. Triggers suit work that must happen with the change, such as validation, which checks that data meets rules before saving, or updating a related record that the user expects to see at once. Events suit work that can happen later, across systems, or for many consumers at once, such as notifying a warehouse, a partner, and an analytics system about one order.
Use a trigger when the user needs an immediate result, when failure should block the original change, or when only one consumer needs the update. Use an event when several consumers need the news, when the follow up work can wait seconds or minutes, when the consumer lives outside Salesforce, or when the publisher should not wait for slow subscribers. Mixing these up creates traps in both directions: an event used for immediate validation lets bad data save before the check runs, while a trigger used for cross system work makes the user wait for every downstream system and fails the whole save when one downstream system hiccups.
A hybrid pattern serves many teams well. A trigger records the change and publishes an event in the same logical step, while subscribers handle the slow, cross system work separately. The user sees an immediate save, the downstream systems still get their news, and a subscriber failure never blocks the user. That pattern needs care around transaction boundaries, because an event published inside a rolled back transaction must not escape, but Salesforce handles that coupling for platform events published from triggers, which is one reason the platform pair works well together. Choose the tool by timing and by failure needs, not by fashion, and the trap count falls sharply.
Conclusion
A platform event trap is rarely a mysterious platform bug. It is usually a missing subscriber, a loop without a stop rule, a duplicate without idempotent handling, an ordering assumption the bus never made, or a retention window the team never measured. Each trap stays silent because publishers and subscribers do not share errors, so the fix is visibility by design: a subscriber registry, publish versus delivery alerts, business outcome checks, dead letter queues, replay discipline, and a tested recovery path. Build those habits before the first production event, and platform events stay what they should be: a flexible way to connect systems without coupling them into one fragile chain.
Frequently Asked Questions
What is a platform event trap?
A platform event trap is a failure pattern where a published platform event never reaches its intended work, loops without end, or stalls in a retry queue, while the sender believes the work succeeded. The trap is silent, so teams discover it from missing results, not from an error message.
What monitors platform event traps best?
The best monitoring combines published counts, delivered counts, subscriber error logs, and an alert on the gap between published and completed work. Dashboards alone miss traps, so pair them with a business check, such as counting orders that reached fulfillment, and alert when that count falls behind.
Can a subscriber replay a missed platform event?
Yes, within the retention window, which is the limited time the event bus keeps events, a subscriber can replay events from a saved position and reprocess the ones it missed. After the window closes, the team must rebuild the missed work from source records, because the events themselves are gone.
Written by Amir Iqbal
Senior AI Systems Architect and Lead Technical Reviewer
Amir Iqbal is a senior AI systems architect at Esaholic who leads production readiness checks for agents, model serving, and data systems before they reach real users.
Reviewed by Umar Abbas
Founder, Principal AI Architect and Operator
Umar Abbas is the founder of Esaholic and a principal AI architect who designs reliable large scale AI systems for regulated industries.
Relevant blogs
What Is a Sandbox Environment? A Simple Guide
How safe test spaces protect live systems, plus setup steps, types, and limits, in plain language.
API Design Principles: A Simple Guide for Teams
How to name resources, version safely, handle errors clearly, and document an interface that teams can trust.
Enterprise Application Integration Explained Simply
How companies connect their systems so orders, stock, and billing agree, without manual copying or fragile links.
Software Testing Basics: A Simple Guide for Teams
What testing means, the main types of tests, and how teams plan, run, and report tests without jargon.
Back to all blog guides · Back to Software Development guides · Explore Workflow Automation Services