SWIS query performance best practices

Last updated: 2026-05-24

Practical guidance for writing SWIS / SWQL queries that don't punish your Orion server. Indexing, joins, filtering, and the patterns that scale to hundreds of nodes without bringing the polling engine to its knees.

If you write SWIS queries against the SolarWinds Orion Platform — for reports, custom dashboards, third-party integrations, or anything else — you've probably noticed that some queries return instantly and others lock up the web console for 30 seconds. The difference is rarely about how much data you ask for. It's about how you ask.

This is a set of patterns that have held up across the Orion installs we've built integrations against. The advice applies whether you're writing SWQL by hand, building a Grafana panel, or designing a custom integration like PocketNOC.

1. Always filter on indexed columns when possible

The Orion database has indexes on the columns SolarWinds expects you to filter on most often — NodeID, IPAddress, EngineID, Status. Filtering on these is fast even on installs with thousands of nodes. Filtering on Caption LIKE '%foo%' is a full table scan and gets slow at scale.

If you find yourself doing string matching on node names regularly, consider adding a custom property with a normalized identifier you can filter on cleanly.

2. Don't SELECT * from Orion.NPM.Interfaces

The Interfaces entity has 60+ columns including some that are computed on the fly. Selecting all of them when you only need Caption, Status, and InBps makes Orion do work it doesn't need to. Pick the columns you want.

This advice generalizes — selecting only the columns you'll use is good practice for any SWIS entity, but Orion.NPM.Interfaces is the one where it shows up most painfully.

3. Prefer navigation properties to manual joins

Bad:

SELECT n.Caption, i.Caption
FROM Orion.NPM.Interfaces i
JOIN Orion.Nodes n ON i.NodeID = n.NodeID

Better:

SELECT Node.Caption, Caption
FROM Orion.NPM.Interfaces

Node here is a navigation property — Orion knows the relationship and uses the indexed join under the hood. SWQL converts your query to native SQL more efficiently when you use navigation properties than when you specify joins manually.

4. Use entity-specific filters for status

Status codes mean the same thing across most entities:

If you want "everything that's actually bad right now," WHERE Status IN (2, 3, 9) is universal across Orion.Nodes, Orion.NPM.Interfaces, Orion.SAM.Applications, etc.

5. Don't poll SWIS every 5 seconds for "real-time" data

SWIS is designed for read operations against the same database the alert engine polls every 60 seconds. Hammering SWIS faster than the underlying poller refreshes is wasted effort — the data isn't updating that quickly.

A 30-second poll interval is reasonable for a mobile client. A 60-second poll is fine for a dashboard. 5-second polls put load on the Orion server and don't get you newer data.

PocketNOC uses a 30-second active poll when the app is foregrounded, longer intervals when backgrounded, and on-demand pull when the user explicitly refreshes. This keeps the per-device load on Orion well under what one analyst running the web console all day generates.

6. Push filters into the query, not the post-processing

If you're going to filter results down to "nodes in the East region," do it with WHERE CustomProperties.Region = 'East' in the SWQL, not by pulling all nodes and filtering in your app code. Orion can use the index; your post-processing can't.

7. Pagination matters for large result sets

For entities with thousands of rows (interfaces, NetFlow records, IPAM addresses), use SWIS pagination instead of pulling everything at once. The web console paginates by default at 20-50 rows; your integration probably should too.

SWIS supports paging via Page and RowsPerPage parameters on the REST endpoint. The HTTP response includes a TotalRows field so you know how much is left.

8. Be careful with computed properties

Some SWIS columns are computed at query time rather than stored. Orion.Nodes.NextRediscovery, Orion.Nodes.ChildStatus and similar are evaluated per-row when you select them. If you don't need them, don't include them in your SELECT clause.

9. Acknowledge the polling cost of joins across modules

A query that joins Orion.Nodes with Orion.NPM.Interfaces with Orion.NetFlow.Flows with Orion.NCM.NodeProperties is doing real work — even if the result set is small. If you need data from four modules, consider whether four targeted queries (parallelized in your app) would actually be faster than one giant join.

10. Read the Orion SDK docs

SolarWinds publishes a Python SDK with documented patterns for common queries. Reading the SDK source is one of the better ways to learn how SolarWinds' own engineers expect SWIS to be used. Even if you don't use Python, the query patterns translate.

Wrap

SWIS rewards thinking about what data you actually need before you write the query. The Orion data model is large enough that "select everything and figure it out later" works fine on a small install and falls over on a big one. The patterns above are the ones we've found move the needle most often.

For PocketNOC specifically, every screen is backed by a SWQL query designed against these rules — minimal columns, indexed filters, navigation properties, batched per-screen. That's why the app stays responsive on Orion installs with thousands of monitored nodes.

Jason Lazerus — Founder, WeaveHub Technologies — 20+ years network and security engineering