A custom module gives you a new object. A custom function gives you new behavior. Teams reach for the wrong one constantly — adding a custom module when they need logic, or a Deluge function when they need data.
Custom Modules Are Nouns
If your business has an entity with its own lifecycle, attributes, and relationships — that’s a noun, that’s a module. Renewals. Subscriptions. Inventory items. Service tickets.
Test: can you draw a record of this thing on a 3x5 card with its own fields and history? It’s a module.
Custom Functions Are Verbs
If you have a behavior that runs against existing records — calculate, validate, transform, route — that’s a verb, that’s a function.
Test: does the work happen “to” something that already exists? It’s a function.
When Both Look Right
Sometimes you need a function that creates module records (e.g., a function that turns a closed deal into a project). That’s not a tie — it’s a function operating on a module. Build the module first, then the function.
The “Just Use a Picklist” Test
Before adding a module, ask if the data could live as a picklist or related list on an existing record. A “Sales Region” custom module with three records is wasted complexity — it should be a global picklist.
Custom module - 50+ rows, own lifecycle, own owners, reportable
Picklist - <50 stable values, no per-row metadata needed
Related list - lives in context of parent, no independent reporting
Custom Module Costs
Each custom module adds:
- Layout(s) to maintain.
- Permissions to manage per profile.
- API endpoints to monitor.
- A surface for schema rot.
Don’t add modules speculatively. The cost is real even when usage is low.
Custom Function Costs
Functions cost:
- Execution time against per-day quota.
- API calls against per-day quota.
- Maintenance debt as your schema evolves.
Don’t write a function for one-off data fixes. Use the bulk update UI or a one-time script.
A Worked Example
You’re tracking equipment serial numbers attached to customer accounts.
- New module “Equipment” with serial, model, install date, account lookup.
- Custom function: when a serial is added, validate it against the manufacturer’s API and stamp a warranty end date.
Module + function. Each does its part.
Anti-Pattern: The “Notes Module”
Don’t build a “Customer Notes” custom module. Use the native Notes feature. Don’t build a “Tasks” custom module. Use the native Tasks. Reach for custom modules only when nothing native fits.
What to Do This Week
- Inventory your custom modules. Mark each as Noun (justified) or Picklist-Equivalent (over-built).
- Inventory your custom functions. Mark each by quota usage.
- Retire one over-built module by collapsing it into a picklist or related list.
- Document the noun-vs-verb test in your team’s CRM playbook.