Manage reasoners
Reasoners are virtual machines used by PyRel models deployed to Snowflake. They run in the RelationalAI (RAI) Native App’s dedicated Snowflake compute pools on Snowpark Container Services in your Snowflake account. This guide covers how to monitor reasoner usage, manage jobs, and adjust reasoner capacity for deployed models.
- Prerequisites
- The RAI Native App is installed and usable in your Snowflake account. See Set up RelationalAI in Snowflake.
What reasoners do
Section titled “What reasoners do”Deployed models use reasoners for the computations needed to produce and refresh their outputs. The reasoner type depends on the work the model needs:
| Type of reasoner | What it does |
|---|---|
| Logic reasoners | Evaluate PyRel model logic as part of refreshing model outputs, including the graph algorithms that need it. |
| Prescriptive reasoners | Run prescriptive reasoning workloads, like processing and solving decision problems defined in a PyRel model. |
| Predictive reasoners | Run predictive reasoning workloads, like training and using GNNs through PyRel. |
How reasoners are managed
Section titled “How reasoners are managed”PyRel creates and manages reasoners based on its configuration file and the workloads required by the model. For logic workloads in a deployed model, the refresh process creates the configured reasoner if it does not exist or resumes it if it is suspended. As an admin, you can:
- View and monitor reasoners and reasoner usage
- Manage warm (standby) reasoners to reduce startup delays when a deployed model needs a logic reasoner.
- Scale reasoner capacity to support deployed models’ workloads or reduce costs when workloads are lighter.
Monitor reasoner usage
Section titled “Monitor reasoner usage”Monitor reasoner usage with the app’s observability views. This guide shows you how to check reasoner health, compare trends over time, and build a dashboard in Snowsight, the Snowflake web interface.
How monitoring works
Section titled “How monitoring works”To run these monitoring queries, enable app observability and use Snowflake SQL with an active warehouse.
The Native App uses Snowflake’s Event Table to report internal metrics about reasoner usage, including memory, CPU, and demand.
Once app observability is enabled, the app makes those metrics available in the relationalai.observability_preview schema.
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 | Compare demand from model jobs with the reasoner’s 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.
Manage reasoner jobs
Section titled “Manage reasoner jobs”Use this section when you need to inspect reasoner work for a deployed model or stop work that should no longer continue. It shows how to list jobs, check one job in detail, and cancel a queued or running job with SQL, Python, or the CLI.
For the SQL examples, use a Snowflake session with an active warehouse. Have a reasoner name to list or filter its jobs, or a job ID to inspect or cancel a specific job.
What jobs are
Section titled “What jobs are”A RelationalAI job is a unit of work that runs on a reasoner. For a deployed model, reasoner jobs perform computations needed to refresh model outputs. Reasoners can also run other work, such as processing changes from data streams.
One reasoner can process more than one job at a time. Each reasoner supports concurrent jobs, and additional work can wait in that reasoner’s queue until capacity is available. That means a reasoner can be available and still feel slow if work is backing up in the queue rather than failing outright.
Concurrent jobs on the same reasoner may impact each other’s performance. Resource-intensive jobs may also increase wait time for other work on the same reasoner.
This guide helps you understand what jobs are running, how long they have been running, and whether any work has been cancelled or failed.
How jobs are managed
Section titled “How jobs are managed”PyRel and the RAI Native App create and submit jobs as work needs to run on a reasoner. As an admin, you use this page to inspect those jobs, check the state of one specific job, or cancel work that should no longer continue.
Use this table to choose the task that matches what you need next:
| What to do | When to do it |
|---|---|
| View all jobs | When a reasoner seems slow or blocked and you need to see which jobs are queued, running, or recently finished. |
| View jobs by status | When you need to interpret the current job states and decide whether work is waiting, running, completed, or failing. |
| Get job details | When you already have a job ID and need to inspect its state, duration, or abort reason more closely. |
| Cancel a job | When a queued or running job should no longer continue on the current reasoner. |
View all jobs
Section titled “View all jobs”Requires the eng_user application role.
Use the following interfaces to view all jobs for a reasoner:
Query the api.jobs view and filter by the REASONER_NAME column.
Add REASONER_TYPE if you want to narrow the results to one reasoner type:
-- List jobs for the reasoner named 'my_reasoner'.SELECT *FROM relationalai.api.jobsWHERE REASONER_NAME = 'my_reasoner' AND REASONER_TYPE = 'logic';+--------------------------------------+---------------+---------------+---------+----------------------+-------------------------------+-------------------------------+----------+------------------+------------+--------------+| ID | REASONER_TYPE | REASONER_NAME | STATE | CREATED_BY | CREATED_ON | FINISHED_AT | DURATION | PAYLOAD | TIMEOUT_MS | ABORT_REASON ||--------------------------------------+---------------+---------------+---------+----------------------+-------------------------------+-------------------------------+----------+------------------+------------+--------------|| 02c8fa31-1234-5678-90ab-abcdef123456 | logic | my_reasoner | ABORTED | john.doe@company.com | 2024-10-28 08:00:12.123 -0700 | 2024-10-28 08:00:19.766 -0700 | 7643 | {"kind":"query"} | 86400000 | canceled |+--------------------------------------+---------------+---------------+---------+----------------------+-------------------------------+-------------------------------+----------+------------------+------------+--------------+Create a client with connect() and call client.jobs.list():
from relationalai.client import connect
async with await connect() as client: jobs = await client.jobs.list("Logic", name="my_reasoner") print(jobs)Use the rai jobs list command and pass the reasoner name to --name:
# List jobs for the reasoner named 'my_reasoner'.rai jobs list --name my_reasonerStart with ID, STATE, CREATED_ON, FINISHED_AT, and ABORT_REASON.
Those fields are usually enough to decide whether you should inspect a job more closely or cancel work that should no longer continue.
View jobs by status
Section titled “View jobs by status”Use the STATE column to understand whether work is waiting, running, finished, or needs follow-up:
| State | Description |
|---|---|
CREATED | The job has been accepted by the native app but has not yet been sent to the reasoner queue. If it remains in this state, the reasoner’s resources may be at capacity, or the native app has not yet forwarded the job to the reasoner. |
QUEUED | The job is in the reasoner’s queue, waiting to be processed. If it remains in this state, the reasoner’s concurrency limit has been reached. Wait for the job to leave the queue or cancel it and rerun on a different reasoner. |
RUNNING | The job is currently being processed by the reasoner. A running job may complete normally, be cancelled, or end in an aborted state if an error occurs. |
COMPLETED | The job finished successfully. |
CANCELED | The job was cancelled and reached its final cancelled state. |
ABORTED | The job encountered an error or other issue. Check the ABORT_REASON column for more details. |
For API details about the STATE and ABORT_REASON columns, see the api.jobs SQL reference.
Get job details
Section titled “Get job details”Requires the eng_user application role.
Use the following interfaces to inspect one job in detail:
Pass the reasoner type and job ID to api.get_job():
-- Get details for the job with ID '02c8fa31-1234-5678-90ab-abcdef123456'.CALL relationalai.api.get_job('logic', '02c8fa31-1234-5678-90ab-abcdef123456');+--------------------------------------+---------------+---------------+-----------+----------------------+-------------------------------+-------------------------------+----------+------------------+------------+--------------+| ID | REASONER_TYPE | REASONER_NAME | STATE | CREATED_BY | CREATED_ON | FINISHED_AT | DURATION | PAYLOAD | TIMEOUT_MS | ABORT_REASON ||--------------------------------------+---------------+---------------+-----------+----------------------+-------------------------------+-------------------------------+----------+------------------+------------+--------------|| 02c8fa31-1234-5678-90ab-abcdef123456 | logic | my_reasoner | COMPLETED | john.doe@company.com | 2024-10-28 08:00:12.123 -0700 | 2024-10-28 08:00:19.766 -0700 | 7643 | {"kind":"query"} | 86400000 | NULL |+--------------------------------------+---------------+---------------+-----------+----------------------+-------------------------------+-------------------------------+----------+------------------+------------+--------------+Create a client with connect() and call client.jobs.get():
from relationalai.client import connect
async with await connect() as client: job = await client.jobs.get("Logic", "02c8fa31-1234-5678-90ab-abcdef123456") print(job)Use the rai jobs get command and pass the job ID to --id:
# Get details for the job with ID '02c8fa31-1234-5678-90ab-abcdef123456'.rai jobs get --id 02c8fa31-1234-5678-90ab-abcdef123456Read the result in this order: STATE, FINISHED_AT, DURATION, then ABORT_REASON.
If a job is ABORTED, start with ABORT_REASON, but do not assume it is always the full explanation.
Cancel a job
Section titled “Cancel a job”Requires the eng_user application role.
Use the following interfaces to cancel a queued or running job:
Pass the reasoner type and job ID to api.cancel_job():
-- Cancel the job with ID '02c8fa31-1234-5678-90ab-abcdef123456'.CALL relationalai.api.cancel_job('logic', '02c8fa31-1234-5678-90ab-abcdef123456');+------------------------+| Cancelling job |+------------------------+Create a client with connect() and call client.jobs.cancel():
from relationalai.client import connect
async with await connect() as client: await client.jobs.cancel("Logic", "02c8fa31-1234-5678-90ab-abcdef123456")Use the rai jobs cancel command and pass the job ID to --id:
# Cancel the job with ID '02c8fa31-1234-5678-90ab-abcdef123456'.rai jobs cancel --id 02c8fa31-1234-5678-90ab-abcdef123456It may take a few moments for the job to reach its final cancelled state.
Monitor the job again and confirm that STATE is reported as CANCELED.
Manage reasoners
Section titled “Manage reasoners”Manage logic reasoners
Section titled “Manage logic reasoners”Logic reasoners evaluate model logic when deployed models refresh their outputs. This guide explains how logic reasoners are created, how to inspect and manage them, and when to step in manually instead of relying on PyRel’s default behavior.
Use a Snowflake session with an active warehouse for the SQL examples.
The required application role is shown beside each task: eng_user for inspection and eng_admin for changes.
What logic reasoners do
Section titled “What logic reasoners do”A deployed model uses a logic reasoner when its refresh plan includes logic workloads. The reasoner evaluates the model’s logic to produce updated outputs. That includes the graph algorithms that use the logic reasoner.
By default, each user gets a dedicated logic reasoner. When a deployed model refreshes its logic outputs, the refresh process resumes the configured logic reasoner if it is suspended or creates one if it does not exist.
Which compute pools host logic reasoners is covered in Configure deployment.
How logic reasoners are created is covered in Configure deployment.
How logic reasoners handle jobs
Section titled “How logic reasoners handle jobs”One logic reasoner can process more than one job at a time. Each reasoner supports up to 8 concurrent jobs and a queue capacity of 128 jobs.
How logic reasoners are managed
Section titled “How logic reasoners are managed”Logic reasoners are managed automatically, including creating them when a deployed model’s refresh needs one. Each PyRel user gets a dedicated logic reasoner.
As an admin, you can perform the following actions on logic reasoners:
| What to do | When to do it |
|---|---|
| View all logic reasoners | When you want to confirm that a logic reasoner exists and see its high-level state. |
| Verify that a logic reasoner is ready | When you want to confirm that one specific logic reasoner is usable with its expected size and settings. |
| Change a logic reasoner’s auto-suspend settings | When you want to trade off lower cost against lower startup latency. |
| Manually suspend a logic reasoner | When you want to stop it from consuming compute while it is not needed. Jobs sent to a suspended reasoner fail until the reasoner is resumed again. |
| Manually resume a suspended logic reasoner | When you need it available before the next model refresh or when you want to confirm that the reasoner itself can start normally. |
| Delete a logic reasoner | When you no longer want to keep that reasoner instance or its current configuration. Deletion is stronger than suspension because it removes the reasoner entirely. |
View all logic reasoners
Section titled “View all logic reasoners”Requires the eng_user application role.
Use the list view when you want to confirm that a logic reasoner exists and see its high-level state.
SELECT *FROM relationalai.api.reasonersWHERE TYPE = 'logic';Start with NAME, SIZE, STATUS, AUTO_SUSPEND_MINS, and SUSPENDS_AT.
Those columns usually tell you whether the reasoner is ready to use, scheduled to suspend, or worth inspecting in more detail.
Verify that a logic reasoner is ready
Section titled “Verify that a logic reasoner is ready”Requires the eng_user application role.
Use the detail view when you want to confirm that one specific logic reasoner is usable with its expected size and settings.
CALL relationalai.api.get_reasoner('logic', 'my_reasoner');Confirm the following fields first:
STATUS = READYSIZEmatches the expected instance familyAUTO_SUSPEND_MINSmatches the current inactivity settingRUNTIME.compute_poolmatches the expected logic reasoner pool
If the reasoner exists but is not yet READY, wait for provisioning to complete and run the check again.
If it remains unavailable, continue with the troubleshooting section on this page.
Change a logic reasoner’s auto-suspend settings
Section titled “Change a logic reasoner’s auto-suspend settings”Requires the eng_admin application role.
Logic reasoners can be configured to automatically suspend after a period of inactivity, which can help reduce costs when logic workloads are infrequent. By default, newly created logic reasoners suspend after 60 minutes of inactivity unless you set a different value, but you can change this setting based on your workload patterns.
Execute the following to change the auto-suspend timer for a logic reasoner named my_reasoner to 30 minutes:
CALL relationalai.api.alter_reasoner_auto_suspend_mins('logic', 'my_reasoner', 30);Set the value to 0 to disable auto-suspension.
Manually suspend a logic reasoner
Section titled “Manually suspend a logic reasoner”Requires the eng_admin application role.
If you need to suspend a logic reasoner immediately, rather than waiting for the auto-suspend timer, you can do so manually.
Run the following to suspend a logic reasoner named my_reasoner:
CALL relationalai.api.suspend_reasoner('logic', 'my_reasoner');Use get_reasoner() to check the reasoner’s status and confirm that it has suspended successfully.
Manually resume a suspended logic reasoner
Section titled “Manually resume a suspended logic reasoner”Requires the eng_admin application role.
The model’s refresh process automatically resumes a logic reasoner when it needs to run logic work, but you can also resume it manually if you want it available immediately.
Run the following to resume a logic reasoner named my_reasoner:
CALL relationalai.api.resume_reasoner_async('logic', 'my_reasoner');It may take a few minutes for the reasoner to start up and become READY again.
Use get_reasoner() to check the reasoner’s status and confirm that it has resumed successfully.
Delete a logic reasoner
Section titled “Delete a logic reasoner”Requires the eng_admin application role.
Delete a logic reasoner when you no longer want to keep that reasoner instance or its current configuration. Deletion is stronger than suspension because it removes the reasoner entirely.
CALL relationalai.api.delete_reasoner('logic', 'my_reasoner');When a reasoner is deleted, all current and queued jobs are cancelled. If PyRel is still configured to use that reasoner name, it can recreate the reasoner later when needed.
Troubleshoot common issues with logic reasoners
Section titled “Troubleshoot common issues with logic reasoners”Use this table to match common logic-reasoner problems to the right next action:
| Symptom | Likely cause | What to do next |
|---|---|---|
| The expected logic reasoner does not exist. | The model has not needed it for a refresh yet, or the configured name does not match the reasoner you expected. | Confirm the current reasoners.logic configuration, then check the model’s refresh status. |
The reasoner exists but is not READY. | Provisioning is still in progress, or startup has stalled. | Wait briefly and run get_reasoner() again. If it does not recover, check broader app status. |
| The reasoner resumes slowly even though nothing is wrong. | The reasoner is auto-suspended and needs to start again. | Increase AUTO_SUSPEND_MINS or use warm reasoners if startup latency is the main problem. |
The reasoner is READY, but model refreshes are still slow. | Jobs may be queued or the reasoner may be under sustained load. | Use Monitor reasoner usage to inspect demand, CPU, and memory before changing the lifecycle settings. |
For adjacent workflows, see Operate RelationalAI and Configure reasoners.
Manage prescriptive reasoners
Section titled “Manage prescriptive reasoners”Prescriptive reasoners run the decision-problem and optimization workflows behind PyRel prescriptive reasoning. This guide explains how prescriptive reasoners are created, how to inspect and manage them, and how to interpret nearby docs that still use solver terminology.
Use a Snowflake session with an active warehouse for the SQL examples.
What prescriptive reasoners do
Section titled “What prescriptive reasoners do”Prescriptive workflows need a prescriptive reasoner. Prescriptive reasoners solve decision problems and optimization workloads defined in a model.
By default, each user gets a dedicated prescriptive reasoner. When a user runs a prescriptive workflow, PyRel uses the configured prescriptive reasoner, resumes it if it is suspended, or creates it if it does not exist.
Some existing docs still describe these workloads as solver workloads or solver reasoners.
On public configuration and reasoner-management surfaces, the supported reasoner type and config field are prescriptive.
Which compute pools host prescriptive reasoners is covered in Configure deployment.
How prescriptive reasoners are created is covered in Configure deployment.
How prescriptive reasoners handle jobs
Section titled “How prescriptive reasoners handle jobs”Prescriptive reasoners handle jobs that solve the model’s decision problems. Although a prescriptive reasoner can process more than one solve job at a time, concurrent solve jobs on the same reasoner may affect each other’s performance.
If performance issues arise, start by checking which jobs are queued or running on that reasoner before you change lifecycle settings using the APIs on this page.
How prescriptive reasoners are managed
Section titled “How prescriptive reasoners are managed”Prescriptive reasoners are fully managed by PyRel, including creating them if a prescriptive workflow needs one. By default, each PyRel user gets a dedicated prescriptive reasoner.
As an admin, you can perform the following actions on prescriptive reasoners:
| What to do | When to do it |
|---|---|
| View all prescriptive reasoners | When you want to confirm that a prescriptive reasoner exists and see its high-level state. |
| Verify that a prescriptive reasoner is ready | When you want to confirm that one specific prescriptive reasoner is usable with its expected size and settings. |
| Change a prescriptive reasoner’s auto-suspend settings | When you want to trade off lower cost against lower startup latency. |
| Manually suspend a prescriptive reasoner | When you want to stop it from consuming compute while it is not needed. Jobs sent to a suspended prescriptive reasoner fail until the reasoner is resumed again. |
| Manually resume a suspended prescriptive reasoner | When you need it available before the next solve or when you want to confirm that the reasoner itself can start normally. |
| Delete a prescriptive reasoner | When you no longer want to keep that reasoner instance or its current configuration. Deletion is stronger than suspension because it removes the reasoner entirely. |
View all prescriptive reasoners
Section titled “View all prescriptive reasoners”Requires the eng_user application role.
Use the list view when you want to confirm that a prescriptive reasoner exists and see its current lifecycle state.
SELECT *FROM relationalai.api.reasonersWHERE TYPE = 'prescriptive';Start with NAME, SIZE, STATUS, AUTO_SUSPEND_MINS, and SUSPENDS_AT.
Those columns usually tell you whether the reasoner is ready to use, scheduled to suspend, or worth inspecting in more detail.
Verify that a prescriptive reasoner is ready
Section titled “Verify that a prescriptive reasoner is ready”Requires the eng_user application role.
Use the detail view when you want to confirm that one specific prescriptive reasoner is usable with its expected size and settings.
CALL relationalai.api.get_reasoner('prescriptive', 'my_reasoner');Confirm the following fields first:
STATUS = READYSIZEmatches the expected prescriptive reasoner sizeAUTO_SUSPEND_MINSmatches the current inactivity settingRUNTIME.compute_poolmatches the expected high-memory pool
If the reasoner exists but is not yet READY, wait for provisioning to complete and check again.
If it remains unavailable, continue with the troubleshooting section on this page.
Change a prescriptive reasoner’s auto-suspend settings
Section titled “Change a prescriptive reasoner’s auto-suspend settings”Requires the eng_admin application role.
Prescriptive reasoners can be configured to automatically suspend after a period of inactivity, which can help reduce costs when prescriptive workloads are infrequent. By default, newly created prescriptive reasoners suspend after 60 minutes of inactivity unless you set a different value, but you can change this setting based on your workload patterns.
Execute the following to change the auto-suspend timer for a prescriptive reasoner named my_reasoner to 30 minutes:
CALL relationalai.api.alter_reasoner_auto_suspend_mins('prescriptive', 'my_reasoner', 30);Set the value to 0 to disable auto-suspension.
Manually suspend a prescriptive reasoner
Section titled “Manually suspend a prescriptive reasoner”Requires the eng_admin application role.
If you need to suspend a prescriptive reasoner immediately, rather than waiting for the auto-suspend timer, you can do so manually.
Run the following to suspend a prescriptive reasoner named my_reasoner:
CALL relationalai.api.suspend_reasoner('prescriptive', 'my_reasoner');Use get_reasoner() to check the reasoner’s status and confirm that it has suspended successfully.
Manually resume a suspended prescriptive reasoner
Section titled “Manually resume a suspended prescriptive reasoner”Requires the eng_admin application role.
PyRel will automatically resume a prescriptive reasoner when it needs to run a prescriptive workflow, but you can also resume it manually if you want it available immediately.
Run the following to resume a prescriptive reasoner named my_reasoner:
CALL relationalai.api.resume_reasoner_async('prescriptive', 'my_reasoner');It may take a few minutes for the reasoner to start up and become READY again.
Use get_reasoner() to check the reasoner’s status and confirm that it has resumed successfully.
Delete a prescriptive reasoner
Section titled “Delete a prescriptive reasoner”Requires the eng_admin application role.
Delete a prescriptive reasoner when you no longer want to keep that reasoner instance or its current configuration. Deletion is stronger than suspension because it removes the reasoner entirely.
CALL relationalai.api.delete_reasoner('prescriptive', 'my_reasoner');When a reasoner is deleted, all current and queued solve jobs are cancelled. If PyRel is still configured to use that reasoner name, it can recreate the reasoner later when needed.
Troubleshoot common issues with prescriptive reasoners
Section titled “Troubleshoot common issues with prescriptive reasoners”Use this table to match common prescriptive-reasoner problems to the right next action:
| Symptom | Likely cause | What to do next |
|---|---|---|
| The expected prescriptive reasoner does not exist. | PyRel has not needed it yet, or the configured name does not match the reasoner you expected. | Confirm the current reasoners.prescriptive configuration, then trigger the workflow that should use it or create the reasoner manually. |
The reasoner exists but is not READY. | Provisioning is still in progress, or startup has stalled. | Wait briefly and run get_reasoner() again. If it does not recover, check broader app status. |
| A solve workflow refers to a solver reasoner, but management docs say prescriptive. | The same public workload family is described with older solver terminology in some places. | Follow the public prescriptive config keys and reasoner-management APIs on this page. |
| The prescriptive reasoner resumes slowly even though nothing is wrong. | The reasoner is auto-suspended and needs to start again. | Increase AUTO_SUSPEND_MINS if startup latency is the main problem. |
Solve work backs up even though the reasoner is READY. | The bottleneck is likely queueing or capacity rather than reasoner lifecycle state. | Use Monitor reasoner usage and Scale reasoner capacity before changing reasoner lifecycle settings again. |
Manage predictive reasoners
Section titled “Manage predictive reasoners”Predictive reasoners run the compute behind PyRel predictive reasoning workflows. This guide explains how predictive reasoners are created, how to inspect and manage them, and what to check first when predictive workflows slow down.
Use a Snowflake session with an active warehouse for the SQL examples.
What predictive reasoners do
Section titled “What predictive reasoners do”Predictive workflows need a predictive reasoner. Predictive reasoners support PyRel predictive reasoning workflows, including Graph Neural Network (GNN) training and inference.
By default, each user gets a dedicated predictive reasoner. When a user runs a predictive workflow, PyRel uses the configured predictive reasoner, resumes it if it is suspended, or creates it if it does not exist.
This page covers the reasoner lifecycle only. For modeling, training, prediction, and run-level monitoring, refer to the predictive reasoning guides.
Which compute pools host predictive reasoners is covered in Configure deployment.
How predictive reasoners are created is covered in Configure deployment.
How predictive reasoners handle jobs
Section titled “How predictive reasoners handle jobs”Predictive reasoners handle model jobs such as GNN training and inference. Although a predictive reasoner can process more than one predictive job at a time, concurrent jobs on the same reasoner may affect each other’s performance.
If performance issues arise, start by checking which jobs are queued or running on that reasoner before you change lifecycle settings using the APIs on this page.
How predictive reasoners are managed
Section titled “How predictive reasoners are managed”Predictive reasoners are fully managed by PyRel, including creating them if a predictive workflow needs one. By default, each PyRel user gets a dedicated predictive reasoner.
As an admin, you can perform the following actions on predictive reasoners:
| What to do | When to do it |
|---|---|
| View all predictive reasoners | When you want to confirm that a predictive reasoner exists and see its high-level state. |
| Verify that a predictive reasoner is ready | When you want to confirm that one specific predictive reasoner is usable with its expected size and settings. |
| Change a predictive reasoner’s auto-suspend settings | When you want to trade off lower cost against lower startup latency. |
| Manually suspend a predictive reasoner | When you want to stop it from consuming compute while it is not needed. Work sent to a suspended predictive reasoner cannot run until the reasoner is resumed again. |
| Manually resume a suspended predictive reasoner | When you need it available before the next predictive workflow or when you want to confirm that the reasoner itself can start normally. |
| Delete a predictive reasoner | When you no longer want to keep that reasoner instance or its current configuration. Deletion is stronger than suspension because it removes the reasoner entirely. |
View all predictive reasoners
Section titled “View all predictive reasoners”Requires the eng_user application role.
Use the list view when you want to confirm that a predictive reasoner exists and see its high-level state.
SELECT *FROM relationalai.api.reasonersWHERE TYPE = 'predictive';Start with NAME, SIZE, STATUS, AUTO_SUSPEND_MINS, and SUSPENDS_AT.
Those columns usually tell you whether the reasoner is ready to use, scheduled to suspend, or worth inspecting in more detail.
Verify that a predictive reasoner is ready
Section titled “Verify that a predictive reasoner is ready”Requires the eng_user application role.
Use the detail view when you want to confirm that one specific predictive reasoner is usable with its expected size and settings.
CALL relationalai.api.get_reasoner('predictive', 'my_reasoner');Confirm the following fields first:
STATUS = READYSIZEmatches the expected predictive reasoner sizeAUTO_SUSPEND_MINSmatches the current inactivity settingRUNTIME.compute_poolmatches the expected predictive reasoner pool
If the reasoner exists but is not yet READY, wait for provisioning to complete and run the check again.
If it remains unavailable, continue with the troubleshooting section on this page.
Change a predictive reasoner’s auto-suspend settings
Section titled “Change a predictive reasoner’s auto-suspend settings”Requires the eng_admin application role.
Predictive reasoners can be configured to automatically suspend after a period of inactivity, which can help reduce costs when predictive workloads are infrequent. By default, newly created predictive reasoners suspend after 60 minutes of inactivity unless you set a different value, but you can change this setting based on your workload patterns.
Execute the following to change the auto-suspend timer for a predictive reasoner named my_reasoner to 30 minutes:
CALL relationalai.api.alter_reasoner_auto_suspend_mins('predictive', 'my_reasoner', 30);Set the value to 0 to disable auto-suspension.
Manually suspend a predictive reasoner
Section titled “Manually suspend a predictive reasoner”Requires the eng_admin application role.
If you need to suspend a predictive reasoner immediately, rather than waiting for the auto-suspend timer, you can do so manually.
Run the following to suspend a predictive reasoner named my_reasoner:
CALL relationalai.api.suspend_reasoner('predictive', 'my_reasoner');Use get_reasoner() to check the reasoner’s status and confirm that it has suspended successfully.
Manually resume a suspended predictive reasoner
Section titled “Manually resume a suspended predictive reasoner”Requires the eng_admin application role.
PyRel will automatically resume a predictive reasoner when it needs to run a predictive workflow, but you can also resume it manually if you want it available immediately.
Run the following to resume a predictive reasoner named my_reasoner:
CALL relationalai.api.resume_reasoner_async('predictive', 'my_reasoner');It may take a few minutes for the reasoner to start up and become READY again.
Use get_reasoner() to check the reasoner’s status and confirm that it has resumed successfully.
Delete a predictive reasoner
Section titled “Delete a predictive reasoner”Requires the eng_admin application role.
Delete a predictive reasoner when you no longer want to keep that reasoner instance or its current configuration. Deletion is stronger than suspension because it removes the reasoner entirely.
CALL relationalai.api.delete_reasoner('predictive', 'my_reasoner');When a reasoner is deleted, current and queued work for that reasoner is cancelled. If PyRel is still configured to use that reasoner name, it can recreate the reasoner later when needed.
Troubleshoot common issues with predictive reasoners
Section titled “Troubleshoot common issues with predictive reasoners”Use this table to match common predictive-reasoner problems to the right next action:
| Symptom | Likely cause | What to do next |
|---|---|---|
| The expected predictive reasoner does not exist. | PyRel has not needed it yet, or the configured name does not match the reasoner you expected. | Confirm the current reasoners.predictive configuration, then trigger the workflow that should use it or create the reasoner manually. |
The reasoner exists but is not READY. | Provisioning is still in progress, or startup has stalled. | Wait briefly and run get_reasoner() again. If it does not recover, check broader app status. |
| The predictive reasoner resumes slowly even though nothing is wrong. | The reasoner is auto-suspended and needs to start again. | Increase AUTO_SUSPEND_MINS if startup latency is the main problem. |
Training or inference work backs up even though the reasoner is READY. | The bottleneck is likely queued work or reasoner capacity rather than lifecycle state. | Use Manage reasoner jobs to inspect queued or running work, then Scale reasoner capacity if the same pattern keeps recurring. |
Enable warm reasoners
Section titled “Enable warm reasoners”Warm reasoners keep pre-provisioned logic reasoners ready so matching create or resume requests can start faster when warm capacity is available. Use this guide when startup latency is the main problem for logic reasoners and you want faster startup by keeping warm capacity ready, while accepting the additional cost of keeping it active.
Use a Snowflake session with an active warehouse for the SQL examples.
The warm-reasoner procedures require the app_admin application role, as noted beside each task.
When to use warm reasoners
Section titled “When to use warm reasoners”Warm reasoners are the right setting when startup latency is the main problem for a logic reasoner. If a request needs a logic reasoner size with matching warm capacity available, the app can assign that warm instance instead of provisioning a new reasoner from scratch, so startup can be faster.
Use warm reasoners when all of the following are true:
- the workload is latency-sensitive at startup
- the workload uses logic reasoners
- the problem is startup readiness, not sustained concurrency
- you accept the additional cost of keeping warm capacity active
Warm reasoners are a preview feature. Only logic reasoners are supported today, so prescriptive workloads, predictive workloads, and CDC are out of scope.
Warm reasoners are also different from a non-suspending reasoner:
- A non-suspending reasoner keeps the same named reasoner running.
- A warm reasoner only affects startup. After assignment, the reasoner follows the requested settings, including its normal auto-suspend behavior.
Warm reasoners consume compute while they remain active, even when no request is using them. They improve readiness, but they do not increase the maximum number of same-size reasoners that can run concurrently.
If one warm reasoner is assigned, the app provisions a replacement to keep the configured warm count available. That replacement can still take time to come online, so provisioning can still be slower for later requests in a burst after the existing warm capacity is consumed.
Enable a warm reasoner
Section titled “Enable a warm reasoner”Requires the app_admin application role.
Start with one warm reasoner for the logic size with the worst startup latency. This tells the app to keep matching warm capacity ready for that size:
CALL relationalai.app.enable_warm_reasoner('logic', 'HIGHMEM_X64_S');The procedure result confirms that the app accepted the warm-reasoner configuration change for that type and size.
Treat that result as confirmation of the setting change, not as proof that the warm capacity is already READY.
Set the warm reasoner count
Section titled “Set the warm reasoner count”Requires the app_admin application role.
If one warm reasoner is not enough for a given size, set the exact number of warm reasoners to keep running.
CALL relationalai.app.set_warm_reasoners('logic', 'HIGHMEM_X64_S', 2);Use this to increase or decrease the warm count for a size. Set the count based on the number of concurrent cold starts you want to absorb, not on the total number of running logic reasoners you need during steady-state work.
The procedure result confirms the new target count.
It does not mean that every requested warm reasoner is already READY, because replacement capacity may still be provisioning.
Disable warm reasoners
Section titled “Disable warm reasoners”Requires the app_admin application role.
Disable warm reasoners when you want to remove always-on warm capacity and accept slower cold starts in exchange for lower ongoing compute usage.
CALL relationalai.app.disable_warm_reasoner('logic', 'HIGHMEM_X64_S');You can also set the warm count to 0 with app.set_warm_reasoners(), but disable_warm_reasoner() is the clearest removal workflow.
Once warm reasoners are disabled, the next create or resume for that size may need to wait for normal provisioning again.
Scale reasoner capacity
Section titled “Scale reasoner capacity”Use this page when you need to change the compute pools that host reasoners rather than manage one named reasoner directly. Use it to raise the shared concurrency ceiling for a reasoner size or to reserve always-ready capacity for lower provisioning latency.
Use a Snowflake session with an active warehouse for the SQL examples.
Changing shared capacity requires the eng_admin application role, as noted beside the task.
When to scale reasoner capacity
Section titled “When to scale reasoner capacity”This section is about the app-managed compute pools that host reasoners. It does not resize one named reasoner. Instead, it changes the shared pool limits for a reasoner type and size.
Use compute-pool scaling when you need to change how many same-size reasoners can run at once or how much capacity stays reserved in advance.
| Setting | What it controls | Use it when |
|---|---|---|
MAX_NODES | The maximum number of nodes available for that reasoner type and size. One node corresponds to capacity for one running reasoner. | More reasoners of the same size need to run concurrently. |
MIN_NODES | The minimum number of nodes that stay reserved and always ready. | You want lower provisioning latency for that pool and can accept the extra cost of idle reserved capacity. |
Choose this section when the bottleneck is shared capacity for one type and size. If the problem is startup visibility or queueing and you have not confirmed the cause yet, start with Monitor reasoner usage. If you actually need a different size for one named reasoner, recreate that reasoner through the relevant type-specific management workflow instead.
Increase the maximum number of reasoners
Section titled “Increase the maximum number of reasoners”Requires the eng_admin application role.
Raise MAX_NODES when the pool needs to support more same-size reasoners at the same time.
CALL relationalai.api.alter_reasoner_pool_node_limits('logic', 'HIGHMEM_X64_S', NULL, 12);This example raises the concurrency ceiling for HIGHMEM_X64_S logic reasoners to 12 without changing the current MIN_NODES setting.
If starting another reasoner would exceed the pool’s maximum capacity, the request fails instead of waiting for capacity. Use this change when concurrency is the real bottleneck.
- Raising
MAX_NODESdoes not keep extra capacity warm by itself. - If more reasoners actually run after the change, spend can increase.
Reserve capacity for lower provisioning latency
Section titled “Reserve capacity for lower provisioning latency”Requires the eng_admin application role.
Set MIN_NODES when you want some capacity to stay reserved and always ready for a reasoner type and size.
This improves readiness for that shared pool, but reserved nodes are billed even when idle.
CALL relationalai.api.alter_reasoner_pool_node_limits('logic', 'HIGHMEM_X64_M', 2, 12);This example reserves capacity for at least two HIGHMEM_X64_M logic reasoners and allows up to 12 to run concurrently.
Reserved nodes help when normal provisioning latency is the problem for that pool. They do not fix queueing inside one busy reasoner, and they are broader than warm reasoners because they reserve compute-pool capacity rather than pre-provisioning warm logic instances.