Stop Being Clever with Your Objects
I used to be proud of a really clever Salesforce build.
You know the kind: like a Swiss Army knife. One object, four record types, page layouts that swapped cleanly, and a validation rule set I could explain to anyone who asked. It did four jobs. Four things that didn't have much to do with each other, living in one place, and I thought that was restraint.
It wasn't restraint. It was four problems agreeing to share a room until one of them needed to move. The instinct behind that build is one I think most of us share, and it sounds like common sense. More objects means more complexity. So you keep the object count down, and you've kept the org simple.
Except that isn't where complexity comes from. Complexity comes from the number of jobs the org has to do. Those jobs exist whether or not you give each one its own object. Putting four of them on one object doesn't remove a single job. It just stops you from being able to see them separately.
And for a long time, we got away with it.
What’s Changed
When I was first building NPSP orgs, the thing that was actually scarce wasn't objects, it was automation. The guidance on Process Builder was roughly one per object (MAYBE two), and you felt that limit. But it also meant there wasn't much sitting on top of any given object. A few record types, some validation rules, a couple of page layouts. When your automation footprint is that thin, a fat object doesn't hurt; you could hold the whole thing in your head. The problem was always there, lying in wait. It just never sent you the invoice.
It does now.
There's more built on top of every object than there used to be. Flow made automation cheap, so we built more of it. Then integrations, then reporting people depend on, then AI reading the data, then surfaces nobody drew on a diagram. The object didn't change. The weight resting on it did.
So now you come in to adjust one small thing for one use case, and you're checking four layouts, six validation rules, and every flow with an entry condition on that object, trying to convince yourself you haven't broken something for a team you don't talk to everyday. Sometimes you don't find out you have. Someone else does, three weeks later, and by then nobody remembers the change.
Calling Out Our Mistakes
There's a name for what that kind of build got wrong, and it isn't from the Salesforce world at all.
Robert C. Martin calls it the Single Responsibility Principle, the first of the five SOLID principles. Developers have argued about it for twenty years, so the phrasing varies, but the version I find most useful is this:
A thing should have one, and only one, reason to change.
Notice what that isn't. It isn't a rule about size, and it isn't a rule about how many things an object does. An object can do quite a lot and still be sound, as long as everything it does would change together, for the same reason, prompted by the same person.
So the question I ask now isn't how many jobs is this object doing. It's this:
Would a change to one of these ever need to leave the others alone?
If the answer is yes, they don't belong together. That's the whole test.
Take it back to my clever build. Four jobs on one object. Would a change to one of them ever need to leave the other three alone? Constantly. That was the entire problem, and I could have found it in about thirty seconds if I'd known to ask.
What I like about this test is that it's answerable at design time, before you've built anything. You don't need to predict the future. You just need to know whether these four things have four different people who care about them.
Exceptions to the Rule
That test is sharp enough to cut things it shouldn't, so let me name two places it looks like you've got a violation and you don't.
The first is actually two standard objects: Case and Lead.
Both of those objects take input from everywhere. Web forms, email, integrations, a thin connector some vendor shipped maybe before it was fully baked. And if you count jobs, that looks like a flagrant violation. One object, a dozen sources, all sorts of different things arriving.
But look at why they're built the way they are. Case and Lead are deliberately unparented. Contact needs an Account. Opportunity needs an Account. Case and Lead need nothing, and that's not an oversight. It makes them cheap to create from anywhere, by anything, including systems that know almost nothing about your org. An integration can drop a record in and a Flow can turn it into whatever it actually needs to become.
That's actually one job, not twelve. The job is being a cheap front door. The variety lives downstream in what you do with the record, not in the object itself.
If the room is the image for the rest of this article, Case and Lead are the lobby. Everyone passes through the lobby. Nobody lives there. What breaks the test isn't a Case object that receives many kinds of intake. It's a Case object that has become the permanent home for four unrelated processes, each with its own lifecycle, its own team, and its own reasons to change.
The second exception is one I actually reach for a lot. One Survey object, with a Type picklist covering every flavor of survey the organization runs.
That passes, and it's worth being precise about why. It isn't because surveys feel similar. It's because they change together. Same lifecycle, same field set, same person asking for changes. Those questions may be worded differently over time, but the vast majority of organizations care about the same general facts because those data points are what matter to their mission or model. Further, it can grow. Add a question to one survey type and the others aren't threatened by it. They're all genuinely the same thing wearing different labels.
One caution, though, and I'll be honest that Survey is a sympathetic example. Somewhere in your org is an object that looks exactly like Survey from the outside and isn't. Two things that feel like siblings, but one of them belongs to Finance and the other to Programs, and the day Finance needs a change, Programs is in the blast radius. So run the test for your use case. Don't assume the answer because the names rhyme.
Which brings up record types, since that's what most of these patterns are built on. Record types aren't the villain here. When variants share one reason to change, record types are exactly the right tool. They only become the tell when they're papering over genuinely different reasons to change — when the record type isn't describing a flavor, it's hiding a separate process.
So why does the Swiss-Army-Knife Build keep happening?
In short: Because of how we evaluate orgs. Someone opens the object manager, sees a long list, and concludes the org is complicated. Someone else opens a shorter list and calls that one clean. I've done it. It's fast, it feels rigorous, and it's the wrong measurement.
Object count doesn't tell you how complex an org is. It tells you how honest the org is about what it does.
The real measure is coupling. How many things have to move when one thing moves. An org with forty purpose-built objects, each answering to one process, is far simpler to change than an org with fifteen objects where four of them are doing secret double duty. The second org looks tidier in the object manager. It is also significantly harder to work in.
And this is where that deferred cost comes due. Every job the organization does has a price, and you don't get to decide whether to pay it. You only get to decide where. Put it in the schema, and you pay it once, visibly, at design time, in an object you had to justify creating. Refuse to put it there, and it doesn't go away. It gets distributed into every change request for the next ten years, paid in small increments by whoever is holding the org at the time.
Usually that's someone who wasn't in the room when the decision got made.
Common Anti-Patterns
Let me give you the failure mode I see most: Opportunities.
I’ve seen admins build program applications on Opportunity. Not donations, not deals. Applications to a program, with stages like submitted, under review, accepted.
And I want to be generous about why, because the reasoning is genuinely appealing. The stages are already there. The pipeline reports are already there. It's an object about something you're trying to accomplish and may or may not accomplish, which is exactly what an application is. You get a working process in an afternoon instead of a week.
But you also get some baggage.
Opportunity is a revenue object. That's not a label, it's what the platform believes about it, and it's why Opportunity has forecasting horsepower nothing else has. Close Date doesn't mean the date this finished. It means the date revenue was won and recognized, whether that's a deal, a donation, or a grant. Amount carries a currency your application never had.
So you fill those fields in, because they're required (mostly) and because the form wants them. And now every pipeline report, every forecast, every roll-up on the Account quietly counts your program applications as money. Nobody decided that. Nobody even sees it at first. It just starts being true.
That highlights the rule underneath all of this. When you borrow a standard object, you inherit its semantics whether you want them or not. You can rename a field label. You cannot rename what the platform wants to do with it.
And it's the same reason my Survey object passes. I built it for surveys. Nothing in the platform has opinions about what it means.
Answering the Cost Objection
Now, I know what the objection is, because I've made it myself. Clean design means more objects, more objects means a bigger org, and a bigger org means someone comes back with a licensing quote nobody wants to sign.
It doesn't have to work that way. Purpose-built custom objects are reachable by Platform licenses in a way that Opportunity, Lead, Case and Campaign simply aren't. So the org that puts each job in its own object often has options the clever org gave up years ago, without even knowing it was giving up anything. That's a longer conversation than I can have here, and I'll have it properly another time. But don't let the fear of a bigger bill push you into a design that costs you more.
One last thing, and it's bigger than objects.
The same test works on everything else you build. A Flow that fires on three unrelated conditions has three reasons to change. An approval process that serves two departments answers to two people. A field that means one thing for one record type and something else for another is actually two fields wearing one API name.
Objects are just where it shows up first, because objects are the part everyone can see.
Monday Morning Takeaway
So here's what I'd ask of you.
The next time you're about to add a fifth job to an object that's already doing four, don't count objects. Ask the one question. Would a change to any one of these ever need to leave the others alone?
If the answer is yes, you already know. Give it its own room.