Field Tracking in standard/custom object salesforce
•15 min read
Here’s a complete, clear, and code-based explanation of Field Tracking (Field History Tracking) in Salesforce Standard and Custom Objects — including setup steps, Apex SOQL example, and best practices.
✅ 1. What Is Field History Tracking in Salesforce?
Field History Tracking allows Salesforce to track changes to selected fields on standard or custom objects, such as:
- Who made the change
- Old value
- New value
- Timestamp of the change
Tracked data is stored in a special history object like:
- AccountHistory
- ContactHistory
- OpportunityFieldHistory
- CustomObject__History
✅ 2. How to Enable Field History Tracking (Standard & Custom Objects)
Step-by-Step
- Go to Setup
- Search Object Manager
- Select the Object (Standard or Custom)
- Click Fields & Relationships
- Click Set History Tracking
- Check "Enable History"
- Select the fields you want to track
- Click Save
👉 Salesforce stores up to 20 fields per object by default.
✅ 3. Example Code: Query Field History Records (SOQL)
🔹 Example: Query Opportunity Field History
List<OpportunityFieldHistory> histList = [
SELECT
OpportunityId,
CreatedById,
CreatedDate,
Field,
OldValue,
NewValue
FROM OpportunityFieldHistory
WHERE OpportunityId = :oppId
ORDER BY CreatedDate DESC
];
JavaScript✅ 4. Example Code: Query History for Custom Objects
Suppose your object is Project__c
History object name → Project__History
List<Project__History> historyRecords = [
SELECT
ParentId,
CreatedById,
CreatedDate,
Field,
OldValue,
NewValue
FROM Project__History
WHERE ParentId = :projectId
ORDER BY CreatedDate DESC
];
JavaScript✅ 5. Display Field History in LWC (Optional Example)
// Apex Controller
public with sharing class FieldHistoryController {
@AuraEnabled(cacheable=true)
public static List<Project__History> getFieldHistory(Id recordId) {
return [
SELECT Field, OldValue, NewValue, CreatedById, CreatedDate
FROM Project__History
WHERE ParentId = :recordId
ORDER BY CreatedDate DESC
];
}
}
JavaScript// LWC JS
import { LightningElement, api, wire } from 'lwc';
import getFieldHistory from '@salesforce/apex/FieldHistoryController.getFieldHistory';
export default class FieldHistoryViewer extends LightningElement {
@api recordId;
@wire(getFieldHistory, { recordId: '$recordId' }) history;
}
JavaScript<!-- LWC HTML -->
<template>
<template if:true={history.data}>
<template for:each={history.data} for:item="h">
<p key={h.Id}>
{h.Field} changed from {h.OldValue} to {h.NewValue} on {h.CreatedDate}
</p>
</template>
</template>
</template>
JavaScript✅ 6. Best Practices
✔ Do not track unnecessary fields to avoid data bloat
✔ Use Field Audit Trail if you need >18 months history
✔ Use SOQL filters for better performance
Related Posts

How to Automatically create a follow-up Task when a Lead is converted

How You need to update a related child record whenever a parent record’s status changes, but only if the status is “Closed Won.” How would you design this in Apex?
