The customization ladder is the way to decide which xMatix tool should carry a change in behaviour: plain configuration at the bottom, custom code at the top. The rule that keeps a system maintainable is simple: pick the lowest rung that genuinely solves the problem. Lower rungs are declarative. They are visible in Setup, you can test them before they go live, and they stay safe across product updates. Higher rungs give you more expressive power, but they add code that someone must read, test and maintain. Climb only when the requirement truly cannot be expressed a rung below, and never ship a weaker approximation just to stay declarative.
Overview
Every rung changes what happens when people work with records. They differ in three ways:
- Who can read it. Configuration, rules, assignments, approvals and workflows are screens an administrator can open and understand. A script or a custom component is code.
- When it runs. Some tools act inside the save and can refuse it. Others act after the save has been stored, and cannot undo it.
- Where it runs. Everything except custom components runs on the server, for every write path: record forms, the mobile app, the Data API, imports and background jobs. Custom components run in the browser.
Where the rungs live in Setup
- Setup → Design Studio → Entities is the bottom rung. Open an entity to reach its Schema group (Fields, Record Types, Field Mappings, Lookup Filters, Relations, Field Dependencies), its Logic group (Validations, Actions, Approval Processes, Document Settings, Execution Plan) and its Experience group (Views, Layouts, Defaults, Email Templates).
- Setup → Process Studio holds every higher rung: Business rules, Assignment rules, Scripts, UI components, Workflows and Approvals.
- Setup → Platform holds system boundaries rather than behaviour: Integrations and Sync profiles.
Before adding anything, search the relevant register. Overlapping rules, scripts and workflows on the same entity are the most common cause of surprising saves. The entity's Logic → Execution Plan page shows everything that runs when the entity is saved, in order.
The ladder at a glance
| Rung | Tool | Reach for it when |
|---|---|---|
| 1 | Field, validation and record-type configuration | The change is about a field: required, unique, a default, a picklist value, a format, a layout, a variant of the record |
| 2 | Business rules | "When this record is saved, changes state or reaches a date, enforce, derive or hand off something" |
| 3 | Assignment rules | "Decide who this record goes to": its resource, owner or branch |
| 4 | Approval processes | A person must sign off before something proceeds |
| 5 | Workflows | Multi-step processes over time: "then wait for someone, then branch, then do a second thing" |
| 6 | Automation scripts | Server-side logic beyond declarative reach: complex cross-record calculations, calls to other systems, the logic behind custom buttons |
| 7 | Custom components | The standard user-interface widgets cannot express the experience |
How xMatix handles it
Field, validation and record-type configuration
The bottom rung is not really customization at all. It is the entity model itself. Required and unique fields, defaults, picklists, field formats, lookup filters, field dependencies, field mappings, record types and page layouts cover a surprising share of requirements. A validation on the entity is a check with a message that is evaluated on every save, and every violated validation refuses the save. It is the right home for a simple rule such as "Quantity must be positive". If the requirement can be stated as a property of a field or as a plain check, it belongs here. See Entity behavior and Design a form layout.
Business rules
A business rule is declarative logic with a condition on the record and an ordered list of actions. Its Triggers decide when it is considered: OnSave, OnInsert, OnUpdate, OnFieldChange (named fields changed), OnPhaseTransition (a status field moving between specific values, such as Draft to Submitted), OnDelete, OnSavedChanges (after the save commits), OnApprovalDecision (after an approval step is decided) and OnSchedule (hourly). A rule's condition can read the value a field had before the save with PRIORVALUE(Field), and the Only when the condition becomes true checkbox makes a rule act once, on the save where its condition turns from false to true.
A rule can also act later. Its Delay setting is Run immediately (the default), Wait after the save or Count from a date on the record, up to 7 days. A delayed rule never acts during the save: a matching save books a run, listed as "Delayed business rule" under Jobs. When the run is due, xMatix reads the record again and tests the condition again before the actions run. Blocking actions cannot be delayed.
The actions split into two families, and the split matters for choosing a rung:
- Before-the-save actions shape or refuse the record before it is written: BlockSave, ShowMessage, SetValue, CopyFromField, LookupValue, FormatValue, SetRequired, SetReadOnly, LockRecord, EnforceUnique, RunAssignment (assign the record by an assignment rule) and ApplyFieldMappings (re-copy field mappings from the lookups).
- After-commit actions run only after a successful save and hand off to something else: TriggerEntityAction (run a server action configured on the entity, exactly as pressing its button would), CreateRecord (of any entity), CreateActivity, PushFieldMappings (copy this record into its lookups and child records), SendMessage, RequestApproval, EnqueueJob, Route to queue, RaiseEvent, RaiseNudge and the legacy InvokeAutomationScript.
Because of the after-commit actions, a rule reaches further than "this record only": it can run a button's server action, start an approval, open a task, update related records or create new ones, all without code. What a rule cannot do is call an external system itself, loop over records it was not given, or wait for a person. Rules have a Test Runner in Setup, so you can preview a rule against a real record. See Business rules and Expressions.
Assignment rules
An assignment rule decides who a record goes to: its resource, owner, branch or company. The screen describes it as "ordered rules, lookups across entities and a fair way to pick". The Runs on column shows when each one runs: Create, Change of named fields, or Manual only. A business rule can also run one with its RunAssignment action, and the Dry run tab shows what an assignment would pick before you switch it on. Use this rung instead of a chain of SetValue actions on the owner field. See Automatic owner assignment.
Approval processes
When the requirement is "a manager must allow this", model it as an approval process, even when it looks like the escape hatch of a blocking rule. An approval process is defined per entity with an entry condition, an order (the first matching active process claims the record), who may submit, and one or more steps. Each step resolves a real approver: a specific user, a manager field on the record, a security role, a team, the submitter's reporting manager, or a person the submitter chooses. The process notifies the approver, can lock the record while the decision is pending, stamps the outcome onto the record and keeps an audit trail of who decided what and when. Records enter it from a Submit for approval action, from a business rule's RequestApproval action, or from a workflow step. An approval step can also run a business rule when it is approved or rejected. An editable "approved" checkbox is not an approval: it records no approver, no timestamp and no reason. See Approval processes.
Workflows
A workflow orchestrates across time and across records in a visual designer. It starts from a record event (create, update or delete of a named entity), either before the save or after it. Only a before-save workflow can stop the save, with its Cancel entity operation step; in an after-save workflow that step does nothing. Steps include branching, sending a message or e-mail, submitting for approval and waiting for the decision, and enqueueing a job. Triggers register only from the published version, so every edit is a draft until you publish again. If the requirement includes "then wait for someone to decide, then…", it is a workflow. A fixed wait of up to 7 days after a save or around a date can stay a delayed business rule. See Build a workflow.
Automation scripts
Scripts are C# code that is compiled when you save it and run by the platform in a sandbox, with a single Ctx object as their whole contract: records with old values, data access, metadata, outbound HTTP, messaging and e-mail, jobs and queues, approvals, secrets and logging. A script is bound to an entity in one of two ways:
- on a lifecycle slot (load defaults on inserts, pre-validate, validate, before save, after save, before delete, after delete), with the change kinds it listens to (insert, update, delete), or
- to a server action behind a button.
Bindings run inline or asynchronously on the worker. By default an inline run has a 10-second budget and an asynchronous run 60 seconds. Saving a script in the editor makes a version that compiles live straight away. Reach for a script for external calls, calculations that read many unrelated records, and the logic behind custom buttons. See Your first automation script.
Custom components
Custom components (Setup → Process Studio → UI components) are your own user-interface widgets. They are versioned like scripts, bound to one entity or to all entities, and can be offered inside App Pages. You place them in layouts and pages with the designer, and they read and write through the same data APIs as the rest of the product, so security and validation still apply. This rung is for presentation. If the logic could live on the server, keep it there. A component runs in the browser, so it can never enforce anything: pair it with a rule or validation when data integrity depends on it.
Module tools that sit beside the ladder
Some registers serve one job and are not general rungs. Deduplication rules (Setup → Feature Hub → Platform → Deduplication rules) decide when two records count as duplicates; see Duplicate rules. Macros (Setup → Feature Hub → Service → Macros) bundle one-click steps for support agents; see Macros.
Choosing quickly
Some signal phrases map directly to rungs:
- "this field must…" is configuration;
- "when the record is saved…" or "two days after the due date…" is a business rule;
- "it should go to the right person…" is an assignment rule;
- "someone must approve…" is an approval process;
- "then wait for a decision, then…" is a workflow;
- "call another system…" is a script;
- "show it differently…" is a layout or a component.
When two rungs both work, the lower one wins.
Two further questions settle most borderline cases. Does it need to block the save? Only validations, before-the-save rule actions, before-save workflows and validate or before-save scripts can block. Anything that runs after the commit cannot. Must any administrator be able to read and change it? Rules, assignments, approvals and workflows are readable in Setup by anyone with the capability. A script is readable only by someone who reads code.
Example
A distributor wants three things for its sales orders: an order over 5,00,000 must be signed off by the regional manager; once approved, the order must be released automatically; and if it is still unshipped three days after approval, the sales executive's manager should get a reminder.
- Configuration. An admin adds a validation so Quantity on order lines must be greater than zero. No rule is needed for that.
- Approval process. An approval process on Order with the entry condition "amount over 5,00,000" and one step whose approver is a manager field on the order. Its final approval stamps a custom date field, Approved On. This rung gives the audit trail a checkbox never could.
- Business rule, after commit. A rule on Order with the OnApprovalDecision trigger, the condition
approvalDecision == "Approved", and a TriggerEntityAction action that runs the server action the company uses to release an order. No script is needed. - Delayed business rule. A second rule with Count from a date on the record (3 days after Approved On) and a SendMessage action to the manager. Its condition checks the order's own fields to see that it is still unshipped, and xMatix tests that condition again when the run is due.
Nothing here needs a workflow or a script. A workflow would only be needed if a second person had to decide something after the first approval.
Training
Practice exercise
In a sandbox, take this requirement: "When a lead's status changes to Nurturing, create a follow-up task for its owner, once." Decide the rung, then build it.
Expected result: a business rule on Lead with the OnSavedChanges trigger, the condition Status == "Nurturing", the Only when the condition becomes true checkbox ticked, and a CreateActivity action. Saving the same lead again while it stays in Nurturing creates no second task. If your answer used a workflow or a script, explain what it adds that the rule does not.
Quick reference
- Pick the lowest rung that genuinely solves the problem.
- Validations always refuse a save they fail. Use them for plain checks.
- Business rules act before the save (shape or refuse) or after commit (hand off). An action in the wrong phase is skipped.
- A rule can act later with Delay, up to 7 days, but cannot block when delayed.
PRIORVALUE(Field)and Only when the condition becomes true handle old-versus-new comparisons without a script.- Decide owners with assignment rules, not SetValue chains.
- Sign-off is an approval process, never an editable checkbox.
- Only before-save workflows can cancel a save, and only the published version runs.
- Scripts: 10 seconds inline, 60 seconds asynchronous, by default.
- Components never enforce anything. Pair them with server-side checks.
Permissions
Each register is gated by its own setup capability, granted on a security profile's Entitlements tab:
| Area | Capability |
|---|---|
| Entities, fields, views, relations, validations, actions | Manage metadata model |
| Business rules and Assignment rules | Manage business rules |
| Approvals | Manage approval processes |
| Scripts | Manage automation scripts |
| Workflows | Manage workflows |
| UI components | Manage custom components |
Setup hides an entry from the menu when you lack its capability. See Security profiles.
Configuration
Every rung can be authored in a sandbox copied from production and moved across with a package, so a new rule, workflow or script never meets live records untested. All rungs also run inside one save pipeline: defaults, validation, rules, module logic, then workflows and scripts. A rule's Sequence, a script binding's sequence and the workflow phase decide where each one sits, and the entity's Execution Plan shows the whole line-up. When two customizations seem to fight, that order is almost always the explanation; see What runs when you save a record.
Common problems
A reminder rule sends on every save
An after-commit rule acts on every save where its condition holds. Tick Only when the condition becomes true, or add a PRIORVALUE comparison to the condition. A rule set to Wait after the save books a run on every matching save too, so pair it with OnInsert, a narrow condition or the same checkbox.
My follow-up action never runs
After-commit actions such as SendMessage, CreateRecord and TriggerEntityAction need the OnSavedChanges or OnApprovalDecision trigger. On a rule with only before-the-save triggers they are skipped, and the Actions tab refuses the clear mismatches when you save the action.
A value set by a rule is overwritten
Scripts and module logic run later in the save pipeline and can overwrite what a rule set. Open the entity's Execution Plan to see who writes last, and move the logic to one place.
Common questions
Why prefer a business rule over an automation script?
Because a rule is declarative. Any administrator can open it in Setup, read exactly what it does, preview it against a record in the Test Runner, and adjust it without a developer. A script is code: more expressive, but opaque to non-developers and a maintenance obligation from the day it ships. Rules now cover old-versus-new comparisons (PRIORVALUE), delays of up to 7 days, related-record updates and running a button's server action, so most single-record save logic no longer needs a script. Reserve scripts for what rules genuinely cannot express, such as external calls.
Can a business rule call another system?
Not directly. A rule never makes an outbound call itself, and that is what makes it safe to run inside every save. It can hand off after the commit: TriggerEntityAction runs a server action (whose bound script may call out through Ctx.Http), and EnqueueJob, SendMessage and RaiseEvent hand work to other parts of the platform. When a save must reach another system with retry and monitoring, use an integration. See the integrations overview.
Isn't an "override" checkbox simpler than an approval process?
It is simpler to build, but worse in every way that matters. A checkbox that lifts a block records nothing: no approver, no timestamp, no reason, and anyone with edit rights can tick it. An approval process resolves the right approver, notifies them, locks the record while pending and writes an audit trail. If you do choose a checkbox as a deliberate lightweight alternative, restrict who can edit it with field-level security, and treat that as the exception.
When is a workflow the wrong tool?
When everything it does happens in one save, or after a fixed delay, with no human decision to wait for: that is a business rule, with Delay if needed. It is also the wrong tool when it must refuse the save on a simple condition: a rule or validation does that without the publish-and-version overhead, and an after-save workflow cannot block at all.
Rule or assignment rule for setting the owner?
Use an assignment rule. It is built to pick a person fairly from candidates, can read across entities, and has a dry run. A business rule's SetValue on the owner field picks one fixed value and is easy to overwrite by accident. You can still trigger an assignment from a rule with RunAssignment when the moment matters.
