Learn About Object Design-Time Limits
- Describe object design-time limits.
- Identify the key object design-time limits.
- Implement techniques to avoid common object design-time limits.
What Are Object Design-Time Limits?
Let’s dig into object design-time limits. As you build out your app or customization, you are bound to encounter design-time limits that apply to individual objects. Your goal is to make design-time decisions that avoid as many of these as possible.
These limits do not vary per transaction. They are in place because each transaction would be slow if you exceeded them. Many of them involve the complexity they create in retrieving a record. Many involve the complexity of saving a record. And in some cases they are physical limitations, like data storage limits.
To put it in the words of our navigation theme, design-time limits are localized factors, like construction along the way. Take them into consideration while you’re planning your route. And as you encounter new ones, make adjustments to get where you’re going.
Key Object Design-Time Limits
Some limits are in place to keep records loading fast. These limits include the following.
- Cross-Object Formulas
- Cross-object formulas span two related objects and reference merge fields on those objects.
Cross-object formulas also work with lookup relationships. An example of a cross-object formula
is a custom account name field on a case object that uses a formula to get its value from
another object’s field, like the Contact.Account.Name field.
Every time you load an object—whether through the UI, in a workflow rule, or by an Apex trigger—Salesforce has to calculate all of the cross-object formulas. Each one of these cross-object formulas performs a join operation across another object data table. As the number of these joins increases, the complexity of the database transaction to retrieve the complete object increases. Translation: Loading gets really slow.
- VLookup Rules per Object
- VLookup rules help validate field values. Validation rules for a field can use the VLOOKUP() function to perform queries on name fields in custom objects. These are useful for verifying things like a ZIP code or whether a user already exists before creating a new one. Just like cross-object formulas, the more of these you have, the more calculations you’re requesting.
- Number of Values in a Picklist
- Picklists are a powerful way to load field values quickly. Users can accept defaults or pick a provided value. You can control the available values, but the number can get out of hand. You don’t want to show so many items that a user can’t find the right one. You can use record types to control the number of available values for a picklist depending on the user or situation. Record types centralize which values can be shown and whether a saved value is valid.
- Number of Filters per Report
- Slow reports can bog down report rendering and general org performance. Each filter adds another condition to the query. Use filters carefully and try to pick ones that don’t have to do a lot of data analysis. For example, use inclusive operators like equals instead of not equals, or starts with instead of contains. Generally, try to keep report filters simple. In the Resources section, we list some links to information for streamlining your reports and dashboards.
Sharing Rules and Calculations
Some limits are in place to keep sharing calculations snappy. Sharing calculations are part of retrieving (or being prevented from retrieving) a record. Their limits include the following.
- Number of Sharing Rules
- We limit the number of sharing rules to help Salesforce determine whether a record can be accessed quickly. Otherwise, you’re waiting around while Salesforce goes through all the potential sharing restrictions on a record through your entire sharing hierarchy.
- Number of Criteria-Based Sharing Rules
- Criteria-based sharing rules offer a lot of flexibility for managing access to data. However, with that flexibility comes increased complexity. Sorting through sharing rules can get very involved as your user base and object access complexity grows. You trade efficiency for the power of criteria-based sharing rules.
- Maximum Child Relationships
- The limit on maximum child relationships prevents data skew. Data skew happens when an object has a huge number of child records. Let’s say you are updating a large number of contacts under the same account in multiple threads. For each update, the system locks both the contact being changed and its parent account to maintain integrity in the database. Each lock is in place for a very short time. But when all the updates are trying to lock the same account, there’s a risk that an update can fail because a previous one is still holding the lock on the account. Data skew also slows down sharing calculations and record-locking management. (All the children want the attention of their parent now, now, now!)
By the Numbers
The complexity of processes simply tends to grow as you have more users and records. As demand grows, you need users to save records and not lose time. The following design-time limits ensure that users can save a record effectively.
- Number of active rules (workflow, assignment, escalation, and auto-assignment) per object ensures that your logic doesn’t get too out of hand. Salesforce must evaluate each rule. If the actions or triggers create new records, rules on those records must also be evaluated. These can create records, too. As your logic gets more complex, the time to save a record gets longer.
- Similarly, the number of filter criteria is capped to keep things simple.
- The number of nodes in a process is capped to prevent runaway logic.
- Ditto the active validation rules per object.
- The number of approval processes can also be a drain. Salesforce evaluates each one for each record every time the record is saved, to see if the approval process criteria are met (thus launching the approval process).
And, some limits are in place for structural reasons.
- The number of custom fields per object limit is bound by the underlying data storage mechanism.
- The limit on number of values in multi-select picklists is bound by the underlying storage as well.
How do you avoid hitting these limits?
Be smart about your relational data structure.
It’s not a good idea to have a single object containing all your fields—things like “Area 1 rep name,” “Area 1 rep phone,” “Area 2 rep name,” and so on. A relational data model lets you break up monolithic objects into logical structures and lets you avoid copying the same data in hundreds of places (where it can certainly get out of sync).
Don’t be too smart about your relational structure.
If you have too many sub-elements in a logical entity, you encounter a lot of the filter- and report-based limits that prevent overly complex queries. An overly complex data structure quickly runs you into overly complex queries.
Embrace the programmatic.
If you have so many rules that you’re encountering limits, it’s probably time to hire an Apex programmer. Apex can be much more efficient than the flexible rules engine we offer you. Once you’re past a certain threshold, it’s time to reap some of the benefits of scale on offer with the programmatic platform.
Don’t overuse standard objects.
If different teams decide they’re going to repurpose the account object for things that are “accounts” only if you squint really hard, they’re all drawing from the same pool of limits. These teams need to share, and each can end up with less to use. It’s time for a custom object.
Keep your sharing rules as simple as possible.
You can build an entire security model based on role hierarchy and the various team-based rules alone. But each rule slows down your processing a little bit. Too many rules adds up to a lot of time. Custom and criteria-based sharing rules are very powerful. Use them wherever the basic role and team-based security model is insufficient. But try the roles and team-based security model first.
Example: Use a Process Instead of a Formula
What happens when you encounter a limit in real time and you feel stuck? Sometimes you have to think on your feet. Let’s walk through a scenario.
You’re adding a new cross-object formula field to the Case object. You have 15 cross-object formulas already. You’re at your limit. But you notice a field on the Case object, Owner, which simply displays the owner of the parent account of the case. You have decided to replace this field with a new text field, Account Owner Name. A Process Builder action populates the field every time the parent account owner changes. Nice move!
Here are the steps you can take to perform this feat.
To keep this example simple, we’re updating the Case’s Account Owner Name field for any change to the Account record. In production, consider setting a condition to update the Account Owner Name field only when the Account.OwnerId value changes.
First, create a Text field (length 80 characters) on the Case object: Account Owner Name. For a refresher on how to create a field on an object, see the Data Modeling module .
Now, create the process.
- From Setup, enter Process Builder in the Quick Find box, then select Process Builder.
- Click New.
- Enter Account Owner Update on Cases for the process name. Press Tab to automatically enter the API name.
- For the process description, enter Update Account Owner Name Field on Cases whenever an associated Account record is added or changed..
- For The process starts when, select A record changes.
- Click Save.
- Click + Add Object.
- Select Account for the object type.
- In the Start the process section, select when a record is created or edited.
- Click Save.
Click + Add Criteria.
- Criteria Name: Account Change
- Select No criteria-just execute the actions!.
- Click Save.
In Immediate Actions, click + Add Action.
- Action Type: Update Records
- Action Name: Update Case Account Owner
- Record Type: Select a record related to the Account
- Enter and select Cases
- Click Choose.
- At Criteria for Updating Records, select No criteria—just update the records!.
- Field: Account Owner Name
- Type: Formula
- Value: Paste the following into the formula
[Account].Owner.FirstName &" "& [Account].Owner.LastName
- Click Use this formula.
- Click Save.
- Click Activate.
Finally, delete the old field on the Case object: Owner.