A self-relationship (or self-lookup) is a relationship field on an object that points back to the same object. The most common shape is a Lookup, but you can technically also do self-master-detail (rare and tricky). Self-relationships model hierarchies, predecessors, parent-child structures, and tree-like data — all within one entity.
Canonical example: Account.ParentId
The standard Account object ships with ParentId, a self-lookup pointing back to Account. This is how you build a corporate hierarchy:
Acme Corp (top)
├── Acme North America (Parent = Acme Corp)
│ ├── Acme USA (Parent = Acme North America)
│ └── Acme Canada (Parent = Acme North America)
└── Acme Europe (Parent = Acme Corp)
├── Acme UK
└── Acme Germany
The “View Hierarchy” button on Account uses ParentId to traverse and display the tree.
Other common self-relationship patterns
- Position__c → Position__c (Reports_To) — corporate org chart on a custom Position object
- Task__c → Task__c (Depends_On) — project task dependencies / predecessors
- Knowledge_Article__c → Knowledge_Article__c (Supersedes) — version chain
- Folder__c → Folder__c (Parent_Folder) — nested folder structure
- Category__c → Category__c (Parent_Category) — N-level taxonomy
How to create one
- Open the object (
Position__c). - Add a new field of type Lookup Relationship.
- In “Related To,” pick the same object (
Position__c). - Field label: e.g., “Reports To”; API name:
Reports_To__c. - Configure the related-list label that will appear on the parent (e.g., “Direct Reports”).
- Save.
Now each Position can reference another Position as its parent. The “Direct Reports” related list on a Position shows its children automatically.
Self master-detail — possible but watch out
You can create a master-detail to the same object, but you should think carefully:
- Cascade delete becomes recursive — deleting a parent deletes its children, which deletes their children, etc.
- Sharing is Controlled by Parent, which means an org-wide chain of inheritance up to the root
- The Salesforce 3-level master-detail limit applies — a child can be a detail of one parent and master of another, but only 3 deep
For most hierarchical needs, self-lookup is the right call. Reserve self-master-detail for truly tightly coupled hierarchies (rare).
Preventing cycles
This is the most important caveat with self-lookups. Salesforce does not automatically prevent cycles on a generic self-lookup (the User Hierarchical Relationship is the only one that does this for you). Without protection, an admin could set:
Position A.Reports_To = B
Position B.Reports_To = A ← cycle!
Or worse:
A → B → C → A
This breaks any code that walks the chain (infinite loop) and corrupts your hierarchy logic. Common solutions:
- Validation rule comparing record Id to lookup Id — at least catches
A → A:Reports_To__c = Id - Trigger that, on every save, walks the proposed chain upward and errors if it encounters the current record’s Id. Use a
Set<Id>of visited Ids and abort once the set’s size suggests a loop. - Flow with the same logic, declaratively — usable for shallow hierarchies.
Querying self-relationships
SOQL handles parent traversal naturally with the relationship name:
SELECT Id, Name, Parent.Name, Parent.Parent.Name
FROM Account
WHERE Id = :accountId
You can go up to 5 levels of parent traversal in a single SOQL query. For deeper trees, query iteratively in Apex or use a recursive flow.
For child traversal (one level only):
SELECT Id, Name, (SELECT Id, Name FROM ChildAccounts)
FROM Account
WHERE Id = :rootId
ChildAccounts is the standard child-relationship name on the self-lookup. For custom self-lookups, you set this name yourself when creating the field.
Reports on self-relationships
Salesforce reports support self-joined reports up to a fixed depth — the “Account with Parent Account” pattern. For arbitrary-depth tree reports, you’ll need a custom report type, or you’ll pre-compute a flattened “Root Account” formula and group by that.
Summary
Self-relationship = a lookup where the object refers back to itself. Used for hierarchies and parent-child within one object. Cycle prevention is your responsibility for everything except the User Hierarchical Relationship.
Verified against: Salesforce Help — Object Relationships Overview. Last reviewed 2026-05-17.