From an architect’s perspective, the first rule is simple: start with standard where possible. Salesforce’s out-of-the-box features are battle-tested, supported, and understood by admins across the ecosystem. Custom code should be the last resort, not the first instinct.

But what happens when standard doesn’t cover your use case?

Why Salesforce Account Teams fall short

Salesforce provides native team functionality for exactly three objects: Account, Case, and Opportunity. Account Teams let you assign users with specific roles and access levels. It’s elegant, declarative, and well-integrated with the platform.

The problem? Real businesses don’t stop at these three objects.

On a recent project, we needed team collaboration on Leads — sales pods working together on high-value prospects before conversion. Another client required team access on custom objects tracking complex approval workflows. A third needed temporary, time-boxed access for external consultants reviewing Campaign performance.

None of these scenarios fit the native model.

Building Apex Managed Sharing from scratch

When architects hit this wall, the instinct is to build. And technically, you can. Salesforce’s sharing model is programmable through Apex Managed Sharing. You create share records, assign access levels, manage the lifecycle.

Here’s what that looks like in practice:

  • Apex triggers to create and delete share records when team members change
  • Custom objects to store team membership (parent record, user, role, access level)
  • Custom UI because users need to actually manage their teams
  • Batch jobs for cleanup when team members leave or access expires
  • Owner sync logic to handle what happens when record ownership transfers
  • Governor limit management because share records count against SOQL and DML limits

I’ve built this. Multiple times. Each implementation took weeks, required ongoing maintenance, and inevitably had edge cases that broke in production.

The worst part? Every org that needs this functionality ends up building their own version. There’s no reusability, no shared learning, no standard approach.

The maintenance tax: living with custom __Share records

Building the initial solution is just the beginning. The real pain starts on day two — when you’re the one responsible for keeping it running.

Salesforce stores sharing grants in __Share objects (e.g., Lead__Share, CustomObject__Share). Every team member assignment creates a share record. Every removal deletes one. Sounds simple until you realize what can go wrong:

  • Debugging access issues is a nightmare. When a user says “I can’t see this record,” you’re digging through __Share records, role hierarchy, sharing rules, and territory management to figure out why. Share records created by Apex all show up with RowCause = 'Manual' unless you’ve set up custom Apex sharing reasons — and most implementations don’t bother.
  • User deactivation leaves orphans. When someone leaves the company and their user gets deactivated, their share records don’t automatically disappear. You end up with thousands of stale share records pointing to inactive users, slowly degrading query performance.
  • Org hierarchy changes break everything. A reorg moves a team to a different business unit. Suddenly the role hierarchy grants wider access than intended, and your custom share records may conflict with or duplicate what the hierarchy already provides. Good luck auditing that.
  • Recalculation timeouts. Large orgs with complex sharing models can hit Salesforce’s sharing recalculation limits. When you trigger a recalc — intentionally or not — it can run for hours and lock records in the process.
  • No audit trail by default. Salesforce doesn’t track changes to share records in the standard audit trail. When a user’s access disappears and nobody knows why, you’re left guessing. Was it a trigger? A batch job? A sharing rule recalc? Someone clicking a button?
  • Testing requires multiple users. You can’t verify sharing in a single-user sandbox session. Every test scenario needs you to log in as different users and validate visibility. Multiply that by the number of objects and access levels you support.
  • Governor limits compound. Each team member change fires DML on share records. Add five team members at once? That’s five share record inserts, plus the trigger logic, plus any cascading updates. In bulk operations — like data loads or mass transfers — you hit limits fast.

I’ve spent entire sprints just fixing edge cases in custom sharing logic. A user was both a team member and above the record owner in the role hierarchy — do you create a share record or not? A record gets transferred and the old owner’s share record needs to be downgraded, but the new owner’s team also needs rebuilding. Every combination generates a new scenario you didn’t think about during the initial build.

This is the maintenance tax. It’s invisible to stakeholders, hard to estimate in planning, and it never goes away.

Requirements for team sharing on custom objects

After building custom team sharing solutions across different projects, the requirements became clear:

  1. Any object support — standard or custom, if it supports sharing, teams should work
  2. Declarative setup — admins should configure, not developers
  3. Temporary access — time-boxed team membership with automatic expiration
  4. Owner sync — when record ownership changes, the Owner role should follow
  5. User-friendly UI — end users need to manage teams without admin intervention
  6. Scalable architecture — handle thousands of records without hitting limits

Building this properly is a significant investment. Maintaining it is an ongoing cost.

Team sharing without code: AppExchange alternative

This is exactly why we built Flexible Team Share at Tucario.

Instead of each org reinventing team sharing, FTS provides a managed package that handles all the complexity. Admins enable objects through a point-and-click wizard. Users manage teams through a clean interface. The platform handles share record lifecycle, temporary access expiration, and owner synchronization automatically.

It works with any object that supports Salesforce sharing — Leads, Campaigns, Orders, custom objects, whatever your business needs.

The app is currently in AppExchange security review. Stay tuned.

The architect’s takeaway

Start with standard. When standard doesn’t fit, evaluate existing solutions before building custom. The total cost of ownership for a managed package — even a paid one — is almost always lower than building and maintaining custom sharing logic.

Team collaboration shouldn’t require Apex skills. It should just work.