I made a thing.
The script at the bottom of this article scans all scripts in a given table/field for GlideRecord queries that use if (gr.next()) {}
WITHOUT a preceding .setLimit(1)
before .query()
.
Unfortunately, since there is no way (to my knowledge) to filter out-of-box records, you're probably going to find far more massively inefficient queries in ServiceNow's out-of-box code, than in your own. In my OOB PDI with only a few SN apps installed, this script finds about 1,450 violations in OOB code (ಠ_ಠ).
But still, this should help you to identify some of the major performance-impacting scripts running in your instance, at least by this particular metric.
Why is this important?
Every time you query a table for a single record, especially if you're not querying by a well-indexed field, you're doing a "full table scan". This means that the database server is going to scan the entire table looking for ANY records which match your query, and helpfully return all of those records to the application server... but if your script running on the app server only uses the first record returned and throws the rest away, then all the rest of that work done by the database server was pointless!
Even if there is only one record matching your query in the entire table, you're still wasting about HALF of your query performance on average.
Think about it - if you tell the database server that you actually only need ONE record, then it isn't going to bother continuing to search after it's found one, right?
You can use .setLimit(1)
to tell the database to stop searching after the first record is found. Otherwise, this would be like continuing to search for your keys, after you've found them.
If there are 100 places where your keys might be found, assuming they're all equally likely, then every time you lose your keys you may find them in the first place you look, or the last place you look, but on average you're going to find your keys in about the middle - about the 50th place you look.
Which means that continuing to search after you've found your keys would sometimes cost you 100x as much time as if you stopped after finding them, or if may not cost you anything extra if you found them only in the last place you looked... but on avreage, it'll cost you about DOUBLE the amount of time you would've spent if you'd stopped looking after you found them.
That's what .setLimit(1)
is for.
Usage
All you have to do is copy/paste this script into a Background Script in your instance, give it a couple minutes to run (it'll take a bit), and check out the output. This script can print out the details of where each violation can be found, including a link to the specific script file, line number, and even each variable name with an inefficient single-record query violation. To print these details, set the boolean argument on line 14 to true
. To print only a summary of findings per table, set that boolean to false
.
-
2025
- Sep 29, 2025 Find Filthy Inefficient Single-Record Queries FAST Sep 29, 2025
- Sep 14, 2025 Communicating Changes to Your Users (& Setting Default User Preferences in ServiceNow) Sep 14, 2025
- Mar 24, 2025 Calculate Distance Between Two Locations in ServiceNow (without an API call!) Mar 24, 2025
- Mar 11, 2025 5 Ways to Check your ServiceNow Instance for DANGEROUS CODE in Less Than 5 minutes Mar 11, 2025
-
2024
- Mar 28, 2024 How to Identify Duplicate Records by Multiple Fields in ServiceNow Mar 28, 2024
- Mar 7, 2024 How to Merge Personal & Company ServiceNow Accounts Mar 7, 2024
- Feb 12, 2024 5 Lessons About Programming From Richard Feynman Feb 12, 2024
-
2023
- Jul 5, 2023 Managing Instance-Specific System Properties for Dev/Test/Prod in ServiceNow Jul 5, 2023
- Apr 28, 2023 Your ACLs and Business Rules are Broken (Here's How to Fix Them) Apr 28, 2023
-
2022
- Dec 13, 2022 ServiceNow Developers: BE THE GUIDE! Dec 13, 2022
- Oct 19, 2022 A Faster, More Efficient Client-side GlideRecord (Free tool!) Oct 19, 2022
- Oct 9, 2022 Animated Loading Message & Collapsible Details on ServiceNow Form or Field (Client-side) Oct 9, 2022
- Aug 23, 2022 Using .addJoinQuery() & How to Query Records with Attachments in ServiceNow Aug 23, 2022
- Aug 18, 2022 Free, Simple URL Shortener for ServiceNow Nerds (snc.guru) Aug 18, 2022
- Aug 16, 2022 How to Get and Parse ServiceNow Journal Entries as Strings/HTML Aug 16, 2022
- Aug 14, 2022 New tool: Get Latest Version of ServiceNow Docs Page Aug 14, 2022
- Mar 4, 2022 How to Set or Change ServiceNow Application's Repository URL, Credentials, or SSH Key Mar 4, 2022
- Feb 7, 2022 How to return a CSV file from a Scripted REST API (SRAPI) in ServiceNow Feb 7, 2022
-
2021
- May 3, 2021 Adding a Guided Setup to Your ServiceNow Application May 3, 2021
- Apr 27, 2021 Use Automated Tests to Validate "Guided Setup" Completion & Functionality. Apr 27, 2021
- Feb 11, 2021 "Processors", SRAPIs, and How to Run a Script and Redirect a User From a URL in ServiceNow Feb 11, 2021
-
2020
- Nov 17, 2020 SN Guys is now part of Jahnel Group! Nov 17, 2020
- Sep 14, 2020 Better ServiceNow Notifications (& Another FREE Tool!) Sep 14, 2020
- Jul 31, 2020 Debugging Client & Catalog Client Scripts in ServiceNow Jul 31, 2020
- Jan 20, 2020 Getting Help from the ServiceNow Community Jan 20, 2020
-
2019
- Dec 18, 2019 Can ServiceNow Script Includes Use the "current" Variable? Dec 18, 2019
- Nov 18, 2019 Handling 'text/plain' and Other Unsupported Content Types in ServiceNow Scripted REST APIs Nov 18, 2019
- Apr 21, 2019 Understanding Attachments in ServiceNow Apr 21, 2019
- Apr 10, 2019 Using Custom Search Engines in Chrome to Quickly Navigate ServiceNow Apr 10, 2019
- Apr 4, 2019 Set Catalog Variables from URL Params (Free tool) Apr 4, 2019
- Apr 1, 2019 Outlook for Android Breaks Email Approvals (+Solution) Apr 1, 2019
- Mar 11, 2019 GlideFilter is Broken - Free Tool: “BetterGlideFilter” Mar 11, 2019
- Feb 27, 2019 Making Update Sets Smarter - Free Tool Feb 27, 2019
-
2018
- Nov 29, 2018 How to Learn ServiceNow Nov 29, 2018
- Nov 6, 2018 ServiceNow & ITSM as a Career? Nov 6, 2018
- Oct 19, 2018 Asynchronous onSubmit Catalog/Client Scripts in ServiceNow Oct 19, 2018
- Oct 11, 2018 How to do Massive, Slow Database Operations Efficiently With Event-Driven Recursion Oct 11, 2018
- Sep 18, 2018 Broken Queries & Query Business Rules in ServiceNow Sep 18, 2018
- Sep 7, 2018 JournalRedactor - Easily Redact or Delete Journal Entries in ServiceNow! Sep 7, 2018
- Jul 23, 2018 Admin Duty Separation with a Single Account Jul 23, 2018
- Jun 19, 2018 Improving Performance on Older Instances with Table Rotation Jun 19, 2018
- Jun 4, 2018 New Free Tool: Login Link Generator Jun 4, 2018
- May 29, 2018 Learning ServiceNow: Second Edition! May 29, 2018
- Apr 17, 2018 Upgrading From Express to Enterprise: What's Missing Apr 17, 2018
- Apr 12, 2018 If a Genie Gave Me Three Wishes, I'd Use Them All to "Fix" Scope Apr 12, 2018
- Mar 19, 2018 Service Catalog "Try in Portal" button Mar 19, 2018
- Mar 15, 2018 Video: Custom Output Transition Conditions From a Single Workflow (Script) Activity Mar 15, 2018
- Feb 11, 2018 We have a new book! Feb 11, 2018
-
2017
- Nov 6, 2017 Requiring Attachments (& Other Miracles) in Service Portal Nov 6, 2017
- Sep 12, 2017 Handling TimeZones in ServiceNow (TimeZoneUtil) Sep 12, 2017
- Jul 27, 2017 How to Enable DOM Manipulation in ServiceNow Service Portal Catalog Client Scripts Jul 27, 2017
- Jun 25, 2017 What's New in ServiceNow: Jakarta (Pt. 1) Jun 25, 2017
- Jun 4, 2017 Powerful Scripted Text Search in ServiceNow Jun 4, 2017
- May 9, 2017 Work at Lightspeed: ServiceNow's Plan for World Domination May 9, 2017
- Apr 9, 2017 Avoiding Pass-By-Reference Using getValue() & setValue() Apr 9, 2017
- Apr 4, 2017 "Learning ServiceNow" is Now Available for Purchase! Apr 4, 2017
- Mar 12, 2017 reCAPTCHA in ServiceNow CMS/Service Portal Mar 12, 2017
-
2016
- Dec 20, 2016 Pro Tip: Use updateMultiple() for Maximum Efficiency! Dec 20, 2016
- Dec 2, 2016 We're Writing a Book! Dec 2, 2016
- Nov 10, 2016 Chrome Extension: Load in ServiceNow Frame Nov 10, 2016
- Sep 7, 2016 Force-Include Any Record Into an Update Set Sep 7, 2016
- Sep 1, 2016 GlideRecord Pagination - Page through your GlideRecord query Sep 1, 2016
- Jul 17, 2016 Granting Temporary Roles/Groups in ServiceNow Jul 17, 2016
- Jul 15, 2016 Scripted REST APIs & Retrieving RITM Variables via SRAPI Jul 15, 2016
- May 17, 2016 What's New in Helsinki? May 17, 2016
- Apr 27, 2016 Customizing UI16 Through CSS and System Properties Apr 27, 2016
- Apr 5, 2016 ServiceNow Versions: Express Vs. Enterprise Apr 5, 2016
- Mar 28, 2016 Update Set Collision Avoidance Tool: V2 Mar 28, 2016
- Mar 18, 2016 ServiceNow: What's New in Geneva & UI16 (Pt. 2) Mar 18, 2016
- Feb 22, 2016 Reference Field Auto-Complete Attributes Feb 22, 2016
- Feb 6, 2016 GlideRecord & GlideAjax: Client-Side Vs. Server-Side Feb 6, 2016
- Feb 1, 2016 Make Your Log Entries Easier to Find Feb 1, 2016
- Jan 29, 2016 A Better, One-Click Approval Jan 29, 2016
- Jan 25, 2016 Quickly Move Changes Between Update Sets Jan 25, 2016
- Jan 20, 2016 Customize the Reference Icon Pop-up Jan 20, 2016
- Jan 7, 2016 ServiceNow: Geneva & UI16 - What's new Jan 7, 2016
- Jan 4, 2016 Detect/Prevent Update Set Conflicts Before They Happen Jan 4, 2016
-
2015
- Dec 28, 2015 SN101: Boolean logic and ServiceNow's Condition Builder Dec 28, 2015
- Dec 17, 2015 Locate any record in any table, by sys_id in ServiceNow Dec 17, 2015
- Dec 16, 2015 Detecting Duplicate Records with GlideAggregate Dec 16, 2015
- Dec 11, 2015 Array.indexOf() not working in ServiceNow - Solution! Dec 11, 2015
- Dec 2, 2015 Understanding Dynamic Filters & Checking a Record Against a Filter Using GlideFilter Dec 2, 2015
- Oct 20, 2015 Bookmarklet: Load the current page in the ServiceNow frame Oct 20, 2015
- Aug 27, 2015 Easily Clone One User's Access to Another User Aug 27, 2015