Skip to content

The Reversed Arrow

Module 1 of 8 in the chapter Events, chapter 11 of the Integration Architect course. Each module stands on its own. Next: The Event Bus and the Pub/Sub API

The question this module answers: When Salesforce publishes an event, who is actually doing the work, and which way does the arrow point?

At Steve Trucking, a delivery’s status changes, and Redrock needs to know. There are three ways to get that news across, and the difference between them is who makes the call.

1. Salesforce calls out. Salesforce calls Redrock’s webhook with the status. To do that, it has to know Redrock’s number, hold Redrock’s credential, and decide what to do when Redrock doesn’t answer: wait, call back later, give up. That’s a callout. Chapter 9 is that world, and it has its place.

Three ways to get the news Three ways to get the news, the same status going to Redrock, one per row. 1, a callout: Salesforce, which knows Redrock's number, holds the credential and retries, calls Redrock's webhook with the status; the webhook has to answer when Salesforce calls. 2, polling: the integration layer calls Salesforce every 30 seconds to ask, then calls Redrock; Salesforce answers "Anything changed?", and mostly the answer is no; the arrow points into Salesforce, labelled calls again and again. 3, subscribing, highlighted: the integration layer calls once and stays on the line, and calls back if it drops; Salesforce tells it each change, the moment it happens; the arrow points into Salesforce, labelled an open line, changes come right away. The legend: highlighted is the subscriber; it dialed, so it keeps the line open and calls back. Underneath: an arrow starts at whoever dials; with an event, the subscriber dials and stays on the line, even though the news comes out of Salesforce. SALESFORCE THE OTHER SIDE 1. Salesforce calls out knows Redrock's number, holds the credential, retries Redrock's webhook has to answer when Salesforce calls calls with the status An arrow starts at whoever dials. With an event, the subscriber dials and stays on the line, even though the news comes out of Salesforce. HOW TO READ IT The subscriber: it dialed, so it keeps the line open and calls back © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

A callout: Salesforce makes the call.

2. They keep calling to ask. The other way round: the integration layer calls Salesforce every 30 seconds. Does anything change? Does anything change? Does anything change? Most of the time the answer is no, and every one of those calls is spent anyway. And when something does change, the news waits until the next call comes. That’s polling. In class I used to describe the event bus as the other system driving to my house to pick up its packages. But that’s this: coming over again and again to ask.

Three ways to get the news Three ways to get the news, the same status going to Redrock, one per row. 1, a callout: Salesforce, which knows Redrock's number, holds the credential and retries, calls Redrock's webhook with the status; the webhook has to answer when Salesforce calls. 2, polling: the integration layer calls Salesforce every 30 seconds to ask, then calls Redrock; Salesforce answers "Anything changed?", and mostly the answer is no; the arrow points into Salesforce, labelled calls again and again. 3, subscribing, highlighted: the integration layer calls once and stays on the line, and calls back if it drops; Salesforce tells it each change, the moment it happens; the arrow points into Salesforce, labelled an open line, changes come right away. The legend: highlighted is the subscriber; it dialed, so it keeps the line open and calls back. Underneath: an arrow starts at whoever dials; with an event, the subscriber dials and stays on the line, even though the news comes out of Salesforce. SALESFORCE THE OTHER SIDE 1. Salesforce calls out knows Redrock's number, holds the credential, retries Redrock's webhook has to answer when Salesforce calls 2. Salesforce answers "Anything changed?" Mostly, no The integration layer polls calls every 30 seconds to ask, then calls Redrock calls with the status calls again and again An arrow starts at whoever dials. With an event, the subscriber dials and stays on the line, even though the news comes out of Salesforce. HOW TO READ IT The subscriber: it dialed, so it keeps the line open and calls back © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Polling: the integration layer keeps calling to ask.

3. They call once and stay on the line. Here’s what’s different about the event bus. The integration layer calls Salesforce once, signs in, says which news it wants, and doesn’t hang up. The line stays open. The moment a status changes, Salesforce tells it, in milliseconds or seconds, on the line that’s already open. No wasted calls, no news waiting for the next one. Then the integration layer calls Redrock’s webhook itself.

