ACL Misconceptions That Hurt Performance
What the Advanced flag really does and why heavy ACL scripts get expensive
ACLs are easy to treat as a pure security feature and forget that they also sit on a hot path.
When an instance loads a form, renders a list, or reads fields through server-side code, ACL evaluation can happen many times. That is why small misunderstandings in ACL design turn into both security confusion and avoidable performance cost.
These are the misconceptions I see most often.
1. The Advanced flag does not disable the ACL script
This is probably the most common misunderstanding.
On an ACL record, the Advanced flag controls whether the script field is shown in the form. It does not decide whether existing script logic is executed.
That means this situation is possible:
- an ACL already has script logic saved
- someone later clears the
Advancedflag - the script field is hidden
- the script still participates in the ACL evaluation
So if behavior feels inconsistent, do not assume “Advanced = false” means “no script is running.” It may simply mean the script is no longer visible in that form layout.
2. ACLs are not automatically slow, but ACL scripts can become expensive
People sometimes say “ACLs are slow” as if the record itself is the problem.
The issue is usually not the existence of an ACL. The issue is what the ACL has to do every time access is checked.
ACL checks can occur:
- when a list loads many rows
- when a form renders many fields
- when code reads records through secure APIs
- when related data causes repeated field-level checks
If an ACL script performs extra queries, builds large objects, or logs aggressively, that work can be repeated far more often than expected.
3. One expensive ACL script can be multiplied across rows and fields
This is where the performance impact becomes visible.
A script that feels cheap for one record may become expensive when:
- a list shows dozens or hundreds of rows
- the same table has several field ACLs
- the script performs another database query for each evaluation
Bad pattern:
var task = new GlideRecord("incident_task");
task.addQuery("incident", current.sys_id);
task.addActiveQuery();
task.query();
answer = task.hasNext();
That may look harmless, but if it runs repeatedly during access evaluation, you have just added extra database work to the security layer.
ACL scripts should be treated like code that may run frequently, not like a one-time business rule.
4. Prefer roles and conditions before you reach for script
The fastest ACL script is the one you do not need.
If access can be expressed with roles, use roles. If it can be expressed with a condition, use a condition. Script should be the fallback for logic that cannot be modeled cleanly any other way.
This is not only about performance. It is also about readability. A role-based ACL is easier to audit than a script that mixes access rules, queries, and edge cases.
A good mental order is:
- Can a role decide this?
- Can a simple condition decide this?
- Only then, do I actually need script?
5. Passing one ACL does not mean the user will get access
Another common mistake is debugging one ACL in isolation and assuming that success there should grant access overall.
Access decisions can involve table-level and field-level ACLs, and multiple rules may participate in the final result depending on the operation and data being accessed.
So when a user still cannot read a record, do not stop at “this ACL returned true.” Keep checking the rest of the applicable security rules.
This is also why performance tuning has to look at the whole set of ACLs on a table, not only the one script that first caught your attention.
6. Admin override is not a universal escape hatch
It is common to assume that checking Admin overrides means administrators will always pass.
In practice, ACL behavior can still be affected by the broader ACL set and instance configuration. If admin access behaves unexpectedly, inspect the full security picture instead of assuming the checkbox alone guarantees the outcome.
That matters for performance too: teams sometimes add more custom ACL logic while debugging admin behavior, when the real problem is a misunderstanding of how the existing rules combine.
7. Keep ACL scripts narrow and predictable
If you do need script, keep it cheap.
Good ACL script habits:
- use data already available on
currentwhen possible - avoid extra
GlideRecordqueries inside the ACL - avoid loops over large related datasets
- avoid verbose logging in normal execution
- return a simple boolean answer
Reasonable pattern:
answer = gs.hasRole("itil") ||
current.getValue("caller_id") == gs.getUserID();
This kind of check is short, obvious, and does not add extra database reads.
8. Field ACLs deserve extra caution
Table ACLs are important, but field ACLs are often where performance surprises show up.
A single scripted field ACL can be evaluated repeatedly across many fields or rows. If that script performs additional server work, the cost multiplies quickly.
So if a page feels slow after security changes, inspect scripted field ACLs first. They are a common place for hidden repetition.
9. Debug security with the right question
When an ACL issue shows up, ask two separate questions:
- Is the access decision correct?
- Is the way we compute that decision efficient?
Those are not the same problem.
An ACL can be logically correct and still be too expensive because it performs unnecessary lookups. It can also be fast and still be wrong because the team misunderstood Advanced, Admin overrides, or the number of ACLs participating in the check.
Keeping those two questions separate usually leads to cleaner fixes.
A practical default
When designing ACLs, this is the bias I try to keep:
- Prefer roles over script.
- Prefer conditions over script when the logic is simple.
- If script is necessary, keep it short and free of extra queries.
- Be especially careful with scripted field ACLs.
- Never assume the
Advancedflag disables existing script logic.
Final thought
ACLs are part of normal platform behavior, so their cost is easy to underestimate.
Most ACL performance problems do not come from security itself. They come from heavy script logic placed in a layer that may run again and again across records, fields, and requests.
If the rule is simple, keep it simple. If the rule must be scripted, write it as if it will run a lot, because it probably will.