Monitor reasoner usage
Monitor reasoner usage by setting up the app’s observability views. This guide shows you how to set up monitoring and use it to check reasoner health, compare trends over time, and build a Snowsight dashboard.
- The RAI Native App is installed in your Snowflake account.
- You can run SQL in Snowflake with an active warehouse.
- You have
SELECTaccess on the active Snowflake Event Table.
How monitoring works
Section titled “How monitoring works”The Native App uses Snowflake’s Event Table to report internal metrics about reasoner usage, including memory, CPU, and demand.
To access those metrics, you create a secure view that filters the Event Table for relevant app-shared metric rows, then register that view with the app so it can read the metrics and make them available in the relationalai.observability_preview schema.
Register a secure events view with the RAI Native App
Section titled “Register a secure events view with the RAI Native App”Requires the observability_admin application role.
-
Find the active Event Table
Use the account setting first so the rest of the SQL points at the right table.
SHOW PARAMETERS LIKE 'EVENT_TABLE' IN ACCOUNT;SHOW TABLES LIKE 'EVENTS' IN SCHEMA SNOWFLAKE.TELEMETRY; -
Enable change tracking if needed
Registration fails if change tracking is disabled on the Event Table.
ALTER TABLE SNOWFLAKE.TELEMETRY.EVENTSSET CHANGE_TRACKING = TRUE; -
Create the filtered secure view
Create the view in a database and schema that you own. The filter keeps the view limited to shared RAI metric rows.
CREATE DATABASE IF NOT EXISTS MONITORING;-- Change the schema name if needed.CREATE SCHEMA IF NOT EXISTS MONITORING.RAI_OBSERVABILITY;CREATE OR REPLACE SECURE VIEW MONITORING.RAI_OBSERVABILITY.RAI_OBSCOMMENT = 'RelationalAI Native App observability filtered events view'CHANGE_TRACKING = TRUEASSELECTtimestamp,value,record,record_attributesFROM SNOWFLAKE.TELEMETRY.EVENTSWHERE record_type = 'METRIC'AND resource_attributes['snow.database.name']::STRING = 'RELATIONALAI'AND record_attributes['snow.application.shared']::BOOLEAN = TRUE; -
Register the view with the app
Registration stores a persistent reference that the app uses to read the filtered telemetry.
CALL RELATIONALAI.app.REGISTER_EVENTS_VIEW(SYSTEM$REFERENCE('view','MONITORING.RAI_OBSERVABILITY.RAI_OBS','PERSISTENT','SELECT')); -
Validate the registration
Do not continue until the status check is healthy.
CALL RELATIONALAI.app.CHECK_EVENTS_VIEW_STATUS();Events view activemeans the configuration is valid and events are flowing.No events view registeredmeans setup is incomplete.ERRORmeans the registration exists but the app cannot use it yet.
View recent reasoner usage
Section titled “View recent reasoner usage”Requires the observability_viewer application role.
You can check reasoner health by looking at recent memory, CPU, and demand readings. Use the following queries as a starting point, then adjust the time filters and aggregation as needed.
| What to do | When to do it |
|---|---|
| Check recent memory readings | See how much memory a reasoner is using compared to its capacity. |
| Check recent CPU readings | See how much CPU a reasoner is using compared to its capacity. |
| Check recent demand | See how many requests a reasoner is handling compared to its capacity. |
Check recent memory readings
Section titled “Check recent memory readings”To see how much of a reasoner’s available memory is currently in use, query the MEMORY_UTILIZATION column from the logic_reasoner__memory_utilization view.
MEMORY_UTILIZATION is already reported as a ratio from 0.0 to 1.0, so you do not need a separate memory-capacity column to interpret it.
SELECT REASONER_NAME, MEMORY_UTILIZATION, TIMESTAMPFROM RELATIONALAI.observability_preview.logic_reasoner__memory_utilizationWHERE TIMESTAMP >= DATEADD(minute, -5, CURRENT_TIMESTAMP())ORDER BY TIMESTAMP DESC;REASONER_NAMEshows which reasoner each reading belongs to.MEMORY_UTILIZATIONshows memory use as a fraction of available memory, where0.50means about half of the available memory is in use and1.0means the reasoner is at its memory limit.TIMESTAMPshows when Snowflake recorded the reading.WHERE TIMESTAMP >= DATEADD(minute, -5, CURRENT_TIMESTAMP())limits the query to a short recent window so you can check current health without scanning older readings.ORDER BY TIMESTAMP DESCshows the newest readings first.
Check recent CPU readings
Section titled “Check recent CPU readings”To see how much of a reasoner’s available CPU is currently in use, query the CPU_UTILIZATION column from the logic_reasoner__cpu_utilization view.
CPU_UTILIZATION is already reported as a ratio from 0.0 to 1.0, so you do not need a separate CPU-capacity column to interpret it.
SELECT REASONER_ID, REASONER_NAME, CPU_UTILIZATION, TIMESTAMPFROM RELATIONALAI.observability_preview.logic_reasoner__cpu_utilizationWHERE TIMESTAMP >= DATEADD(hour, -1, CURRENT_TIMESTAMP())ORDER BY TIMESTAMP DESC;REASONER_IDandREASONER_NAMEidentify which reasoner each reading belongs to.CPU_UTILIZATIONshows CPU use as a fraction of available CPU, where0.50means about half of the available CPU is in use and1.0means the reasoner is at its CPU limit.TIMESTAMPshows when Snowflake recorded the reading.WHERE TIMESTAMP >= DATEADD(hour, -1, CURRENT_TIMESTAMP())keeps the query focused on recent activity without scanning older readings.ORDER BY TIMESTAMP DESCshows the newest readings first.
Check recent demand
Section titled “Check recent demand”To see whether a reasoner is keeping up with recent work, query the DEMAND column from the logic_reasoner__demand view.
DEMAND reports job demand as a ratio, and values above 1.0 generally indicate that work is queueing.
SELECT REASONER_NAME, DEMAND, REASONER_CAPACITY, TIMESTAMPFROM RELATIONALAI.observability_preview.logic_reasoner__demandWHERE REASONER_NAME = 'my_reasoner' AND TIMESTAMP >= DATEADD(hour, -1, CURRENT_TIMESTAMP())ORDER BY TIMESTAMP DESC;REASONER_NAMEidentifies which reasoner each reading belongs to.DEMANDshows job demand as a ratio. Values below1.0mean the reasoner is handling the current workload without queueing, while values above1.0generally indicate queued work.REASONER_CAPACITYshows the capacity tier assigned to the reasoner, such asHIGHMEM_X64_SorHIGHMEM_X64_M, so you can see which tier produced the reading.TIMESTAMPshows when Snowflake recorded the reading.WHERE REASONER_NAME = 'my_reasoner'narrows the query to one reasoner. Replace'my_reasoner'with the reasoner you want to inspect.AND TIMESTAMP >= DATEADD(hour, -1, CURRENT_TIMESTAMP())limits the query to recent demand readings.ORDER BY TIMESTAMP DESCshows the newest readings first.
Compare reasoner trends over time
Section titled “Compare reasoner trends over time”Requires the observability_viewer application role.
You can compare reasoner trends over time by aggregating memory, CPU, and demand readings into larger time buckets. Use the following queries as a starting point, then adjust the time filters and bucket sizes as needed.
| What to do | When to do it |
|---|---|
| Compare memory trends | See whether high memory usage is a one-off spike or a recurring pattern. |
| Compare CPU trends | See whether heavy CPU usage is sustained or limited to short bursts. |
| Compare demand trends | See whether queued work is isolated to a short window or recurring over time. |
| Compare multiple metrics together | See how memory, CPU, and demand relate to each other during the same time buckets. |
Compare memory trends
Section titled “Compare memory trends”To see whether memory pressure is sustained over time, aggregate MEMORY_UTILIZATION readings from the logic_reasoner__memory_utilization view into daily buckets.
Looking at both the average and peak values helps you distinguish recurring pressure from isolated spikes.
SELECT DATE_TRUNC('day', TIMESTAMP) AS day, REASONER_NAME, AVG(MEMORY_UTILIZATION) AS avg_memory_utilization, MAX(MEMORY_UTILIZATION) AS peak_memory_utilizationFROM RELATIONALAI.observability_preview.logic_reasoner__memory_utilizationWHERE TIMESTAMP >= DATEADD(day, -7, CURRENT_TIMESTAMP())GROUP BY 1, 2ORDER BY day DESC, REASONER_NAME;DATE_TRUNC('day', TIMESTAMP) AS daygroups readings into daily buckets so you can compare one day with another.REASONER_NAMEshows which reasoner each aggregated row belongs to.AVG(MEMORY_UTILIZATION) AS avg_memory_utilizationshows the average memory use for that day.MAX(MEMORY_UTILIZATION) AS peak_memory_utilizationshows the highest memory reading recorded during that day.WHERE TIMESTAMP >= DATEADD(day, -7, CURRENT_TIMESTAMP())limits the scan to the last 7 days so you can spot recent patterns without pulling older history.
Compare CPU trends
Section titled “Compare CPU trends”To see whether CPU pressure is sustained over time, aggregate CPU_UTILIZATION readings from the logic_reasoner__cpu_utilization view into hourly buckets.
Hourly buckets make it easier to see whether heavy CPU usage is persistent or concentrated in a few short bursts.
SELECT REASONER_NAME, DATE_TRUNC('hour', TIMESTAMP) AS hour, AVG(CPU_UTILIZATION) AS avg_cpu_utilization, MAX(CPU_UTILIZATION) AS peak_cpu_utilizationFROM RELATIONALAI.observability_preview.logic_reasoner__cpu_utilizationWHERE TIMESTAMP >= DATEADD(hour, -24, CURRENT_TIMESTAMP())GROUP BY REASONER_NAME, hourORDER BY hour DESC, REASONER_NAME;REASONER_NAMEshows which reasoner each aggregated row belongs to.DATE_TRUNC('hour', TIMESTAMP) AS hourgroups readings into hourly buckets so short-lived spikes do not dominate the view.AVG(CPU_UTILIZATION) AS avg_cpu_utilizationshows the average CPU use during each hour.MAX(CPU_UTILIZATION) AS peak_cpu_utilizationshows the highest CPU reading recorded during that hour.WHERE TIMESTAMP >= DATEADD(hour, -24, CURRENT_TIMESTAMP())keeps the query focused on the last 24 hours so you can compare recent busy periods.
Compare demand trends
Section titled “Compare demand trends”To see whether queued work is building over time, aggregate DEMAND readings from the logic_reasoner__demand view into hourly buckets.
Keeping REASONER_CAPACITY visible helps you compare observed demand with the capacity tier assigned to each reasoner.
SELECT REASONER_NAME, REASONER_CAPACITY, DATE_TRUNC('hour', TIMESTAMP) AS hour, AVG(DEMAND) AS avg_demand, MAX(DEMAND) AS peak_demandFROM RELATIONALAI.observability_preview.logic_reasoner__demandWHERE TIMESTAMP >= DATEADD(hour, -24, CURRENT_TIMESTAMP())GROUP BY REASONER_NAME, REASONER_CAPACITY, hourORDER BY hour DESC, REASONER_NAME;REASONER_NAMEidentifies which reasoner each aggregated row belongs to.REASONER_CAPACITYshows the capacity tier assigned to that reasoner so you can interpret the demand readings in context.DATE_TRUNC('hour', TIMESTAMP) AS hourgroups demand readings into hourly buckets so you can see whether queueing is recurring.AVG(DEMAND) AS avg_demandshows the average demand during each hour.MAX(DEMAND) AS peak_demandshows the highest demand reading recorded during that hour.WHERE TIMESTAMP >= DATEADD(hour, -24, CURRENT_TIMESTAMP())limits the query to the last 24 hours so you can compare recent workload trends.
Compare multiple metrics together
Section titled “Compare multiple metrics together”Requires the observability_viewer application role.
Use a combined query when you need to compare memory, CPU, and demand in the same recent time buckets. Because joins across preview metric views cost more than single-view queries, keep the input window short.
SELECT m.REASONER_NAME, m.REASONER_ID, TIME_SLICE(m.TIMESTAMP, 10, 'SECOND') AS time_bucket, AVG(m.MEMORY_UTILIZATION) AS memory_utilization, AVG(c.CPU_UTILIZATION) AS cpu_utilization, AVG(d.DEMAND) AS avg_demandFROM RELATIONALAI.observability_preview.logic_reasoner__memory_utilization AS mJOIN RELATIONALAI.observability_preview.logic_reasoner__cpu_utilization AS c ON m.REASONER_ID = c.REASONER_ID AND TIME_SLICE(m.TIMESTAMP, 10, 'SECOND') = TIME_SLICE(c.TIMESTAMP, 10, 'SECOND')JOIN RELATIONALAI.observability_preview.logic_reasoner__demand AS d ON m.REASONER_ID = d.REASONER_ID AND TIME_SLICE(m.TIMESTAMP, 10, 'SECOND') = TIME_SLICE(d.TIMESTAMP, 10, 'SECOND')WHERE m.TIMESTAMP >= DATEADD(hour, -1, CURRENT_TIMESTAMP()) AND c.TIMESTAMP >= DATEADD(hour, -1, CURRENT_TIMESTAMP()) AND d.TIMESTAMP >= DATEADD(hour, -1, CURRENT_TIMESTAMP())GROUP BY 1, 2, 3ORDER BY time_bucket DESCLIMIT 10;The shared TIME_SLICE() bucket is what makes the comparison meaningful.
Without it, the three metric streams would rarely line up on exactly the same timestamps.
Build a Snowsight dashboard
Section titled “Build a Snowsight dashboard”Requires the observability_viewer application role.
Start with one bounded query rather than a broad dashboard. That keeps the first dashboard cheap to run and easier to interpret.
-
Run a bounded monitoring query in Snowsight
A good starting point is the hourly CPU summary:
SELECTREASONER_NAME,DATE_TRUNC('hour', TIMESTAMP) AS hour,AVG(CPU_UTILIZATION) AS avg_cpu_utilization,MAX(CPU_UTILIZATION) AS peak_cpu_utilizationFROM RELATIONALAI.observability_preview.logic_reasoner__cpu_utilizationWHERE TIMESTAMP >= DATEADD(hour, -24, CURRENT_TIMESTAMP())GROUP BY REASONER_NAME, hourORDER BY hour DESC, REASONER_NAME; -
Create a time-series chart
After the query finishes, select Chart above the results table. Snowsight generates a chart automatically.
If it does not choose a line chart:
- Select the chart-type control and switch it to Line.
- In the Data section, keep
houras the time column on the x-axis. - Use
avg_cpu_utilizationorpeak_cpu_utilizationas the y-axis value. - If you want one line per reasoner, keep
REASONER_NAMEin the chart so Snowsight splits the series by reasoner.
-
Save the chart to a dashboard
- On the worksheet tab, hover over the worksheet name, select the worksheet More actions menu, then select Move to.
- To create a new dashboard, select New dashboard, enter a name such as
Reasoner monitoring, and then select Create Dashboard. - To add the chart to an existing dashboard instead, select that dashboard from the Move to menu. Snowsight moves the worksheet into the dashboard and creates a tile from it.
- Keep the bounded time filter in the saved query so the tile stays cheap to run.