Custom Metadata & Custom Settings
Custom metadata records are metadata: deployable with change sets/packages, versionable in source control, and readable without consuming SOQL limits via static methods.
33.1 Custom metadata types (__mdt)
Custom metadata records are metadata: deployable with change sets/packages, versionable in source control, and readable without consuming SOQL limits via static methods.
Uses: feature flags/kill switches, trigger handler configuration, mapping tables, integration endpoints paths, DI bindings (§36). Records can be deployed from Apex with Metadata.Operations.enqueueDeployment (asynchronous) but not changed with DML.
// all records (Map<DeveloperName, record>) — no SOQL consumed
Map<String, Discount_Rule__mdt> rules = Discount_Rule__mdt.getAll();
Discount_Rule__mdt gold = Discount_Rule__mdt.getInstance('Gold');
Decimal pct = gold?.Percent__c ?? 0;
// SOQL also works (supports relationship fields to EntityDefinition/FieldDefinition)
List<Discount_Rule__mdt> active = [SELECT DeveloperName, Percent__c, Tier__c
FROM Discount_Rule__mdt WHERE Is_Active__c = true];33.2 Custom settings
My_Settings__c.getInstance() (current user → profile → org default), getOrgDefaults(), getInstance(userOrProfileId)
Per-user/profile overrides, e.g., bypass automation for an integration user
List (legacy; prefer custom metadata) Country_Code__c.getAll(), getValues(name) Static lookup tables
Custom settings data is not deployed with metadata (unlike custom metadata records) and can be changed with DML; reads via getInstance are cached and don't use SOQL.
| | Custom Metadata | Hierarchy Custom Setting | Custom Object | |-|-----------------|--------------------------|---------------| | Deployable records | Yes | No | No | | DML from Apex | No (Metadata API only) | Yes | Yes | | Per-user override | No | Yes | Custom | | Counts toward SOQL | No (static methods) | No (getInstance) | Yes |
Automation_Settings__c s = Automation_Settings__c.getInstance();
if (s.Bypass_Triggers__c) return;