---
schema_version: "1"
id: 32693b871e975c969351c7da230f57c08f95c99edd3f818baa803765795e9406
title: Apex Triggers Always Run in a “without sharing” Context
collection: admin
version: current
locale: en-us
portal_url: https://docs.salesforce.com/admin/current/en-us/release-notes/262-0-0/rn_apex_triggers_system_mode.md
canonical_url: https://help.salesforce.com/s/articleView?id=release-notes.rn_apex_triggers_system_mode.htm&release=262.0.0&type=5
source_site: help.salesforce.com
content_type: documentation
content_hash: 0047b3f6c370a655bf61250169281b58625df05f79321d3721ecd8d8e6828b3d
description: Apex triggers now always run in a without sharing context. Previously, nested triggers enforced sharing rules in certain edge cases. However, in API version 67.0 and later, database operations within trigger bodies, including SOQL queries, SOSL queries, DML statements, and Database methods, run in user mode unless system mode is explicitly specified. User mode overrides the trigger’s without sharing context and effectively enforces a with sharing context in the trigger body.
products:
  - Cross Cloud
release: "262"
---
# Apex Triggers Always Run in a “without sharing” Context

Apex triggers now always run in a `without sharing` context. Previously, nested triggers enforced sharing rules in certain edge cases. However, in API version 67.0 and later, database operations within trigger bodies, including SOQL queries, SOSL queries, DML statements, and Database methods, run in user mode unless system mode is explicitly specified. User mode overrides the trigger’s `without sharing` context and effectively enforces a `with sharing` context in the trigger body.

**Where:** Triggers run in a `without sharing` context in all API versions. Database operations in trigger bodies default to user mode in API version 67.0 and later. The changes apply to Lightning Experience and Salesforce Classic in Enterprise, Performance, Unlimited, and Developer editions.

**Why:** These changes are part of the new “secure by default” security paradigm. For more information, see [Database Operations Run in User Mode by Default, Not System Mode](https://help.salesforce.com/s/articleView?id=release-notes.rn_apex_default_user_mode.htm&release=262.0.0&type=5 "Take advantage of an enhanced Apex security model that protects your data though default object- and field-level access enforcement. Apex database operations, such as SOSL and SOQL queries, DML statements, and Database methods, now run in user mode by default. In user mode, database operations enforce the sharing rules, field-level security, and object permissions of the current user. In earlier API versions, database operations default to system mode, which means that the current user can access all data regardless of their permissions."). To control behavior reliably independent of the API version, set explicit access mode on all database operations in your trigger and handler classes. When possible, delegate all business logic to trigger handlers.

**How:** This example demonstrates trigger database access in API version 67.0 and later.

```java
// API version 67.0

// The trigger itself runs as without sharing (all records accessible by default)
trigger AccountUpdateTrigger on Account (after update) {

    // This SOQL query doesn't specify an access mode, so it defaults to WITH USER_MODE. 
    // Object- and field-level permissions are enforced.
    // User mode reapplies the record-sharing rules of the current user,
    // effectively overriding trigger's own sharing context.
    List<Contact> contactsAccessibleByCurrentUser = [SELECT Id, Name, AccountId 
                                                     FROM Contact 
                                                     WHERE AccountId = :Trigger.newMap.keySet()];

    // This SOQL query explicitly includes a WITH SYSTEM_MODE clause.
    // Object- and field-level are bypassed.
    // Record sharing remains governed by the trigger's own without sharing context, 
    // so all records are visible regardless of the user running the query    

List<Contact> allRelatedContacts = [SELECT Id, Name, AccountId 
                                    FROM Contact 
                                    WHERE AccountId = :Trigger.newMap.keySet() 
                                    WITH SYSTEM_MODE ];

    // Further processing with the related Contacts

}
```

#### See Also

- [_Apex Developer Guide:_ Use the with sharing, without sharing, and inherited sharing Keywords](https://developer.salesforce.com/docs/atlas.en-us.262.0.apexcode.meta/apexcode/apex_classes_keywords_sharing.htm)
- [_Apex Developer Guide_: Apex Security and Sharing Model](https://developer.salesforce.com/docs/atlas.en-us.262.0.apexcode.meta/apexcode/apex_security_sharing_chapter.htm)