Use search.lookupFields when you only need a small set of fields. Use record.load when you actually need full record behavior, sublists, or a subsequent save path.
Verdict
Use search.lookupFields by default when you are only reading a small number of fields. Reach for record.load only when you truly need full record behavior or intend to modify and save.
| Criterion | Option A | Option B | Recommendation |
|---|---|---|---|
| Governance cost | Typically far cheaper for lightweight reads. | Expensive if used as a reflex. | lookupFields wins for simple reads. |
| API surface | Limited to returned field values. | Full record interaction. | record.load only when you need the full surface area. |
| Loop safety | Safer for repeated execution. | Can become a governance trap quickly. | lookupFields in loops unless proven insufficient. |
| Mutation path | Not the right tool for mutation. | Natural fit when save follows. | record.load when the read is part of an update workflow. |
The cheapest and usually correct option for lightweight reads.
Correct when you need full record context, not just field values.
I see this pattern constantly: a developer needs one field, reaches for record.load because it is familiar, and then repeats that choice inside a loop. Individually the call feels harmless. At scale it becomes the quiet reason the script no longer finishes cleanly.
const values = search.lookupFields({
type: search.Type.SALES_ORDER,
id: orderId,
columns: ['entity', 'status']
});Default bias
If you are only reading, your first thought should be lookupFields. Make record.load prove that it is necessary.
Governance
This is the kind of small decision that becomes a site-wide performance problem. The wrong choice multiplied by thousands of iterations is how ordinary scripts turn into governance incidents.
Performance
The real optimization is not micro-benchmarking a single call. It is removing unnecessary full-record loads from hot paths.