Skip to content

Your First Query

Note

Step-by-step tutorial to write your first NQL query - from the simplest device list to a complete performance analysis query.

Overview

This guide walks you through writing your first NQL queries, starting with the absolute basics and building up to a practical IT monitoring query. By the end, you'll understand how to:

  • Query device inventory
  • Filter results
  • Add time windows for events
  • Compute metrics
  • Display formatted results

Time to complete: 10-15 minutes

Before You Start

What you need:

  • Access to Nexthink Web Interface
  • Permission to view device and event data
  • No prior NQL experience required!

Where to write queries: 1. Open Nexthink Web Interface 2. Navigate to InvestigationsNew Investigation 3. You'll see the NQL query editor

Development Best Practice

Always add | limit 10 to your queries while learning. This makes them run faster and keeps results manageable.

Step 1: Your First Query (Device List)

Let's start with the absolute simplest query - listing all devices.

Query:

devices
| list device.name

What this does:

  • devices - Query the devices table (current device inventory)
  • | list device.name - Show only the device names

Click "Run Query"

Expected output:

device.name
-----------
LAPTOP-001
LAPTOP-002
DESKTOP-005
SERVER-101
...

Success!

You just wrote your first NQL query! You're querying the devices table and displaying device names.

Add a limit for faster testing:

devices
| list device.name
| limit 10

Now you'll see only 10 devices - much faster during development!

Step 2: Add More Fields

Let's see more information about each device.

Query:

devices
| list device.name,
       operating_system.name,
       hardware.memory
| limit 10

What's new:

  • Multiple fields in list (separated by commas)
  • operating_system.name - The OS running on the device
  • hardware.memory - RAM installed

Expected output:

device.name  | operating_system.name | hardware.memory
-------------|----------------------|----------------
LAPTOP-001   | Windows 11           | 17179869184
LAPTOP-002   | Windows 10           | 8589934592
DESKTOP-005  | Windows 11           | 34359738368

Wait, what's with those huge numbers for memory?

Those are bytes! Let's format them properly.

Step 3: Format the Output

Query:

devices
| list device.name,
       operating_system.name,
       hardware.memory.as(format = bytes)
| limit 10

What's new:

  • .as(format = bytes) - Format bytes as GB/MB/KB

Expected output:

device.name  | operating_system.name | hardware.memory
-------------|----------------------|----------------
LAPTOP-001   | Windows 11           | 16 GB
LAPTOP-002   | Windows 10           | 8 GB
DESKTOP-005  | Windows 11           | 32 GB

Much better! Now we can actually read the memory sizes.

Available Formats

You can format other values too: - as(format = percent) - 0.47 → 47% - as(format = currency, code = USD) - 2000 → $2,000 - as(format = bitrate) - 1500000 → 1.5 Mbps

Step 4: Filter the Results

Let's find only Windows 11 devices.

Query:

devices
| where operating_system.name == "Windows 11"
| list device.name,
       operating_system.name,
       hardware.memory.as(format = bytes)
| limit 10

What's new:

  • | where operating_system.name == "Windows 11" - Filter to only Windows 11

Expected output:

device.name  | operating_system.name | hardware.memory
-------------|----------------------|----------------
LAPTOP-001   | Windows 11           | 16 GB
DESKTOP-005  | Windows 11           | 32 GB
LAPTOP-045   | Windows 11           | 8 GB

Only Windows 11 devices are shown now!

Common Filters

/* Equals */
| where operating_system.name == "Windows 11"

/* Greater than */
| where hardware.memory > 8589934592  # More than 8GB

/* In a list */
| where operating_system.name in ["Windows 10", "Windows 11"]

/* Wildcards */
| where device.name = "LAPTOP*"

Step 5: Add Performance Data (Events)

Now let's add CPU usage data from the past week.

Query:

devices during past 7d
| where operating_system.name == "Windows 11"
| include device_performance.events
| compute avg_cpu = cpu_usage.avg()
| list device.name,
       operating_system.name,
       avg_cpu
| limit 10

What's new:

  • during past 7d - Look at data from the past 7 days
  • | include device_performance.events - Bring in performance metrics
  • | compute avg_cpu = cpu_usage.avg() - Calculate average CPU usage per device

Expected output:

device.name  | operating_system.name | avg_cpu
-------------|----------------------|--------
LAPTOP-001   | Windows 11           | 45.2
DESKTOP-005  | Windows 11           | 32.8
LAPTOP-045   | Windows 11           | 67.3

