salesforce-object-design
This skill should be used when the user asks to "design custom objects in Salesforce", "create custom objects in SFDC", "Salesforce object architecture", "when to use custom objects in Salesforce", "Salesforce data model design", "custom object best practices Salesforce", "design Salesforce schema", "custom object vs custom field Salesforce", "Salesforce object relationships", or any variation of designing custom objects and data architecture in Salesforce for B2B SaaS.
Salesforce Object Design
Custom objects in Salesforce extend the data model beyond standard objects (Leads, Contacts, Accounts, Opportunities). They store data that doesn't fit standard objects: product usage events, partner records, subscription data, or custom scoring models. Good object design keeps data organized, queryable, and reportable. Bad object design creates a spaghetti data model that nobody can navigate.
The principle: use standard objects for standard data. Only create custom objects when standard objects genuinely can't hold the data you need. Every custom object adds maintenance, permission management, and reporting complexity. Earn the complexity.
When to Create a Custom Object
Decision framework
| Question | If yes | If no |
|---|---|---|
| Does this data naturally belong on Lead, Contact, Account, or Opportunity? | Add a custom field to the standard object | Consider a custom object |
| Will this data have multiple records per parent? (1-to-many) | Custom object (e.g., multiple subscriptions per account) | Custom field on the parent |
| Does this data need its own page layout and record type? | Custom object | Custom field |
| Will multiple standard objects reference this data? | Custom object with lookup relationships | Custom field on one object |
| Do you need to report on this data independently? | Custom object (reportable as its own entity) | Custom field |
When to use standard objects instead
| Data | Standard object | Why not custom |
|---|---|---|
| Prospect info before qualification | Lead | Leads are designed for this. Don't create "Prospect" custom object |
| Company information | Account | Accounts handle company data natively |
| Deal data | Opportunity | Opportunities have built-in pipeline features |
| Support interactions | Case | Cases have built-in escalation and SLA features |
| Meeting notes | Activity (Task/Event) | Activities associate to contacts and opportunities natively |
Object Design Rules
Naming conventions
| Rule | Example | Anti-pattern |
|---|---|---|
| Singular noun | "Subscription" not "Subscriptions" | Plural names confuse relationships |
| No abbreviations | "Product_Usage_Event__c" not "PUE__c" | Nobody remembers what PUE means in 6 months |
| Prefix with namespace if using packages | "myapp__Subscription__c" | Unprefixed objects conflict with other packages |
| Label matches API name (minus suffix) | Label: "Subscription", API: "Subscription__c" | Label: "Sub", API: "Customer_Subscription_Record__c" |
Field design on custom objects
- Every custom object needs a clear record name. The "Name" field should uniquely identify the record. For a Subscription object: "Account Name - Plan Name" as an auto-number or text formula
- Include a lookup to the parent object. Every custom object should relate to a standard object. Subscription → Account. Usage Event → Contact. The relationship enables reporting and navigation
- Add created/modified timestamps. Salesforce provides these automatically, but add custom date fields for business events: "Subscription Start Date," "Renewal Date"
- Minimize required fields. 3-5 required fields per object. More than that and users avoid creating records. The data stays in spreadsheets instead of Salesforce
Relationship types
| Type | When to use | Example |
|---|---|---|
| Lookup | Optional relationship. Child can exist without parent | Contact → Custom "Project" object |
| Master-Detail | Required relationship. Child can't exist without parent. Cascading delete | Subscription → Account (subscription can't exist without an account) |
| Junction object | Many-to-many relationship | Contact-to-Campaign (a contact can be in many campaigns) |
Relationship rules
- Use Master-Detail when the child record has no meaning without the parent. A subscription without an account is meaningless. Use Master-Detail. Cascading delete ensures orphan records don't pile up
- Use Lookup when the relationship is optional or the child serves multiple parents. A project might relate to an account OR a contact, but not always both. Use lookups
- Limit to 2 lookup relationships per object. More than 2 and the object becomes hard to navigate. If you need more, reconsider the data model
Common Custom Objects for B2B SaaS
Subscription / Plan
Object: Subscription__c
Parent: Account (Master-Detail)
Fields:
- Plan_Name__c (text)
- MRR__c (currency)
- Start_Date__c (date)
- Renewal_Date__c (date)
- Status__c (picklist: Active, Churned, Paused)
- Seats__c (number)
Purpose: Track subscription data separately from opportunities
Product Usage Event
Object: Usage_Event__c
Parent: Contact (Lookup)
Fields:
- Event_Type__c (picklist: Login, Feature_Used, Integration_Connected)
- Event_Date__c (datetime)
- Feature_Name__c (text)
- Session_Duration__c (number, minutes)
Purpose: PQL scoring based on product behavior
Partner Record
Object: Partner__c
Parent: Account (Lookup)
Fields:
- Partner_Type__c (picklist: Referral, Reseller, Technology)
- Partner_Tier__c (picklist: Gold, Silver, Bronze)
- Revenue_Shared__c (currency)
- Active__c (checkbox)
Purpose: Track partner relationships and revenue separately
Reporting on Custom Objects
Report type setup
- Create a custom report type for every custom object. Standard report types don't include custom objects. Go to Setup → Report Types → New to create one
- Include related objects in the report type. "Accounts with Subscriptions" lets you report on subscription data alongside account data
- Test the report type before deploying. Build a sample report using the custom report type. If you can't build the report you need, the report type or object design is wrong
Reporting rules
- If you can't report on it, it shouldn't be a custom object. The primary reason to create a custom object is structured, reportable data. If the data is just for reference, use a custom field or attachment
- Create at least 2 standard reports per custom object. A list view and a summary report. This validates the object design works for reporting and gives users starting templates
Measurement
| Metric | Definition | Target | Frequency |
|---|---|---|---|
| Custom object count | Total custom objects in org | < 15 (for most orgs) | Quarterly |
| Record creation rate | New records per object per month | Objects with 0 new records may be unused | Quarterly |
| Field fill rate | % of required fields populated | > 90% | Monthly |
| Orphan record rate | Records without required parent associations | 0% | Monthly |
| Report type coverage | Custom objects with associated report types | 100% | Quarterly |
Pre-Creation Checklist
- [ ] Confirmed data doesn't fit a standard object (Lead, Contact, Account, Opportunity)
- [ ] Data requires multiple records per parent (1-to-many relationship)
- [ ] Object name is a singular noun, no abbreviations
- [ ] Relationship type chosen (Master-Detail or Lookup) with justification
- [ ] Required fields limited to 3-5
- [ ] Record name field uniquely identifies each record
- [ ] Custom report type created and tested
- [ ] Page layout designed for the primary use case
- [ ] Permissions set (which profiles can create/read/edit/delete)
- [ ] At least 2 standard reports created using the custom object
- [ ] Documentation written (what the object stores, who owns it)
Anti-Pattern Check
- Creating custom objects for data that belongs on standard objects. A "Prospect" custom object when Leads exist. A "Client" custom object when Accounts exist. Use standard objects first. They have built-in features you'd have to rebuild from scratch
- 30 custom objects. Maintenance nightmare. Every permission change, deployment, and report involves custom objects. Most B2B SaaS orgs need 5-10 custom objects. More than 15 is a red flag
- No report type for the custom object. You created the object but can't report on the data. The object exists but provides no visibility. Create the report type before deploying the object
- Custom object with 1 record. You created a "Configuration" object with exactly one record. That's not a custom object. That's Custom Settings or Custom Metadata. Use the right tool
- Orphan records everywhere. Master-Detail cascading delete wasn't used. The parent account was deleted. 500 subscription records now have no parent. Use Master-Detail for records that can't exist independently
- No naming convention. Objects named "Tracker," "Data_Thing__c," "Bob_Custom_Obj__c." Six months later, nobody knows what they store. Use descriptive, consistent naming from the start
Want agents that use skill files like this?
We customize skill files for your brand voice and methodology, then run content agents against them.
Book a call