Skip to content

SOQL: FOR VIEW, FOR REFERENCE, and FOR UPDATE

Published 06/03/2026

SOQL FOR VIEW, FOR REFERENCE, and FOR UPDATE Hero Image

Learn how FOR VIEW, FOR REFERENCE, and FOR UPDATE enhance SOQL for usage tracking and safe concurrent updates in Salesforce.


When you move beyond simple read-only queries and start building custom UIs, integrations, and complex Apex logic, you sometimes need SOQL to do more than just “return records.” You may want Salesforce to track that records were viewed or referenced, or you might need to lock records while your code updates them to prevent conflicts.

In this guide, we’ll explore three advanced SOQL clauses and when to use each one effectively:

  • FOR VIEW
  • FOR REFERENCE
  • FOR UPDATE

The optional FOR VIEW clause tells Salesforce that the retrieved records have been viewed by the current user. When you add FOR VIEW to a SOQL query, Salesforce:

  • Updates the LastViewedDate field for each returned record.
  • Inserts a row into the RecentlyViewed object so the record appears in Recent Items and other “recently viewed” experiences for that user.
SELECT Id, Name
FROM Contact
LIMIT 1
FOR VIEW

This query retrieves one Contact record and simultaneously updates its LastViewedDate while adding it to the current user’s RecentlyViewed list. It behaves as if the user had opened that Contact’s standard record page in the Salesforce UI.

Use FOR VIEW when:

  • You have a custom interface (LWC, Aura, Visualforce, external app) that shows full record details to a user, and
  • You want Salesforce’s Recent Items, LastViewedDate, and related “recent” behaviors to reflect that the record was actually viewed.

Avoid using FOR VIEW in background jobs, batch processes, or any automated context where no human is actually viewing the records. Adding FOR VIEW in these situations pollutes Recent Items and creates misleading “viewed” history for users, since Salesforce will treat the query as if a person opened the record in the UI.


The FOR REFERENCE clause tells Salesforce that the retrieved records are being referenced in the context of something the user is viewing. When you add FOR REFERENCE to a SOQL query, Salesforce:

  • Updates the LastReferencedDate field for each returned record.
  • Inserts rows into RecentlyViewed, similar to FOR VIEW.

In the standard UI, Salesforce uses “referenced” when a record is involved indirectly—for example, related list records or records displayed alongside a primary record.

SELECT Id, Name
FROM Contact
LIMIT 1
FOR REFERENCE

This query retrieves one Contact record and updates its LastReferencedDate, as well as adding it to the user’s RecentlyViewed data. It is treated as a supporting record that was involved in the user’s activity.

Use FOR REFERENCE when:

  • Your UI loads supporting or related records to a primary record the user is viewing (for example, related Contacts while viewing an Account).
  • You want those related records to appear in Recent Items and have accurate LastReferencedDate values.

Avoid using FOR REFERENCE in system-only or headless integrations where no real user is actually viewing the related records. It’s also not appropriate for bulk jobs that read large volumes of data purely for processing. As with FOR VIEW, using this clause outside a genuine user-driven context creates unnecessary noise in Recent Items and leads to inaccurate usage tracking.


Both clauses update usage‑tracking fields and create RecentlyViewed entries, but they signal different kinds of interaction. FOR VIEW represents a direct view — the equivalent of opening a record page — while FOR REFERENCE marks records that were indirectly involved, such as related list items or lookup targets. A simple way to choose between them is this:

  • If your UI is effectively replacing the standard record page → use FOR VIEW.
  • If you’re loading supporting data (related lists, lookups, helper records) alongside a primary record → use FOR REFERENCE.

Both FOR VIEW and FOR REFERENCE ultimately feed into the RecentlyViewed object, which powers Recent Items, search suggestions, and the various “recently viewed” lists throughout the UI. Salesforce updates this data whenever a user views or references records in the interface, or when your SOQL queries include FOR VIEW or FOR REFERENCE.

Salesforce also manages this table behind the scenes:

  • Salesforce periodically truncates RecentlyViewed to keep a manageable number of rows per user and object (around a couple hundred entries).
  • RecentlyViewed entries are retained for about 90 days, after which older rows are removed.

Because this data directly shapes the user experience, from auto‑complete to recent‑record lists. Salesforce recommends using these clauses only when you’re confident the user genuinely viewed or referenced the records.


While FOR VIEW and FOR REFERENCE deal with tracking how records are used, FOR UPDATE is about record locking. In Apex, you can append FOR UPDATE to an inline SOQL query to lock the returned rows, preventing other transactions from modifying them until your transaction finishes.

FOR UPDATE ensures exclusive access to the selected records so your transaction can safely read, compute, and write without interference from other concurrent processes.

Account[] accts = [
SELECT Id, Name
FROM Account
WHERE BillingCountry = 'New Zealand'
LIMIT 10
FOR UPDATE
];

In this example, the SOQL query retrieves up to ten Account records and immediately places a lock on them. That lock stays in place for the entire Apex transaction, ensuring no other process can modify those rows until your code finishes running. While they are locked:

  • Other transactions cannot update these rows.
  • Your code can safely perform additional logic and then update them, knowing they won’t be changed mid‑transaction by another process.
  • The locks are automatically released when the transaction completes (either commit or rollback).

FOR UPDATE comes with a few important limitations to be aware of. It’s only supported in Apex inline SOQL (queries written inside [ ]), and it cannot be combined with an ORDER BY clause in the same statement. You should also be careful about how long you hold locks; long‑running logic, large loops, or heavy contention can lead to “unable to obtain exclusive access to this record” errors for other users or processes.

Salesforce recommends using row locks thoughtfully, and the “Locking Records” section of the Apex Developer Guide offers deeper guidance and patterns for working safely with concurrent updates.


You should reach for FOR UPDATE only when there’s a real chance that multiple processes might touch the same records at the same time. It’s designed for situations where you need exclusive access to a record while your logic runs.

Use FOR UPDATE when you have genuine concurrency risk, such as:

  • Work‑queue patterns — pulling the “next” record to process (Cases, Leads, custom work items).
  • Aggregated updates — where your logic reads a record, calculates new values, and then writes them back, and you must ensure no one else changes the record in the meantime.
  • Sequential assignment — ensuring only one user or process can claim a given record at a time.

Avoid FOR UPDATE when:

  • You’re only reading data with no updates planned.
  • Your transaction is long‑running or involves external callouts before DML.
  • You’re processing very large batches of records that may compete with heavy user activity.

Used correctly, FOR UPDATE can increase reliability; used excessively, it can become a source of contention.


These three clauses extend SOQL beyond basic querying and give you tools for tracking how records are used and managing safe, concurrent updates:

  • FOR VIEW — marks records as viewed, updating LastViewedDate and adding them to RecentlyViewed for the user.
  • FOR REFERENCE — marks records as referenced, updating LastReferencedDate and adding supporting records to RecentlyViewed.
  • FOR UPDATE — locks records in Apex so your transaction can safely read and update them without interference.

Together, they help you build custom UIs that respect Salesforce’s usage‑tracking model and write Apex logic that handles concurrency safely without data collisions.

For deeper details, edge cases, and the latest platform behavior, refer to the official Salesforce documentation: