You create a List Custom Setting in Setup, add its fields, then add the actual data records. The definition deploys between orgs, but the records do not, so plan to load data separately in each environment.
- Create the setting
In Setup, go to Custom Settings and click New. Enter a Label and Object Name, choose Setting Type = List, set Visibility to Public or Protected, then save.
- Add custom fields
On the setting detail page, add the fields you need from the supported types (Text, Number, Checkbox, Date, Email, URL, and similar). Lookups, picklists, and formulas are not available.
- Add data records
Click Manage, then New, and create each record. The Name field identifies the row that getValues(name) will return, so use stable, predictable names your code can rely on.
- Read it from Apex
Call MySetting__c.getValues('Some_Name') for one record or MySetting__c.getAll() for the full Map. Neither call consumes a SOQL query, since the data is served from the application cache.
Set this to List so every record is global. The alternative, Hierarchy, adds per-user and per-profile overrides you do not want for shared data, and the type cannot be changed later.
Public exposes the setting to subscriber code in a managed package; Protected hides it. For an org-internal setting either works, but Protected is safer if you later package the code.
The unique text key for each record. Code fetches a row by this Name, so treat it as a stable identifier and avoid renaming records that running code depends on.
- The definition deploys through change sets, but the records do not. The target org gets an empty setting until you load the data manually or by script.
- getValues(name) returns null when no record matches, so null-check before reading a field or the transaction throws a null pointer error.
- All custom setting data shares a roughly 10 MB org-wide cap across List and Hierarchy combined. Large or growing data sets belong in a custom object instead.
- Updates take a few seconds to propagate across application servers, so a record written and re-read in the same flow may briefly return a stale value.