Integration patterns for Salesforce: request-reply vs fire-and-forget, and how to choose

Written by

in

Every Salesforce integration decision eventually comes down to one question: does the calling system need to wait for an answer, or can it fire something off and move on? Get this wrong early and you’ll spend months untangling timeouts, retries, and support tickets nobody can quite explain.

Two patterns, one real difference

Request-reply is the pattern most developers reach for first, because it matches how a function call feels. System A sends a request, waits, and gets a response before doing anything else. A callout to a payment gateway during checkout is the obvious example: the customer is sitting there, and the outcome of that call changes what happens next on screen.

Fire-and-forget flips that. System A sends the message and carries on immediately, trusting the receiving system to process it on its own schedule. A case gets created in Salesforce and a message goes out to a reporting warehouse. Nobody’s waiting on that. Whether it lands in four seconds or four minutes, nothing in the user’s experience changes.

The mistake I see most often isn’t picking the wrong pattern outright. It’s defaulting to request-reply because it’s easier to reason about, then bolting synchronous behaviour onto a use case that never needed it.

When request-reply earns its place

Use it when the caller genuinely can’t proceed without an answer. Three situations come up again and again in the orgs I’ve worked on:

  • The user is waiting on screen and the next action depends on the result, like an address validation lookup during a form submission.
  • The transaction needs to succeed or fail as a unit. If the callout fails, the whole operation should roll back rather than leave Salesforce in a half-updated state.
  • The volume is low enough that a synchronous call won’t create contention. A handful of callouts a minute from a support console is fine. Ten thousand an hour from a bulk data load is a different problem entirely.

Governor limits make the tradeoffs sharper on this platform than on most others. A synchronous callout inside a trigger context ties up an Apex transaction for the length of that call, and Salesforce caps both the number of callouts per transaction and how long the whole thing can run. Push too much synchronous integration into high-volume automation and you’ll hit those ceilings during your busiest hour, which is exactly when you can least afford it.

When fire-and-forget is the better call

Anything that doesn’t block a user and doesn’t need an immediate answer is a candidate. Order confirmations to a fulfilment system, audit events to a logging platform, sync jobs keeping a marketing database current. None of these need Salesforce to sit around waiting for a reply.

Platform Events exist precisely for this. Publish an event, let subscribers pick it up on their own timeline, and Salesforce moves on without holding a transaction open. I worked through this exact shift on an order fulfilment process that had been running as a few scheduled batch jobs a day. Moving the trigger to a published event, picked up by an integration layer processing it in near real time, cut the delay between order and fulfilment from hours to seconds, and it did that without adding a single synchronous callout to the org.

The catch is that fire-and-forget trades certainty for throughput. You lose the immediate feedback loop. If the receiving system is down, you need a retry strategy, a dead-letter approach, or some way of noticing that messages are piling up unprocessed. Teams that adopt async patterns without building that visibility find out about failures weeks later, when someone finally asks why a batch of orders never reached the fulfilment system.

A middle ground worth knowing

Not every integration sits purely on one side. A common pattern is fire-and-forget with a callback: publish the event, keep working, and let the receiving system call back into Salesforce (through a Platform Event, an outbound message, or a REST callout of its own) once it’s done. You get the throughput of async processing with an eventual confirmation loop, at the cost of more moving parts to monitor.

A decision framework that actually holds up

When I’m scoping an integration, I ask these in order:

Does a human need the answer right now?

If yes, request-reply. If the answer only matters to a downstream system or a report, look at async first.

What happens if the external system is slow or down?

A synchronous call that times out fails the whole transaction in front of the user. An async message that fails can retry quietly in the background. If a brief outage on the other end shouldn’t be visible to your users, don’t build a synchronous dependency on it.

What’s the expected volume, and what’s the peak?

Design for the peak, not the average. A pattern that copes fine at fifty calls an hour can fall over completely at five thousand during an end-of-month run or a campaign spike.

Does this need to be transactionally consistent with the record change?

If the external system’s state has to match the Salesforce record at every moment, that pulls you toward synchronous, transactional design, with all the governor limit constraints that come with it. If eventual consistency is good enough, async buys you resilience and scale you’d otherwise have to build by hand.

The pattern you pick becomes the constraint you live with

This decision rarely stays contained to one integration. Once a team defaults to synchronous callouts because that’s what the first integration used, every automation built after it inherits the same assumption, and the governor limit pressure compounds. I’ve seen orgs where a dozen separate synchronous integrations were each individually reasonable, and collectively meant the org was one busy afternoon away from hitting API limits.

Before building the next integration, ask whether anyone is actually waiting on the other end. Most of the time, the honest answer is no. Designing for that reality from the start costs far less than re-architecting it once the org has grown around the wrong assumption.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *