ServiceNow Business Rule interview questions usually test whether you understand when server-side logic runs, what you can safely change on current, and which rule type fits a requirement.
Common follow-up questions cover:
- Recursion from
current.update() - Why
previousis unavailable in async rules - When a query business rule should not be used as a security mechanism
These questions show up in developer, administrator, and implementation partner loops—not only on pure coding screens.
Below are 40 ServiceNow business rules interview questions grouped by fundamentals, timing, APIs, query rules, debugging, and scenario design. Each card states what interviewers probe and ends with a spoken closing line. For broader platform scripting, ACLs, and GlideRecord patterns, pair this page with ServiceNow developer interview questions.
Understand Business Rules in 60 seconds
Start by asking what you need the Business Rule to do:
What does your server-side logic need to do?
│
├─ Validate/change the record before it is written?
│ → Before BR
│
├─ Act on related records immediately after it is written?
│ → After BR
│
├─ Perform work that can finish later?
│ → Async BR
│
└─ Send server data to a form while it opens?
→ Display BRThese four choices mainly differ by timing:
- Before — validate or change the record currently being saved
- After — the record has been written; update related records immediately
- Async — work can finish later without making the user wait
- Display — send server data while a form opens (not during save)
Before, after, and async rules are commonly used around record writes. A display rule belongs to the form-load path.
A Query Business Rule is separate again: it modifies a database query before matching records are returned. Configuration is When = before with the Query operation selected—not a fifth When value.
When a user saves a record, think in this order:
Request / save
│
▼
Before Business Rules
│
▼
Database operation
│
▼
After Business Rules
│
▼
Synchronous processing finishes
│
▼
Async work runs separatelySuppose a user changes an incident and clicks Update:
- Before business rules run while ServiceNow is still processing the save—they can validate the change, modify fields on
current, or stop the operation - ServiceNow then performs the database operation
- After business rules run afterward but are still part of synchronous processing, so they suit related-record work that must finish before the request completes
- Async business rules defer their work so the user does not have to wait
The diagrams above are intentionally simplified. ServiceNow also runs other platform engines at defined stages, including assignment rules, data policies, workflows, flows, and notification engines.
Business rule fundamentals
What is a Business Rule in ServiceNow?
What interviewers are testing: Whether you define business rules as server-side scripts tied to record operations—not generic "automation scripts."
A Business Rule is a server-side script that runs when a record on a configured table is displayed, inserted, updated, deleted, or queried (for query rules). It is bound to one table (or Global for rare shared hooks), filtered by When (before, after, async, display) and Insert / Update / Delete / Query operation checkboxes.
Typical uses:
- Validate or mutate fields on the current record before the database operation
- Update related records after the current record has been written
- Pass server data to the form through
g_scratchpad - Append query conditions so list and reference fields return a filtered row set
Business rules run on the server, so they are not limited to browser forms:
- They can run on server-side paths such as APIs
- Import and transform behavior depends on the import configuration
A strong answer is:
A Business Rule is a server-side script on a table that runs on display or CRUD/query operations. It enforces record logic on the server rather than only in the browser, and I use it for validation, related-record updates, and server-to-client data—not as a substitute for ACLs.
What are the different types of Business Rules?
What interviewers are testing: Whether you understand the four Business Rule timings—before, after, async, and display—and that a Query Business Rule is normally a before rule with the Query operation selected.
Think of When as the point in the record lifecycle where ServiceNow should execute your script.
ServiceNow documents four When values:
| When | Runs | Primary purpose |
|---|---|---|
| before | Before the record is written to the database | Mutate current, validate, setAbortAction |
| after | After the database operation, while processing remains synchronous | Related records, events, immediate follow-up work |
| async | Later, outside the user's save transaction | Email, integrations, heavy background work |
| display | When a form loads (read path) | Populate g_scratchpad for client scripts |
The operation checkboxes answer a different question: what action on the record should trigger that rule?
Query is an operation checkbox, not a fifth When value. A query business rule is configured as When = before with Query selected:
| Configuration | Runs | Primary purpose |
|---|---|---|
| Query Business Rule | Before a query executes (When = before, Query = selected) | Add conditions before records are returned |
Insert, Update, and Delete are separate operation checkboxes for standard CRUD rules.
A strong answer is:
ServiceNow has four When values: before, after, async, and display. A query business rule is a before rule with the Query operation checked—it filters reads, not a separate timing type.
What happens if a Business Rule has When = before but Insert, Update, Delete, and Query are not selected?
What interviewers are testing: Whether you distinguish When (timing) from operation (trigger)—a common configuration mistake in interviews.
- When — when in the lifecycle should this script run? (before, after, async, display)
- Operation — what database action should trigger it? (insert, update, delete, query)
If When = before but no operation checkbox is selected, the rule has timing without a trigger—it will not run on insert, update, delete, or query.
For example, When = before + Update selected means: "run this script before an existing record is updated." If Update is not selected, changing an existing record will not trigger the rule.
Interview trap: a rule with a perfect condition but the wrong operation checkbox checked (for example Update unchecked on an update-only requirement) looks configured but never fires.
A strong answer is:
When controls timing and the operation checkboxes control the trigger. If none of Insert, Update, Delete, or Query is selected, the rule will not run even when the condition looks correct.
What does the Order field in a Business Rule control?
What interviewers are testing: Whether you know how multiple matching rules at the same stage are sequenced.
Multiple business rules can match the same table and operation. The Order field sets their sequence: lower numbers run before higher numbers among rules at the same stage.
Before BR — Order 100
↓
Before BR — Order 200
↓
Before BR — Order 500For example, if Order 100 sets priority = 2 and Order 200 later sets priority = 1, the second rule sees the result of the first rule and can overwrite it. This is why rule order matters when multiple rules touch the same data.
The Order field controls the sequence of matching business rules at the same stage. It does not control every type of automation running on the platform.
A strong answer is:
The Order field controls execution sequence among matching business rules at the same stage; lower numbers run first. I use it when one rule depends on values another rule sets, and I avoid unnecessary ordering chains.
What is a Global Business Rule, and when should you avoid it?
What interviewers are testing: Whether you understand performance and scope—global rules load broadly and are easy to misuse.
A Global business rule is attached to the Global table. It can run across the instance (depending on conditions) and historically held shared functions.
Today, prefer Script Includes for reusable server functions:
| Approach | Trade-off |
|---|---|
| Global BR | Loads broadly; hard to trace; performance cost |
| Script Include | Explicit call site; scoped; easier to test and upgrade |
Use a global rule only when you truly need a cross-cutting hook with tight conditions—or migrate legacy estates gradually.
A strong answer is:
Global business rules attach to the Global table and can fire very broadly. I avoid new global rules for shared logic and use Script Includes instead, keeping global hooks only for narrow cross-cutting cases.
When would you choose a Business Rule over a UI Policy, Data Policy, or Workflow Studio flow?
What interviewers are testing: Whether you know which ServiceNow feature fits the requirement and when each option is appropriate.
| Need | Tool |
|---|---|
| Change form behavior (show, hide, mandatory) | UI Policy / Client Script |
| Enforce field rules beyond the form | Data Policy |
| Multi-step process orchestration | Workflow Studio / Flow |
| Code tied to insert/update/delete timing on a record | Business Rule |
| Reusable server logic | Script Include |
A business rule fits when logic must run at a specific point in the record lifecycle on the server. A UI Policy improves the form experience, but it does not replace server-side enforcement when the requirement must hold regardless of how the record is created.
A strong answer is:
I match the tool to the requirement: UI Policies for form behavior, Data Policies for server field enforcement, flows for process orchestration, and business rules when logic must run on insert, update, delete, or query timing.
Before, after, async, and display
In what order do Business Rules run relative to UI Policies and Client Scripts?
What interviewers are testing: Whether you separate form load from form save—not one blended lifecycle.
Opening a record is primarily a read path. ServiceNow first has to find the record, then prepare any server-side information required by the form before the browser runs its client-side logic.
Database query
↓
Before Query BR may modify query
↓
Record retrieved
↓
Display BR
↓
g_scratchpad sent to browser
↓
onLoad Client Scripts / UI PoliciesOn the read path:
- A query business rule can change which records the database query is allowed to return
- Once the record is retrieved, a display business rule can prepare server-side values in
g_scratchpad - The browser then receives the form and runs its onLoad client scripts and UI Policies
Saving is a write path. Client-side checks can run first in the browser, but once the request reaches ServiceNow, server-side business rules control what happens around the database operation.
Client validation / onSubmit
↓
Request reaches server
↓
Before Business Rules
↓
Database operation
↓
After Business Rules
↓
Response after synchronous work
↓
Async Business Rules (separate)On the write path:
- A before rule gets the last opportunity to change
currentor reject the save before the database operation - An after rule runs once that database operation has taken place but still makes the request wait for its work
- An async rule is separated from that interactive work and can finish later
This is intentionally simplified. ServiceNow also runs other platform engines at defined stages, including assignment rules, data policies, workflows, flows, and notification engines.
Client scripts and UI Policies run in the browser:
- They improve usability
- They do not replace before business rules for server enforcement
A strong answer is:
When a form is opened, query rules can affect which records are returned, and display rules can prepare server-side data for the form. On save, before rules run before the database operation, after rules run synchronously afterward, and async rules run later. Client scripts never replace before business rules.
What is the difference between before and after Business Rules?
What interviewers are testing: Whether you tie each type to database operation timing and which record you may change.
| Before | After | |
|---|---|---|
| Timing | Before the database operation | After the database operation, while processing remains synchronous |
Mutate current |
Set fields; saved with the operation | Changing current needs another update() |
| Related tables | Risky—the operation may still fail | Typical place for synchronous related-record updates |
| Abort save | setAbortAction(true) |
Too late to abort the save |
Before example: when state moves to Resolved, set closed_by to the current user on the same incident row.
After example: when an incident is Resolved, add a work note on the linked problem—only after the incident row has been written.
A strong answer is:
Before rules run before the database operation, so I can change fields on current or abort the save. After rules run once the current record has been written, which is the typical place for synchronous related-record updates.
What is an async Business Rule, and when do you use it?
What interviewers are testing: Whether you know async rules defer work and do not finish before the response returns.
An async business rule queues work to run after synchronous processing finishes. The user is not blocked while email, metrics, or integration calls complete.
Use async for:
- Notifications that can wait
- Longer-running server work that does not need an immediate result
- Outbound integrations where the form should return quickly
Async keeps the user from waiting, but the background work should still use efficient queries.
Avoid async when:
- The user must see related data immediately after save
- You need
previousor change-detection methods in the script - Downstream logic must run before the HTTP response completes
A strong answer is:
An async business rule runs in the background after synchronous processing finishes. I use it for email and integrations when the user does not need to wait, not when related data must appear immediately on the next screen.
What are the advantages of async Business Rules over after rules—and vice versa?
What interviewers are testing: Whether you can explain when the user waits versus when work can finish later.
Async over after:
- Shorter perceived save time for the user
- Isolates slow integrations from the interactive request
- Reduces risk of timeout on heavy server work
After over async:
- Related updates complete before the request finishes
previousandchanges()methods work in the script- Another script or screen reading the database immediately sees the result
Example: closing child incidents when a parent closes needs after (or before on children), not async, if the list must refresh without delay.
A strong answer is:
An after business rule runs synchronously, so I use it when related changes must finish before the request completes. An async rule runs later in the background, so I prefer it for heavier work the user does not need immediately.
Which Business Rule types should not use current.update(), and why?
What interviewers are testing: Whether you understand how current.update() can trigger recursion.
| Type | current.update() |
|---|---|
| before | Avoid / unnecessary — changes to current are already saved automatically |
| after | Avoid on the same record — can retrigger rules and cause recursion |
| async | Possible but still risks loops; prefer mutating in before or related records with care |
| display | Not applicable — display is read-only for persist |
ServiceNow best practice:
- Avoid
current.update()inside business rules because of recursion and duplicate database operations - If the same record needs fields changed as part of the save, move that logic to a before business rule
setWorkflow(false)exists for specialized GlideRecord updates where you intentionally disable Business Rules and other workflow-related processing normally triggered by that update—it is not the normal fix for a badly placedcurrent.update()
A strong answer is:
I do not call current.update() in before rules because the save is already in progress. In after rules I avoid updating the same record and move same-row field changes to a before rule instead.
What is the difference between setWorkflow(false) and setForceUpdate(true) on GlideRecord?
What interviewers are testing: Whether you understand that these methods solve different problems.
| Method | What it changes |
|---|---|
setWorkflow(false) |
What automation accompanies the update — disables Business Rules and other workflow-related processing normally triggered by that GlideRecord update |
setForceUpdate(true) |
Whether an update happens when values did not change — forces a write even when the platform would skip it as a no-op |
Use both carefully because they change normal update behavior:
- If the requirement is simply to modify the current record during save, a before business rule is usually clearer
- Do not default to
setWorkflow(false)followed bycurrent.update()in after
A strong answer is:
setWorkflow(false) suppresses normal Business Rule and workflow processing for that GlideRecord update, while setForceUpdate(true) forces an update even when no field value changed. They solve different problems.
Display BR and client/server communication
What is a display Business Rule, and give a real use case?
What interviewers are testing: Whether you connect display BR to g_scratchpad and server data the form does not carry.
Display rules run when a record form is loaded:
- They cannot block save; they prepare data for the client
- The platform passes
g_scratchpadfrom server to client - Client scripts read
g_scratchpadon load
Use case: show the Description field only if the logged-in user belongs to the incident assignment group. The display rule evaluates membership server-side:
g_scratchpad.showDescription = gs.getUser().isMemberOf(current.assignment_group);The onLoad Client Script shows or hides Description based on that flag:
- This controls form behavior only
- If Description is sensitive, enforce access with an ACL—hiding a field in a client script is not security
A strong answer is:
Display business rules run on form load and populate g_scratchpad for client scripts. I use them when the form needs server-only data at load time, and I still use ACLs when the field must be protected.
When would you use a display Business Rule instead of GlideAjax?
What interviewers are testing: Whether the data is needed when the form opens or only later.
| Display BR + g_scratchpad | GlideAjax | |
|---|---|---|
| Timing | Data ready on form load | Extra round trip when needed |
| Best for | Flags needed immediately on load | User-triggered lookups (onChange) |
| Load cost | Every form open | Only when client calls |
Example: default visibility flags for several fields on open → display BR. Lookup catalog price when the user picks a model → GlideAjax to a Script Include.
A strong answer is:
I use a display rule when the form needs server data as soon as it opens, without an extra round trip. GlideAjax fits lookups the user triggers after the form is already open.
Can you call a Business Rule directly from a Client Script?
What interviewers are testing: Whether you know business rules are triggered by configuration, not invoked like functions.
No — you do not call a business rule like a reusable server function from a client script. A business rule runs when its configured record operation fires:
- insert, update, delete, display, or query
For client-to-server logic:
Client Script
│
│ GlideAjax
▼
Client-callable Script Include
│
▼
Server logicThe client script does not execute the business rule:
- It sends a separate request through GlideAjax to a client-callable Script Include
- That Script Include runs the required server-side code
If the server data is already known when the form loads, a display business rule plus g_scratchpad may avoid the extra GlideAjax call.
A strong answer is:
You do not directly call a business rule from a client script. For client-to-server calls I use GlideAjax with a Script Include; for data needed at form load, a display rule and g_scratchpad may be a better fit.
current, previous, and server APIs
What is the difference between current and previous?
What interviewers are testing: Whether you know which object holds new versus old field values in an update.
current |
previous |
|
|---|---|---|
| Represents | Current/new record state | State before the update |
| Update BR | New values | Old values |
| Insert | Available | Not available |
| Delete | Record being deleted | Previous state available |
| Async | Available | Not available |
For example, if an incident priority changes from 3 to 1, previous.priority represents 3 and current.priority represents 1 during a synchronous update rule.
- Use
currentfor the values being saved - Use
previouson synchronous update/delete rules when you need the old value or want to compare what changed
A strong answer is:
current holds the new record state in the transaction, and previous holds the old values on update. previous is not available on insert or in async business rules.
What objects are available inside a Business Rule?
What interviewers are testing: Whether you know the main objects used inside a Business Rule.
| Object | Role |
|---|---|
current |
GlideRecord for the record in this operation |
previous |
Field values before this update/delete (not available on insert; not available in async) |
gs |
GlideSystem — logs, events, user, messages, properties |
g_scratchpad |
Display rules only — server-to-client payload |
Other server-side APIs such as GlideDateTime and GlideAggregate, along with Script Includes, can also be called from the business rule when needed.
A strong answer is:
In business rules I use current for the record, previous for old values on synchronous update, gs for system services, and g_scratchpad in display rules to pass data to the client.
Why is an Advanced Business Rule wrapped in a function?
What interviewers are testing: Whether you know why ServiceNow wraps Advanced Business Rule code in a function such as executeRule(current, previous).
An Advanced Business Rule is normally structured like this:
(function executeRule(current, previous /*null when async*/) {
// Business Rule code
})(current, previous);Why it matters:
- Gives variables inside the rule local scope
- Prevents namespace collisions with other server-side scripts
- Passes
currentandpreviousinto the function - Keeps the script in the standard Advanced Business Rule structure
Keep custom variables inside this function instead of creating globals that may interfere with other server-side scripts.
A strong answer is:
I keep Business Rule code inside the function wrapper so variables remain local to that rule and do not collide with other server-side scripts. ServiceNow passes current and previous into that function.
Why is previous unavailable in an async Business Rule?
What interviewers are testing: Whether you know previous is not available in async rules and that change-detection helpers do not work there.
ServiceNow does not make previous available to async business rules. Async processing happens later, outside the synchronous record update where the old and new values are available together.
In async scripts:
previousis unavailable- Do not use
current.field.changes(),changesTo(), orchangesFrom() - Use synchronous before or after rules when you need an old-vs-new comparison
In async, read current and design idempotent logic so rerunning it does not create duplicate effects.
A strong answer is:
previous is not available in async business rules, and changes(), changesTo(), and changesFrom() do not work there either. I use a synchronous after rule when I need to compare old and new values once per save.
How do you detect that a specific field changed in a Business Rule?
What interviewers are testing: changes() / changesTo() versus naive string compare on previous.
Preferred patterns on synchronous update:
if (current.assignment_group.changes()) {
// assignment group changed
}
if (current.state.changesTo(6)) { // use your app's resolved state value
// state transitioned to resolved
}To detect escalation to Critical priority (when 1 is Critical in your app):
if (current.priority.changesTo(1)) {
// priority escalated to Critical
}Put the condition in the business rule condition field when possible so the script body does not run on every save. These methods are for synchronous rules—not async.
A strong answer is:
On a synchronous update I use current.field.changes() or changesTo(), and I compare with previous when I need the old value. I also narrow the rule condition so the script does not run on every save.
How do you tell whether the current operation is insert, update, or delete?
What interviewers are testing: Operation-aware logic without duplicating three rules unnecessarily.
Use current.operation() inside the script:
| Return | Meaning |
|---|---|
insert |
New row |
update |
Existing row change |
delete |
Row removal |
You can also create separate rules with only Insert, Update, or Delete checked—clearer for operators reading the rule list.
Example: run assignment logic only on insert:
if (current.operation() == 'insert' && !current.assignment_group.nil()) {
// initial routing
}A strong answer is:
I use current.operation() when one script handles multiple operations, or I split rules with the Insert, Update, and Delete checkboxes when that is clearer for maintenance.
How do you prevent a record from saving in a Business Rule?
What interviewers are testing: Server-side validation that works beyond the browser—not client return false.
In a before rule:
gs.addErrorMessage('Resolve all open tasks before closing the incident.');
current.setAbortAction(true);| Piece | Role |
|---|---|
gs.addErrorMessage |
User-visible reason |
setAbortAction(true) |
Stops the database operation |
Must run in a before rule—after the database operation is too late. Client scripts improve UX but do not replace this for requirements that must hold on server-side writes.
A strong answer is:
In a before business rule I add an error message and call current.setAbortAction(true). That stops the save on the server, not only in the browser.
How do you trigger a notification or event from a Business Rule?
What interviewers are testing: Whether you know how to separate the Business Rule from the notification or downstream action via gs.eventQueue.
Pattern:
gs.eventQueue(
'incident.assigned',
current,
current.assignment_group.toString(),
''
);Registered notifications, script actions, or flows listen for incident.assigned.
Benefits:
- Keeps the business rule short
- Lets admins adjust notification content without editing the rule
- Works well from after rules when the record is already written
Pass meaningful parm1/parm2 strings; document them for the event consumer.
A strong answer is:
I use gs.eventQueue() to queue a registered event, then let notifications or Script Actions handle the downstream work. I commonly do this from an after rule when the event should fire only after the record has been written.
Query business rules and security
What is a query Business Rule, and what is its primary objective?
What interviewers are testing: Row-level read filtering on queries—not write enforcement.
A query business rule runs when GlideRecord queries the table (When = before, Query selected). It appends conditions with current.addQuery() or similar before the query runs, so matching queries return only rows that satisfy the additional conditions.
Think of the query business rule as adding another filter before ServiceNow sends the query to the database. If the user asks for "all users" but the rule adds active=true, the effective request becomes "all active users."
User/query asks for:
All users
↓
Query BR adds:
active = true
↓
Database effectively receives:
All users WHERE active = trueExample (conceptual): non-admins see only active users:
if (!gs.hasRole('admin') && !gs.hasRole('user_admin')) {
current.addQuery('active', true);
}Effects and performance:
- Can affect list, reference, report, and GlideRecord results that query that table
- Query rules can run frequently—keep conditions and added queries efficient
- Excessive before-query rules or non-indexed OR-heavy logic can hurt performance
A strong answer is:
A query business rule appends conditions before records are returned, so lists and reference fields show a filtered row set. I keep the logic efficient because it can run on many reads.
What is the difference between a query Business Rule and an ACL?
What interviewers are testing: The classic security architecture question—query BR is not a full ACL replacement.
| Query BR | ACL | |
|---|---|---|
| Scope | Read/query filtering | Create, read, write, delete on rows and fields |
| Mechanism | Modifies the query before rows return | Denies operations; may show "security constraints" message |
| GlideRecord | Affects normal queries | Use GlideRecordSecure to enforce ACLs in script |
| Column security | No | Yes — field-level ACLs |
Examples:
- Query BR — "users without admin only see active users"
- ACL — "only HR role can read salary field"
Do not confuse a query business rule with a Query ACL:
query_matchandquery_rangeACL operations control potentially sensitive queries (security controls)- A query business rule modifies the query itself (operational filtering)
Enforce authorization with ACLs; use query BR for operational filtering when appropriate.
For security or data segregation, prefer ServiceNow's dedicated security mechanisms rather than introducing a query business rule just to hide records.
A strong answer is:
Query business rules change which rows a query returns, while ACLs enforce access to records and fields. I use ACLs for authorization and query business rules only when I need to modify query results for an operational reason.
What happens if a query BR filters active records only but a reference qualifier requires inactive rows?
What interviewers are testing: What happens when two filters add conflicting conditions and the reference list comes back empty.
If the query BR adds active=true and the reference qualifier adds active=false, the combined query matches no rows. The reference picker shows zero results.
Fix paths:
- Align qualifier with query BR intent
- Narrow the query BR with roles so admins retain full pickers
- Revisit whether inactive rows should be selectable at all
A strong answer is:
Stacked filters intersect, so an active-only query BR plus an inactive reference qualifier returns zero rows. I align the qualifier with the query rule or exempt roles that need the wider picker.
If a Business Rule is defined on task, does it run for incident?
What interviewers are testing: Table extension and inherited server behavior.
Business rules defined on an extended parent table such as task can apply when operations occur on child tables such as incident, depending on the rule configuration and conditions:
incidentextendstask- Always consider parent-table rules when debugging unexpected behavior on an incident
Same caution for:
- ACLs on parent tables
- Client scripts on parent tables (when applied to child views)
Test on the child form and API path you actually ship.
A strong answer is:
A business rule on task can apply to incident depending on configuration and conditions. Because incident extends task, I always check parent-table rules when debugging unexpected behavior on the child table.
Debugging, recursion, and performance
How do you debug a Business Rule?
What interviewers are testing: Whether you know a practical debugging process, not only gs.log.
| Technique | Use |
|---|---|
| Script Debugger | Step through synchronous before/after/display rules |
| gs.info / gs.debug | Targeted logging with rule name prefix |
| System Log / All | Find errors and stack traces |
| Session debug / Debug Business Rule | Trace which rules ran (version-dependent) |
| Temporarily disable a suspect rule | Isolate overlapping behavior in a safe test instance |
| Field watch | Confirm condition fields fire when expected |
Narrow the condition and operation checkboxes first—most "rule does not run" issues are filter typos, wrong table, or missing Insert/Update selection. Check Order when multiple rules at the same stage interact.
A strong answer is:
I reproduce the save, use Script Debugger or gs.info with a clear prefix, check System Log for errors, and verify conditions, operation checkboxes, and Order before I change script logic.
Why call a Script Include from a Business Rule instead of putting all logic in the rule?
What interviewers are testing: Maintainability, reuse, and testability.
Reasons:
- Same validation called from BR, Flow script, REST, UI Action
- Shorter rules—easier rule list for operators
- Easier to test reusable logic independently of the Business Rule trigger
- One place to fix GlideRecord query patterns (avoid N+1)
The Business Rule can then stay small and focus only on deciding when to call the reusable logic:
var validator = new IncidentCloseValidator();
if (!validator.canResolve(current)) {
gs.addErrorMessage(validator.getMessage());
current.setAbortAction(true);
}A strong answer is:
I put reusable server logic in a Script Include so the Business Rule stays small and the same logic can be reused from other server-side entry points.
How do you prevent recursive Business Rules?
What interviewers are testing: Loop breaking when related updates re-fire the same rule.
Techniques:
- Move same-row field changes to before (no
current.update()) - Use conditions so the rule runs only on the transition you care about
- Avoid updating the same table in after without narrow conditions
- Use
setWorkflow(false)only for special cases—not as the default fix for recursion
One warning sign is a single save producing repeated Business Rule log entries or many repeated events. That often indicates that one update is triggering another update in a loop.
A strong answer is:
I prevent recursion by using before rules for same-row changes, tight conditions, and avoiding current.update() in after. If related records must update, I narrow the condition so the rule does not fire on its own writes.
What are best practices for efficient Business Rules?
What interviewers are testing: Whether you know how to prevent Business Rules from slowing record saves or database queries.
| Practice | Why |
|---|---|
| Use conditions / filter conditions | Prevent the rule from executing its script on unrelated records and updates |
| Avoid GlideRecord queries inside loops | Repeated database queries inside a loop can become expensive |
| GlideAggregate for counts | Avoid loading full record sets when you only need an aggregate value |
| Fewer overlapping rules | Easier debugging |
| Async for slow IO | Keep interactive request short |
| Script Includes | Shared optimized queries |
| Efficient query BR logic | Query rules run on many reads |
Where possible, put simple filtering in the Business Rule's Condition or Filter Conditions rather than entering the script and immediately returning.
Anti-pattern: query all incidents on every task update. Fix: query only current.parent children with indexed fields.
A strong answer is:
I keep conditions tight, avoid GlideRecord in loops, use aggregates for counts, push slow work to async, and keep query business rules lean because they run on many reads.
Should you trigger a Scheduled Job from a Business Rule?
What interviewers are testing: Whether you understand record-driven work versus scheduled batch processing.
Usually, you should not need to. A business rule responds to a record operation, while scheduled jobs are intended for time-based or batch processing.
If record activity needs deferred processing, prefer:
- An async business rule
- An event consumed by a script action or flow
- Another supported asynchronous mechanism for the use case
Reserve scheduled jobs for work that is genuinely calendar-based or batch-oriented—not as a shortcut for every after rule.
A strong answer is:
I usually do not need to invoke scheduled jobs from business rules. For work triggered by a record change that can run later, I use async processing or events; scheduled jobs are for time-based or batch processing.
When should you use try/catch in a Business Rule?
What interviewers are testing: Exception handling versus normal null checks.
Use try/catch when code can throw:
- JSON parsing
- Parsing or handling data returned by an integration
- Calling custom code that may throw
- A small block of custom code where you need to log and handle a possible runtime exception explicitly
Use normal conditions and null checks for expected states—a missing reference usually needs nil() checks, not try/catch.
Pattern:
try {
var payload = JSON.parse(current.u_payload);
} catch (e) {
gs.error('IncidentBR routing: ' + e.message);
gs.addErrorMessage('Routing failed; contact platform support.');
current.setAbortAction(true);
}Whether you abort the save depends on the requirement. If the failed operation is optional, log the error and handle it gracefully instead.
Do not wrap entire rules to hide logic bugs—log and handle exceptions intentionally.
A strong answer is:
I use try/catch for parsing, integrations, or other code that can throw. For expected missing data I use normal null checks, and I log context when I abort the save.
Scenario-based questions
Scenario: short description must contain at least 10 characters. Client Script or Business Rule?
What interviewers are testing: Whether you know when client validation is enough and when server-side enforcement is required.
| Layer | Role |
|---|---|
| Client Script | Immediate feedback on the form |
| Data Policy / before BR | Enforces the requirement beyond client-side form validation |
| Client only | Can be bypassed through API or other server paths |
- Form usability only — a client script is fine
- Must hold on every server-side write — enforce with a Data Policy or before business rule, not client validation alone
A strong answer is:
A client script gives immediate feedback on the form. If the validation must not depend only on the browser, I enforce it on the server as well, using the appropriate Data Policy or before business rule.
Scenario: two before Business Rules update the same field. Order 100 runs first, Order 200 second. Which value is saved?
What interviewers are testing: Whether you apply the Order field to a concrete outcome.
Order 200 runs second, so its field value overwrites what Order 100 set—assuming both run on the same save and mutate the same field on current. Teams document Order deliberately and avoid two rules fighting over one field without coordination.
A strong answer is:
Lower Order runs first, so Order 200 runs after Order 100 and its field value wins if both set the same field on current during one save.
Scenario: block resolving an incident while child tasks are still open. How do you implement it?
What interviewers are testing: Before update validation with a narrow query—not client-only checks.
Design:
- Before update business rule on
incident(ortaskif shared) - Condition: state changes to resolved/closed (use your app's state values)
- Script: check whether at least one open child task exists using a narrow
GlideRecordquery withsetLimit(1), or useGlideAggregatewhen you actually need the count - If an open task exists:
gs.addErrorMessage+setAbortAction(true)
Example existence check:
var task = new GlideRecord('task');
task.addQuery('parent', current.sys_id);
task.addQuery('active', true);
task.setLimit(1);
task.query();
if (task.hasNext()) {
gs.addErrorMessage('Close all open tasks before resolving the incident.');
current.setAbortAction(true);
}- Before — abort before the database operation
- Not client script alone — server-side writes can bypass the form
A strong answer is:
I use a before update business rule that detects the resolve transition, checks for at least one open child task with a narrow GlideRecord query, and aborts with addErrorMessage so the rule holds on the server.
Scenario: when an incident is resolved, add a work note on the related problem. Which rule type?
What interviewers are testing: Related record timing—after the current record is written, not before.
Use an after update business rule on incident:
- Condition: state changes to resolved
- Script: if
problem_idis set, update the problem record's work notes or comments
Use after because the related-record action should occur only after ServiceNow has performed the incident update. A before rule should focus on validating or changing the incident itself.
Use async only if the note can wait and ordering with other updates is loose.
A strong answer is:
I use an after update rule so the problem work note is written only after the incident update has been performed, with a condition on the resolved state transition.
Scenario: assign critical incidents to the Major Incident group automatically. Where do you put the logic?
What interviewers are testing: Before mutation on current versus unnecessary related-table work.
Use a before insert and before update rule (or one rule with both checkboxes):
-
Condition: priority is Critical (or impact/urgency matrix your process uses)
-
Script: set
assignment_groupto the Major Incident group's sys_id (from a system property or reusable helper logic) -
Set fields on
currentin before—noupdate()needed -
Avoid hard-coding the group sys_id directly in the business rule; store configurable values in a system property or resolve them through reusable configuration/helper logic
A strong answer is:
I set assignment_group on current in a before insert or update rule when priority is critical, pulling the group sys_id from a system property or reusable helper logic—not hard-coded in the rule.
Scenario: create a change task when a change request is submitted via a record producer. Does the business rule run?
What interviewers are testing: Record producer inserts are still server inserts—BR timing applies.
Yes, when the record producer inserts a record into the table where the business rule is configured. The rule fires as part of that insert if its conditions and operation checkboxes match.
Typical pattern:
- After insert on
change_request: createchange_taskrows with GlideRecord - Or catalog workflow / flow if the process is approval-heavy
Confirm whether the producer writes to change_request or a staging table—rules on the wrong table never fire.
A strong answer is:
When a record producer inserts into change_request, insert business rules on that table can fire if configured. I use after insert to create change tasks, or a flow when approvals own the process.
Scenario: sync related KPI fields that the list must show immediately after save. Can you use async?
What interviewers are testing: Recognizing when async is the wrong tool.
No — if the list or form must show updated KPI fields as soon as save completes:
- Use an after (synchronous) rule, or
- Set the KPI fields in before on
currentwhen the KPIs live on the same row
Async completes later; users refreshing immediately may see stale KPIs and report "the rule failed."
A strong answer is:
No. If KPIs must appear immediately after save, I use a synchronous after rule or set the fields in a before rule on current, because async runs too late for the next screen refresh.
Pattern cheat sheet (quick reference)
| Need | Business rule choice |
|---|---|
| Validate or block save | before + setAbortAction |
| Set fields on same row | before |
| Update related rows after database operation | after |
| Email / integration / heavy IO | async |
| Server data on form load | display + g_scratchpad |
| Filter list/reference rows | query (When = before, Query selected) |
| Reusable logic | Script Include called from rule |
| Authorization | ACL (not query BR alone) |
Summary
ServiceNow business rules interviews reward timing discipline: before for current and abort, after for related rows that need the database operation to finish first, async only when immediate consistency and previous do not matter, display for g_scratchpad, and query rules for read filters—not ACL replacements. Practice explaining recursion from current.update(), the Order field when two rules touch the same field, and scenario answers like blocking resolve with open tasks.
Answer aloud and compare your structure to each card. For GlideAjax, ACL evaluation, update sets, and full developer loop prep, continue with ServiceNow developer interview questions.
Interview context (optional prep)
What business rules interviews test
| Area | What panels focus on |
|---|---|
| Timing | Before vs after vs async vs display; query as operation |
| Objects | current, previous, g_scratchpad |
| Safety | Recursion, setAbortAction, avoiding current.update() |
| Security | Query BR vs ACL vs Query ACL |
| Configuration | When vs operation checkboxes, Order field |
Junior vs senior expectations
| Topic | Junior / mid | Senior |
|---|---|---|
| Before vs after | Names the four When values | Explains database operation timing and related-record risk |
| current.update() | "Avoid it" | Moves same-row logic to before; names recursion |
| Async | "Runs in background" | States previous is unavailable; names when async is wrong |
| Query BR | "Filters lists" | Contrasts with ACL and query_match / query_range |
| Design | One rule per requirement | Script Includes, Order, minimal rule count |
Hands-on practice on a personal developer instance (PDI) or subproduction helps most—follow-ups expose gaps quickly if you have only read definitions.

