Skip to content

This feature is currently in Preview.

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 SELECT access on the active Snowflake Event Table.

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”
  1. 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;
  2. Enable change tracking if needed

    Registration fails if change tracking is disabled on the Event Table.

    ALTER TABLE SNOWFLAKE.TELEMETRY.EVENTS
    SET CHANGE_TRACKING = TRUE;
  3. 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_OBS
    COMMENT = 'RelationalAI Native App observability filtered events view'
    CHANGE_TRACKING = TRUE
    AS
    SELECT
    timestamp,
    value,
    record,
    record_attributes
    FROM SNOWFLAKE.TELEMETRY.EVENTS
    WHERE record_type = 'METRIC'
    AND resource_attributes['snow.database.name']::STRING = 'RELATIONALAI'
    AND record_attributes['snow.application.shared']::BOOLEAN = TRUE;
  4. 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'
    )
    );
  5. Validate the registration

    Do not continue until the status check is healthy.

    CALL RELATIONALAI.app.CHECK_EVENTS_VIEW_STATUS();

    Events view active means the configuration is valid and events are flowing. No events view registered means setup is incomplete. ERROR means the registration exists but the app cannot use it yet.

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 doWhen to do it
Check recent memory readingsSee how much memory a reasoner is using compared to its capacity.
Check recent CPU readingsSee how much CPU a reasoner is using compared to its capacity.
Check recent demandSee how many requests a reasoner is handling compared to its capacity.

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,
TIMESTAMP
FROM RELATIONALAI.observability_preview.logic_reasoner__memory_utilization
WHERE TIMESTAMP >= DATEADD(minute, -5, CURRENT_TIMESTAMP())
ORDER BY TIMESTAMP DESC;
  • REASONER_NAME shows which reasoner each reading belongs to.
  • MEMORY_UTILIZATION shows memory use as a fraction of available memory, where 0.50 means about half of the available memory is in use and 1.0 means the reasoner is at its memory limit.
  • TIMESTAMP shows 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 DESC shows the newest readings first.

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,
TIMESTAMP
FROM RELATIONALAI.observability_preview.logic_reasoner__cpu_utilization
WHERE TIMESTAMP >= DATEADD(hour, -1, CURRENT_TIMESTAMP())
ORDER BY TIMESTAMP DESC;
  • REASONER_ID and REASONER_NAME identify which reasoner each reading belongs to.
  • CPU_UTILIZATION shows CPU use as a fraction of available CPU, where 0.50 means about half of the available CPU is in use and 1.0 means the reasoner is at its CPU limit.
  • TIMESTAMP shows 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 DESC shows the newest readings first.

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,
TIMESTAMP
FROM RELATIONALAI.observability_preview.logic_reasoner__demand
WHERE REASONER_NAME = 'my_reasoner'
AND TIMESTAMP >= DATEADD(hour, -1, CURRENT_TIMESTAMP())
ORDER BY TIMESTAMP DESC;
  • REASONER_NAME identifies which reasoner each reading belongs to.
  • DEMAND shows job demand as a ratio. Values below 1.0 mean the reasoner is handling the current workload without queueing, while values above 1.0 generally indicate queued work.
  • REASONER_CAPACITY shows the capacity tier assigned to the reasoner, such as HIGHMEM_X64_S or HIGHMEM_X64_M, so you can see which tier produced the reading.
  • TIMESTAMP shows 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 DESC shows the newest readings first.

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 doWhen to do it
Compare memory trendsSee whether high memory usage is a one-off spike or a recurring pattern.
Compare CPU trendsSee whether heavy CPU usage is sustained or limited to short bursts.
Compare demand trendsSee whether queued work is isolated to a short window or recurring over time.
Compare multiple metrics togetherSee how memory, CPU, and demand relate to each other during the same time buckets.

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_utilization
FROM RELATIONALAI.observability_preview.logic_reasoner__memory_utilization
WHERE TIMESTAMP >= DATEADD(day, -7, CURRENT_TIMESTAMP())
GROUP BY 1, 2
ORDER BY day DESC, REASONER_NAME;
  • DATE_TRUNC('day', TIMESTAMP) AS day groups readings into daily buckets so you can compare one day with another.
  • REASONER_NAME shows which reasoner each aggregated row belongs to.
  • AVG(MEMORY_UTILIZATION) AS avg_memory_utilization shows the average memory use for that day.
  • MAX(MEMORY_UTILIZATION) AS peak_memory_utilization shows 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.

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_utilization
FROM RELATIONALAI.observability_preview.logic_reasoner__cpu_utilization
WHERE TIMESTAMP >= DATEADD(hour, -24, CURRENT_TIMESTAMP())
GROUP BY REASONER_NAME, hour
ORDER BY hour DESC, REASONER_NAME;
  • REASONER_NAME shows which reasoner each aggregated row belongs to.
  • DATE_TRUNC('hour', TIMESTAMP) AS hour groups readings into hourly buckets so short-lived spikes do not dominate the view.
  • AVG(CPU_UTILIZATION) AS avg_cpu_utilization shows the average CPU use during each hour.
  • MAX(CPU_UTILIZATION) AS peak_cpu_utilization shows 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.

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_demand
FROM RELATIONALAI.observability_preview.logic_reasoner__demand
WHERE TIMESTAMP >= DATEADD(hour, -24, CURRENT_TIMESTAMP())
GROUP BY REASONER_NAME, REASONER_CAPACITY, hour
ORDER BY hour DESC, REASONER_NAME;
  • REASONER_NAME identifies which reasoner each aggregated row belongs to.
  • REASONER_CAPACITY shows the capacity tier assigned to that reasoner so you can interpret the demand readings in context.
  • DATE_TRUNC('hour', TIMESTAMP) AS hour groups demand readings into hourly buckets so you can see whether queueing is recurring.
  • AVG(DEMAND) AS avg_demand shows the average demand during each hour.
  • MAX(DEMAND) AS peak_demand shows 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.

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_demand
FROM RELATIONALAI.observability_preview.logic_reasoner__memory_utilization AS m
JOIN 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, 3
ORDER BY time_bucket DESC
LIMIT 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.

Start with one bounded query rather than a broad dashboard. That keeps the first dashboard cheap to run and easier to interpret.

  1. Run a bounded monitoring query in Snowsight

    A good starting point is the hourly CPU summary:

    SELECT
    REASONER_NAME,
    DATE_TRUNC('hour', TIMESTAMP) AS hour,
    AVG(CPU_UTILIZATION) AS avg_cpu_utilization,
    MAX(CPU_UTILIZATION) AS peak_cpu_utilization
    FROM RELATIONALAI.observability_preview.logic_reasoner__cpu_utilization
    WHERE TIMESTAMP >= DATEADD(hour, -24, CURRENT_TIMESTAMP())
    GROUP BY REASONER_NAME, hour
    ORDER BY hour DESC, REASONER_NAME;
  2. 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 hour as the time column on the x-axis.
    • Use avg_cpu_utilization or peak_cpu_utilization as the y-axis value.
    • If you want one line per reasoner, keep REASONER_NAME in the chart so Snowsight splits the series by reasoner.
  3. 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.