Now we're seeing actual performance data!

Why "during past 7d"?

Event tables (like device_performance.events) require a time window. Object tables (like devices) don't, but when you add events with include, you must specify the time.

Step 6: Format and Sort

Let's format the CPU percentage and show the busiest devices first.

Query:

devices during past 7d
| where operating_system.name == "Windows 11"
| include device_performance.events
| compute avg_cpu = cpu_usage.avg()
| list device.name,
       operating_system.name,
       avg_cpu.as(format = percent)
| sort avg_cpu desc
| limit 10

What's new:

  • avg_cpu.as(format = percent) - Format as percentage
  • | sort avg_cpu desc - Sort by CPU (highest first)

Expected output:

device.name  | operating_system.name | avg_cpu
-------------|----------------------|--------
LAPTOP-045   | Windows 11           | 67%
LAPTOP-001   | Windows 11           | 45%
DESKTOP-005  | Windows 11           | 33%

Perfect! Now you can see which Windows 11 devices are working hardest.

Step 7: Add More Filters

Let's find Windows 11 devices with high CPU usage (over 50%).

Query:

devices during past 7d
| where operating_system.name == "Windows 11"
| include device_performance.events
| compute avg_cpu = cpu_usage.avg()
| where avg_cpu > 50
| list device.name,
       operating_system.name,
       avg_cpu.as(format = percent)
| sort avg_cpu desc
| limit 10

What's new:

  • | where avg_cpu > 50 - Filter to CPU > 50% (this comes AFTER compute!)

Expected output:

device.name  | operating_system.name | avg_cpu
-------------|----------------------|--------
LAPTOP-045   | Windows 11           | 67%
LAPTOP-089   | Windows 11           | 58%
DESKTOP-022  | Windows 11           | 52%

Now we're only seeing devices that might need attention!

Two "where" Clauses?

Yes! You can filter multiple times: - First where filters devices (operating system) - Second where filters computed results (CPU usage)

Your Complete First Query

Here's a full query that combines everything you've learned:

/* Find Windows 11 devices with high average CPU usage */
devices during past 7d
| where operating_system.name == "Windows 11"
| include device_performance.events
| compute
    avg_cpu = cpu_usage.avg(),
    peak_cpu = cpu_usage.avg.max(),
    avg_memory_free = free_memory.avg()
| where avg_cpu > 50
| list device.name,
       operating_system.name,
       avg_cpu.as(format = percent),
       peak_cpu.as(format = percent),
       avg_memory_free.as(format = bytes)
| sort avg_cpu desc
| limit 20

Adding Comments

NQL now supports comments using /* */ syntax! Use them to document your queries:

/* Query purpose: Find high CPU devices
   Author: IT Team
   Last updated: 2026-01-09 */
devices during past 7d
/* Filter to Windows 11 only */
| where operating_system.name == "Windows 11"
| include device_performance.events
| compute avg_cpu = cpu_usage.avg()

Important: Comments work between clauses, not within them!

This query: 1. Starts with devices table 2. Looks at data from past 7d 3. Filters to Windows 11 only 4. Includes performance events 5. Computes average CPU, peak CPU, and free memory 6. Filters to devices with >50% average CPU 7. Lists relevant fields with formatting 8. Sorts by CPU (highest first) 9. Shows top 20 results

Result: A list of Windows 11 devices that might be experiencing performance issues!

Common Beginner Mistakes

Mistake 1: Missing Time Window on Events

/* ❌ WRONG - Missing time window */
devices
| include device_performance.events  # ERROR!
| compute avg_cpu = cpu_usage.avg()

/* ✅ CORRECT - Time window specified */
devices during past 7d
| include device_performance.events
| compute avg_cpu = cpu_usage.avg()

Mistake 2: Using = Instead of ==

/* ❌ WRONG - Single equals */
| where operating_system.name = "Windows 11"  # ERROR!

/* ✅ CORRECT - Double equals (or ==) */
| where operating_system.name == "Windows 11"

Note: Both = and == actually work in NQL, but == is more explicit and recommended.

Mistake 3: Wrong Clause Order

/* ❌ WRONG - limit before sort */
devices
| limit 10
| sort device.name asc
/* Sorts only the 10 devices, not all devices! */

/* ✅ CORRECT - sort before limit */
devices
| sort device.name asc
| limit 10
/* Sorts all devices, then shows top 10 */