Three ways to get the news Three ways to get the news, the same status going to Redrock, one per row. 1, a callout: Salesforce, which knows Redrock's number, holds the credential and retries, calls Redrock's webhook with the status; the webhook has to answer when Salesforce calls. 2, polling: the integration layer calls Salesforce every 30 seconds to ask, then calls Redrock; Salesforce answers "Anything changed?", and mostly the answer is no; the arrow points into Salesforce, labelled calls again and again. 3, subscribing, highlighted: the integration layer calls once and stays on the line, and calls back if it drops; Salesforce tells it each change, the moment it happens; the arrow points into Salesforce, labelled an open line, changes come right away. The legend: highlighted is the subscriber; it dialed, so it keeps the line open and calls back. Underneath: an arrow starts at whoever dials; with an event, the subscriber dials and stays on the line, even though the news comes out of Salesforce. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.57.1", "built": "2026-11-03", "id": "DGM-INT-EV-01", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "cells 0.5.0", "theme": "stevetecharc 1.4.0"} SALESFORCE THE OTHER SIDE 1. Salesforce calls out knows Redrock's number, holds the credential, retries Redrock's webhook has to answer when Salesforce calls 2. Salesforce answers "Anything changed?" Mostly, no The integration layer polls calls every 30 seconds to ask, then calls Redrock 3. Salesforce tells it at once each change, the moment it happens The integration layer subscribes calls once and stays on the line; calls back if it drops calls with the status calls again and again an open line; changes come right away An arrow starts at whoever dials. With an event, the subscriber dials and stays on the line, even though the news comes out of Salesforce. HOW TO READ IT The subscriber: it dialed, so it keeps the line open and calls back © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Subscribing: one call, kept open, and the news comes the moment it happens.

That’s publish and subscribe. Salesforce publishes the news; whoever is on the line hears it. It’s the design the Data Architect course drew for the same status, with a return receipt on top (Proof of Delivery). For anyone dialing in today, Salesforce’s guidance is plain: “Use the Pub/Sub API for any future publish/subscribe patterns instead of building your own event handlers using other APIs, including the Streaming API” (Event-Driven Architecture (opens in a new tab), Salesforce Architects, checked 2026-11-07). The older ways onto the bus, PushTopics and the Streaming API’s CometD clients, are chapter 17 (coming soon)‘s story.

A call that stays open for hours is fragile. The internet wasn’t built for long calls. Networks restart, connections time out, a server along the way gets patched. So both sides keep the line alive. When nothing is happening, Salesforce sends a small “still here” message at least every 270 seconds; and when the subscriber has had everything it asked for, it has to ask for more within 60 seconds, or the call ends (Flow Control (opens in a new tab), Pub/Sub API Developer Guide, checked 2026-11-07).

And sometimes the line drops anyway. When it does, who calls back? The one who dialed, the same as in chapter 2. Salesforce doesn’t call the subscriber back: it doesn’t even have the number. Salesforce’s guide says it in its own words: when an error stops the call, “the Pub/Sub API service closes the streaming connection. To create a new streaming connection, you must retry,” and it recommends waiting a little longer between each try (Retry Long-Lived RPC Calls After an Error Occurs (opens in a new tab), same guide, checked 2026-11-07).

Here’s what makes the event bus better than an ordinary phone call. Salesforce numbers every message, and keeps them for a while. So when the subscriber calls back, it doesn’t have to say “start over.” It can say “the last one I heard was number 11,” and hear everything since. How far back it can ask, and the three ways to pick up again, are module 4.

In chapter 2, we called it a tango: the client has its moves and the server has its moves, and neither can dance the other’s part. The client knows the address, signs in, owns the round trip and retries. The server makes itself available and answers.

When a flow publishes onto the event bus, all of a sudden I no longer need the connection string, the named credential, the try and the catch. I’ve shifted the onus onto the subscriber. The subscriber needs to know how to call Salesforce, not Salesforce needing to know how to call the subscriber. We’ve taken the client–server responsibility grid and flipped it.

The tango, flipped The tango, flipped: two equal panels. The subscriber's moves, the one that dials in: signs in to Salesforce; dials in, and names the channel it wants; says where to start, new events or from one it already has; stays on the line, and calls back when it drops; catches up on what it missed, within the window; handles its own errors and retries, and delivers onward. Salesforce's moves, the publisher: publishes the event and moves on; no address, no credential, no try and catch for this; keeps each event for the retention window; tells whoever is on the line, as each change happens; doesn't know who received them, or when; a light drag on its own processing. Underneath: chapter 2's client moves, now the subscriber's; Salesforce publishes; whoever dials in does the rest. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.57.1", "built": "2026-11-03", "id": "DGM-INT-EV-02", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "comparison/side-by-side 0.5.0", "theme": "stevetecharc 1.4.0"} The subscriber's moves the one that dials in Signs in to Salesforce. Dials in, and names the channel it wants. Says where to start: new events, or from one it already has. Stays on the line, and calls back when it drops. Catches up on what it missed, within the window. Handles its own errors and retries, and delivers onward. Salesforce's moves the publisher Publishes the event and moves on. No address, no credential, no try and catch for this. Keeps each event for the retention window. Tells whoever is on the line, as each change happens. Doesn't know who received them, or when. A light drag on its own processing. Chapter 2's client moves, now the subscriber's. Salesforce publishes; whoever dials in does the rest. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Chapter 2’s tango, with the client’s moves handed to the subscriber.

