Skip to main content

SF-0296 · Concept · Medium

How many types of custom settings are there?

✓ Verified by Vikas Singhal · Last reviewed 5/17/2026 · Updated for Spring '26

Two types: List and Hierarchy. They share the underlying caching mechanism but differ in how records are looked up and what API call you use.

1. List Custom Settings

A flat lookup table. Each record has a Name (a string key) and arbitrary fields. You fetch records by their Name.

// One record by key
Country_Code__c india = Country_Code__c.getValues('IN');
String currency = india.Currency__c;

// All records
Map<String, Country_Code__c> all = Country_Code__c.getAll();
for (String code : all.keySet()) {
    System.debug(code + ' → ' + all.get(code).Currency__c);
}

Common uses:

  • ISO country / currency / state code tables
  • Static mappings (regions → endpoints, codes → labels)
  • Tax brackets, pricing tiers, holiday calendars

Up to 300 records per List setting by default (and the cap can be raised).

2. Hierarchy Custom Settings

A single resolved record that the platform picks based on a precedence rule:

  1. The running User’s personal record, if one exists.
  2. The running user’s Profile record, if one exists.
  3. The Organization-wide default record.
Feature_Flags__c flags = Feature_Flags__c.getInstance();        // for current user
Feature_Flags__c orgFlags = Feature_Flags__c.getOrgDefaults();  // org-wide only
Feature_Flags__c userFlags = Feature_Flags__c.getInstance(userId); // specific user

You can also create Hierarchy records keyed by Profile Id rather than User Id. The platform handles the cascade automatically; getInstance() returns the most-specific match.

Common uses:

  • Feature flags (“enable new search for me”)
  • Per-profile threshold overrides (“Sales Manager profile sees opportunities ≥ $1k; Reps see ≥ $10k”)
  • Trigger bypass switches that admins can toggle for themselves while debugging

When to choose which

NeedPick
Lookup table indexed by a string keyList
Configuration that varies per user/profileHierarchy
One single configuration record for the whole orgHierarchy (use getOrgDefaults())
Multiple records of the same shape but different keysList

A side-by-side example

// LIST — flat table of region endpoints
Region_Endpoint__c r = Region_Endpoint__c.getValues('US-WEST');
String url = r.Endpoint_URL__c;

// HIERARCHY — single config that varies per user
Trigger_Settings__c t = Trigger_Settings__c.getInstance();
Boolean accountTriggerEnabled = t.Account_Trigger_Enabled__c;

A list setting always returns one specific record by key. A hierarchy setting returns the appropriate version for the running user/profile/org.

What both share

  • Cached in memorygetInstance(), getValues(), getAll(), getOrgDefaults() don’t fire SOQL.
  • DML is allowedinsert, update, delete work in Apex (this is the one thing Custom Metadata can’t do).
  • Defined in Setup, not the Object Manager’s standard custom object UI.
  • Don’t deploy with their data between orgs — change sets only carry the schema, not the records. (This is why Custom Metadata replaced them for new work.)

A common bug: querying a Custom Setting with SOQL

You can write SELECT Name, Currency__c FROM Country_Code__c — and it works. But you’ve just fired a SOQL query and bypassed the cache. Always use the static accessors:

// BAD — defeats the cache
List<Country_Code__c> codes = [SELECT Name, Currency__c FROM Country_Code__c];

// GOOD — cached, no SOQL
Map<String, Country_Code__c> codes = Country_Code__c.getAll();

What interviewers are really looking for

The first answer: List and Hierarchy. The senior signal: (1) Hierarchy’s resolution cascade — User → Profile → Org, (2) the right API for eachgetValues for List, getInstance/getOrgDefaults for Hierarchy, (3) records are cached automatically — never use SOQL on them, (4) Custom Metadata Types is the modern replacement, but Custom Settings still win when Apex needs to write the values at runtime.

Verified against: Salesforce Help — Custom Settings Methods and Types, Apex Developer Guide — Custom Setting Methods. Last reviewed 2026-05-17.