Salesforce docs tends to write examples that use global
despite not needing to. From time to time, I've seen this on scheduled classes, batchable classes, queueable classes, etc. You should not generally follow this example. Basically, you should instead consider the purpose of the class at hand.
If it's in your own org, it should be public
, unless the compiler specifically tells you something must be global
. If it's in a managed package to be installed, it should be public
unless it is meant to be used directly by subscribers (the most usual case are utility classes for controlling behavior and scheduled classes that can be scheduled by the subscriber directly).
For all typical cases, you should assume that public
is the correct access modifier, unless the documentation specifically says "the access modifier must be global" (e.g. Considerations for Using the webservice
Keyword says "All classes that contain methods defined with the webservice keyword must be declared as global"), or it is a feature meant to be directly used by subscribers.
When in doubt, make your code public
or private
. You can always promote it to global
later if you realize you made a mistake, but you can't go back down once you do go global
. Post-install handlers are one of those times where it typically doesn't make sense to have it be global
, because it may expose underlying data structures or secrets you don't want exposed unnecessarily.