When Salesforce Is the Wrong Choice (Yes, Really)
A few years ago I spent most of a week writing a proposal to make a Salesforce org run faster. Twenty-odd pages of skinny tables, custom indexing, an async redesign, the lot. On the Friday I deleted all of it and wrote a one-page recommendation instead. It said, more or less, that the workload in question should never have been on Salesforce, and no amount of tuning was going to change that. Nobody had hired me to say it, which is exactly why it needed saying.
I make my living on this platform. I've spent fifteen years inside it and I'll happily argue its corner in most rooms. But part of being an architect rather than an order-taker is telling a client when the thing they bought — or the thing they're about to buy — is the wrong tool for the job in front of them. Salesforce is very good at a specific shape of problem. When your problem is a different shape, it fights you the whole way, and the licence renewal makes the fight expensive.
The Question I Ask Before the Licences Get Bought
Before anyone signs an order form, I put the same distinction on the table. A system of engagement and a system of record-keeping at volume are two different problems, and Salesforce is built for only the first one.
A system of engagement is where people work. Sales reps chasing opportunities, service agents closing cases, an operations team coordinating a hundred moving parts a day. Humans, records they touch, process wrapped around them. That is Salesforce's home turf and nothing on the market does it better.
A system of record-keeping at volume is different. It's millions of events a day that no human will ever open individually, ingested from sensors or transactions or logs, aggregated into something someone eventually looks at. The moment I hear "we want to capture every single X," where X happens millions of times a day, my hand goes up. That is not a CRM problem wearing a disguise. It's a data platform problem, and Salesforce is the most expensive database you could possibly choose to solve it.
High Volume Is Where the Platform Fights You
The clearest example I've lived through was a logistics business that wanted every parcel scan in Salesforce. Every pickup, every depot handover, every failed delivery attempt — one record each. The pitch made sense on a whiteboard. Full traceability, everything in one place, reports the ops managers already knew how to build.
The reality was roughly 4.3 million scan events a day. They'd built a Scan_Event__c object and were writing to it through the REST API, and the nightly rollup batch they'd inherited looked like this:
global Database.QueryLocator start(Database.BatchableContext bc) {
return Database.getQueryLocator(
'SELECT Id, Parcel__c, Scanned_At__c, Location__c, Status__c ' +
'FROM Scan_Event__c ' +
'WHERE Rolled_Up__c = false'
);
}
By the time I saw it, that batch had stopped finishing inside its window. The unprocessed backlog grew faster than a single batch job could chew through it, the Rolled_Up__c filter wasn't selective once tens of millions of rows sat behind it, and they were buying additional data storage at a rate that made the CFO physically wince. No trigger framework, no query rewrite, no clever SOQL selectivity work was going to fix a model where the platform was being asked to be a high-throughput event store. It simply isn't one.
What the ops managers actually needed was never the four million raw rows. It was this:
SELECT parcel_id, COUNT(*) AS scan_count, MAX(scanned_at) AS last_seen, MAX(status) AS current_status
FROM scan_event
WHERE scanned_at >= CURRENT_DATE - INTERVAL '1 day'
GROUP BY parcel_id;
An aggregate that a cheap columnar warehouse answers in under a second and Salesforce charges you a fortune to even store. So we moved event ingestion off-platform entirely, kept the raw stream in the warehouse, and synced only per-parcel summaries back into Salesforce as a single Parcel__c record with rollup fields. Something like a few hundred thousand upserts a night instead of four million inserts:
List<Parcel__c> summaries = ParcelSummaryService.buildFromWarehouseFeed(feed);
Database.upsert(summaries, Parcel__c.External_Id__c, false);
I'll be honest about the ending, because the voice guide of my own head insists on it: we didn't get it clean. The warehouse pipeline was owned by a different team on a different roadmap, the sync lagged by up to an hour on bad days, and for the first six months there were two sources of truth that occasionally disagreed. We shipped it anyway because the alternative was the batch never finishing at all. It's been running for a couple of years now with a monitoring dashboard bolted to the side. Nobody's proud of it. It works.
Per-Seat Pricing for a Per-Transaction Problem
The other place Salesforce turns out to be the wrong choice is economics, and this one catches people who've already fallen in love with the platform.
Salesforce prices per seat. That model is fair and predictable when your users are employees doing high-value work — a service agent on a full licence is cheap relative to what they produce. It falls apart the moment your "users" are hundreds of thousands of external people doing something low-value and occasional.
I watched a member-based organisation try to build a self-service portal on Experience Cloud for roughly 140,000 members who logged in maybe twice a year to update a detail or download a statement. The internal case looked wonderful — reuse the existing org, one platform, one security model. Then someone did the licensing arithmetic across that many external identities and the number came back higher than building a bespoke portal from scratch and running it for a decade. For a login-twice-a-year interaction, you're paying platform rent on 140,000 people to serve maybe 3,000 of them on any given day.
This is the opinion I'll plant a flag on: if the interaction is high-volume, low-value, and external, Salesforce's pricing model is working against you by design, not by accident. The platform is optimised to be worth its seat cost for people who live in it eight hours a day. Occasional visitors break that assumption. We ended up building the public-facing portal on a lightweight stack and using Salesforce as the back office it's genuinely good at — the staff who administered memberships stayed on full licences, the members never touched the org at all.
Using Salesforce as a Database You Query Through a Straw
There's a subtler failure mode that isn't about volume or money. It's when a team picks Salesforce as a generic datastore because it's already there, then spends the next two years frustrated that it behaves like a CRM.
An admin named Ravi once showed me an org where the "product" was essentially a data-matching engine. It needed to run set operations across large reference tables, the kind of thing a relational database does in a single indexed join. On Salesforce he was orchestrating it through Batch Apex, chaining jobs, fighting the 50,000-row query ceiling, and stitching results together across async job boundaries that were never meant to carry that load. He'd become genuinely expert at a problem he should never have had.
The tell is always the same. When most of your engineering effort goes into working around the platform rather than building on it, the platform is wrong for that component. Salesforce gives you governor limits precisely because it's multi-tenant and it will protect its neighbours from your workload. Those limits are a feature when you're building CRM automation. They're a wall when you're trying to run a computation engine, and no framework I've ever written makes a wall feel like a door.
When It Is Still the Right Call
I'd be a poor architect if I let the contrarian take run unchecked, so here's the counterweight. Most of the time, for most of the businesses I work with, Salesforce is the right choice — and the reasons people pick it are usually sound.
If your problem is people and process — sales, service, field operations, anything where a human touches a record and something needs to happen next — the platform earns its cost many times over. The declarative tooling, the security model, the ecosystem of admins you can actually hire in Sydney, the fact that you're not maintaining a bespoke framework nobody else understands: all of that is real value that a custom build quietly forgets to price in. I've seen plenty of teams reject Salesforce to "save money" and rebuild half of it, badly, over three years. That failure mode is at least as common as the one I've been describing.
The honest position isn't Salesforce-always or Salesforce-never. It's Salesforce for the system of engagement, and something purpose-built behind it for the volume and the computation. The parcel client landed there. The membership organisation landed there. The best architectures I've worked on treat Salesforce as one deliberately chosen component with a clear boundary, not as the place where everything goes because it happened to be the platform someone bought first. If you're staring at an org that's fighting you and you're not sure whether the problem is the design or the platform itself, that's exactly the kind of review I do — sometimes the answer is a better trigger framework, and sometimes it's a much shorter proposal.
The trap is that Salesforce is capable enough to limp along with almost any workload for a while, which is precisely what makes the wrong choice so hard to unwind later.
The right platform makes the hard problems boring. The wrong one makes the boring problems hard, and by the time you notice, you've already renewed.
Liked this?
New essays in your inbox when I publish. No cadence, no spam.
You might also like
The 80/20 of Salesforce: The 20% of Features That Deliver 80% of Value
After fifteen years on the platform, the pattern is clear: a small set of unglamorous features carries almost all the value. Here's the 20% I protect first.
Read →The Real Cost of Salesforce Technical Debt
Technical debt on Salesforce has a real interest rate, and it compounds where you don't look. How I measure it, cost it, and decide what's worth paying down.
Read →15 Years on Salesforce: What I'd Tell My Day-1 Self
Fifteen years of Salesforce, ten orgs, three major platforms shifts, and a long list of mistakes. The lessons I'd pass back to the version of me who started in 2010.
Read →