So the subscriber signs in, dials in, names the channel it wants, says where to start, stays on the line, and calls back when it drops. If there’s a problem in the connection, the subscriber does the reconnect, and it controls the retries and where it picks up again. Salesforce publishes the event, keeps it for a while, and tells whoever is on the line.

I call that a light drag on Salesforce. When MuleSoft, or any integration layer, is the subscriber, the processes inside Salesforce never make a callout. No flow or trigger is waiting on another system. They just publish the event and move on.

Two of the subscriber’s moves have their own modules. Where it starts, and how it catches up on what it missed, is module 4. How many events can go out to subscribers outside Salesforce in a day is module 5.

Why So Many People Get the Arrows Reversed

Section titled “Why So Many People Get the Arrows Reversed”

Now look at the third row again. The status leaves Salesforce and ends up at Redrock. So most people draw the arrow from Salesforce outward. It’s still an outbound notification, after all.

But an arrow on a landscape doesn’t show which way the data goes. It shows who starts the call (chapter 5). And with an event, Salesforce doesn’t start anything. The subscriber dials in and stays on the line to hear them. That’s why so many people get their arrows reversed. They think “messages out”, but the subscriber is the one that called. The clients connect in, data goes out.

So draw it the way it runs: the arrow from the integration layer into Salesforce, with a label that says what comes back, “subscribes: status events”. Then the integration layer’s own arrow out to Redrock. Two connections, two arrows, and each one starts where the work starts. Chapter 7 warned you about this one: a push that isn’t quite a push.

It matters for more than a tidy diagram. The arrow tells you who owns the retry, who needs the credential, who has to keep the line open at 2 a.m., and whose logs to read when something’s missing. Draw it backwards, and you’ll go looking for the problem in the wrong system.

Here’s a way to see it. Take one business need: when a record changes, another system has to know. Salesforce gives you several ways to build that, and they all send the news outbound. What changes is who drives:

How you build itWho opens the connectionWho owns the retry
A flow or Apex calls out (an HTTP callout, External Services, an invocable action)SalesforceSalesforce
An outbound messageSalesforceSalesforce
A flow or Apex publishes a platform eventThe subscriberThe subscriber
Change Data Capture publishes the changeThe subscriberThe subscriber

The first two are chapter 9 (the ways out, and outbound messages). The last two are this chapter. Same outbound news, but in the last two rows the arrow points in.

What you get:

  • Salesforce stays light. No credential, no endpoint, no retry logic in your flows for this. Publish and move on.
  • The systems don’t have to know about each other. Salesforce doesn’t know who’s listening. A new subscriber can start listening next year without anyone touching the publisher (chapter 7).
  • A subscriber can be away and catch up. Salesforce keeps the events for a while, so a subscriber that was down can come back and ask for what it missed (module 4).

What you take on:

  • Someone has to run the subscriber. All the time. An integration layer like MuleSoft, or a program of your own, signed in and on the line. That’s a box on your landscape with an owner.
  • Salesforce doesn’t know whether it arrived. It published the event. It doesn’t know who received it, or when, or whether Redrock got the status in the end. If you need to know, you build the proof yourself: the Data Architect course’s return receipt.
  • Deliveries outside Salesforce are counted. How many events can leave Salesforce in a day is limited, and every subscriber counts (module 5).

For a subscriber dialing in today, the line is the Pub/Sub API, Salesforce’s modern way onto the event bus, built on gRPC and HTTP/2, carrying each event in binary Apache Avro (Get Started (opens in a new tab), Pub/Sub API Developer Guide, checked 2026-11-07). That’s module 2.

Test knowledge. Know that in publish and subscribe, the publisher doesn’t know its subscribers and doesn’t call them: the subscriber connects in, names the channel and says where to start, and it owns reconnection, catching up and error handling. Know that Salesforce recommends the Pub/Sub API for new publish and subscribe designs, and platform events or Change Data Capture for record changes, not PushTopic or generic events. Know the older door by name: the Streaming API uses the Bayeux protocol and CometD for long polling (Getting Started with Streaming API (opens in a new tab), checked 2026-11-07).

  • For each outbound need: call out, or publish. Who should own the connection and the retry: Salesforce, or the system that needs the news?
  • Who the subscriber is, and who keeps it on the line, all the time: an integration layer, or a program of your own. Put it on the landscape, with an owner.
  • Which way the arrows point. From the subscriber into Salesforce, labelled with what comes back; then the subscriber’s own arrows onward.
  • How you’ll know it arrived, when the business needs to know: a return receipt, or a check on the other side.
  • Which door the subscriber uses, and how it calls back when the line drops: for new work, the Pub/Sub API; the older doors only where they already run.