Mistake 4: Filtering Before Computing

/* ❌ WRONG - Filter computed value before computing it */
devices during past 7d
| where avg_cpu > 50  # ERROR - avg_cpu doesn't exist yet!
| include device_performance.events
| compute avg_cpu = cpu_usage.avg()

/* ✅ CORRECT - Compute first, then filter */
devices during past 7d
| include device_performance.events
| compute avg_cpu = cpu_usage.avg()
| where avg_cpu > 50

Mistake 5: Missing "limit" During Development

/* ⚠️ SLOW - Returns all devices (could be thousands!) */
devices during past 30d
| include execution.events
| compute avg_cpu = cpu_time.avg()
/* Takes 10+ seconds... */

/* ✅ FAST - Limit to 10 for testing */
devices during past 1d  # Also use shorter time window
| include execution.events
| compute avg_cpu = cpu_time.avg()
| limit 10
/* Takes <1 second */

Practice Exercises

Try writing these queries on your own:

Exercise 1: Basic Device List

Goal: List all devices with their OS and last seen time

Click to see solution
devices
| list device.name,
       operating_system.name,
       last_seen
| limit 10

Exercise 2: Filter by Platform

Goal: Find all Windows devices (any version)

Click to see solution
devices
| where operating_system.platform == windows
| list device.name,
       operating_system.name
| limit 10

Exercise 3: Devices with Low Disk Space

Goal: Find devices with less than 20GB free disk space

Click to see solution
devices during past 7d
| include device_performance.events
| compute free_space_gb = free_disk_space.last() / 1000
| where free_space_gb < 20
| list device.name,
       operating_system.name,
       free_space_gb.as(format = bytes)
| sort free_space_gb asc
| limit 10

Exercise 4: Application Crash Count

Goal: Count crashes per application in the past 7 days

Click to see solution
execution.crashes during past 7d
| summarize crash_count = count() by application.name
| sort crash_count desc
| limit 10

Next Steps

Now that you've written your first queries, explore these topics:

Learn more syntax:

Understand the data model:

Get productive quickly:

Troubleshooting:

Quick Reference: Query Structure

Every query follows this general pattern:

/* 1. Start with a table */
<table> [during past Xd]

/* 2. Filter early (optional but recommended) */
| where <condition>

/* 3. Join events if needed (optional) */
| include <event_table>

/* 4. Calculate metrics (optional) */
| compute <variable> = <calculation>

/* 5. Filter computed results (optional) */
| where <computed_condition>

/* 6. Select fields to display */
| list <field1>, <field2>, ...

/* 7. Order results (optional) */
| sort <field> asc/desc

/* 8. Limit results (recommended during development) */
| limit 10

Not every query needs all these parts! Start simple and add complexity as needed.

Tips for Success

Start Simple, Build Incrementally

Don't try to write the perfect query on the first try. Build it step by step: 1. Start with just the table and limit 2. Add one filter 3. Add the include/compute 4. Add formatting and sorting 5. Remove/adjust limit for production

Always Use limit During Development

Add | limit 10 to every query while you're learning. Remove it when you're ready to see all results.

Use Short Time Windows for Testing

  • Development: past 1d or past 1h
  • Testing: past 7d
  • Production: past 7d to past 30d as needed

Copy Examples and Modify Them

Find a query that's close to what you need (from Common Query Templates or this guide), then modify: - Change the table name - Change the filters - Change the fields in list - Adjust the time window

Comment Your Queries

/* This helps you (and others) understand your query later! */
devices during past 7d
/* Only Windows 11 */
| where operating_system.name == "Windows 11"
| include device_performance.events
/* Calculate average CPU */
| compute avg_cpu = cpu_usage.avg()
/* High CPU only */
| where avg_cpu > 50
| list device.name, avg_cpu.as(format = percent)
/* Highest first */
| sort avg_cpu desc
/* Top 20 devices */
| limit 20

Remember: Comments work between clauses using /* */, not within them!

You're Ready!

Congratulations! You now know how to:

  • ✅ Query the devices table
  • ✅ Filter results with where
  • ✅ Add time windows for events
  • ✅ Include performance data
  • ✅ Compute metrics
  • ✅ Format output
  • ✅ Sort and limit results

You're ready to write real NQL queries!

Start with the exercises above, then explore Common Query Templates for more real-world examples.

Additional Resources