by datastudy.nl

Field notes for enterprise data engineers and scientists

Engineering

Snowflake per-user quotas GA: the AI credit kill switch

Snowflake per-user quotas are now GA. Admins set daily and monthly AI credit limits per person, with automatic block enforcement within minutes of overspend.

Abstract data visualization of Snowflake per-user quotas circuit breaker for AI spend, with enforcement propagation improving from 15 minutes in preview to 5 to 10 minutes at GA.
Enforcement propagation time for Snowflake per-user quotas: 15 minutes in preview, 5 to 10 minutes at GA. Source: Snowflake release notes October 2026.

A single analyst firing an unoptimized AI_COMPLETE call across a million-row table can drain a department's monthly AI budget before lunch. Per-user quotas, now generally available in Snowflake, give you a per-person credit circuit breaker that blocks AI requests within minutes of a spend event. The feature covers Cortex AI Functions, Cortex Agents, Snowflake CoWork, and Snowflake CoCo, with separate tracking available for warehouse compute.

The enforcement pipeline runs in Snowflake-managed infrastructure, so it does not consume credits in your account. That is the detail that matters: you are not paying to be protected from overspend.

If you have been relying on aggregate budgets to catch runaway AI spend, you already know the gap. A team budget tells you the department went over. It does not tell you who did it, or stop them before the damage is done. Per-user quotas close that gap with individual credit limits and automatic blocking, no stored procedures required.

What exactly can you govern, and what stays outside the fence?

Per-user quotas track spend across five domains, but enforcement splits cleanly between AI and compute. Here is the breakdown:

Domain Spend Tracking Block Enforcement Example
Cortex AI Functions Yes Yes AI_COMPLETE, AI_SUMMARIZE, AI_TRANSLATE
Cortex Agents Yes Yes Agent workflows
Snowflake CoWork Yes Yes Collaborative business tools
Snowflake CoCo Yes Yes Snowsight, CLI, Desktop assistant
Warehouse compute Yes No Query execution credits

That last row is the one to pay attention to. You can track warehouse credits per user for attribution, but you cannot hard-block someone from running queries when they hit a limit. Snowflake's per-user quotas documentation states this plainly: block enforcement does not apply to warehouses.

The design is deliberate. Blocking warehouse access mid-pipeline could corrupt a transaction or leave a stream in a broken state. AI requests are stateless from the user's perspective, so pausing them is safe. If you need to govern warehouse spend, you still depend on warehouse sizing controls and resource monitors, not per-user quotas.

Because AI and compute use different credit structures, limits are set independently. A common pattern: tight daily caps on AI functions where a single bad prompt can burn hundreds of credits, and generous monthly ceilings on warehouse compute for routine query work.

How do you configure a quota with block enforcement?

Quotas are managed through SQL, the Snowsight UI, or Snowflake CoCo. The SQL path gives you the most control and the easiest audit trail. The core flow is three steps: set the per-user limit, enable block enforcement, and add notification thresholds.

First, set the monthly and optional daily credit limits. The monthly cycle is fixed to the UTC calendar month and resets automatically. Custom cycles like weekly are not supported.

-- Monthly limit: 500 credits per user (default cycle)
CALL SET_PER_USER_LIMIT(500);

-- Optional daily limit: 50 credits per user.
-- Pass the cycle argument to switch from monthly to daily.
CALL SET_PER_USER_LIMIT(50, 'DAILY');

Daily and monthly limits are evaluated independently. A user can be blocked for hitting a daily cap while still being well under their monthly ceiling, and the reverse is also true.

Next, enable block enforcement. The GA release added a second boolean argument to control whether blocked users get an email notification. Going forward, end-user notifications are disabled by default, so you must explicitly opt in.

-- Enable block enforcement and send email to blocked users.
-- The first TRUE enables enforcement; the second enables notifications.
CALL SET_BLOCK_ENFORCEMENT_ENABLED(TRUE, TRUE);

Then add notification thresholds so users get warnings before they hit the wall. The GA release added the ability to target thresholds at the monthly or daily limit by passing a fourth argument to ADD_NOTIFICATION_THRESHOLD.

-- Notify at 80 percent of the monthly limit.
-- Fourth argument scopes the threshold to MONTHLY or DAILY.
CALL ADD_NOTIFICATION_THRESHOLD(80, 'EMAIL', 'MONTHLY');

The enforcement pipeline that handles blocking is separate from the measurement task that handles notifications. Block enforcement runs in Snowflake's infrastructure and evaluates breaches within minutes of a spend event. The notification and custom-action measurement task is slower, so do not rely on notifications alone to prevent overspend.

How do you scope quotas to teams without maintaining user lists?

By default, a new quota covers all users in the account, including anyone added later. That is the zero-config path: one quota, one limit, everyone governed. For most teams starting out, that is the right first step.

When you need different limits for different groups, you scope by tag. Tags map your existing organizational structure, cost centers, departments, or teams onto quota scope. If you use SCIM integration with an identity provider like Microsoft Entra ID or Okta, tags can be applied automatically as users are onboarded, so quota scope tracks your org chart without manual maintenance.

When multiple tag keys are used for scoping, an operator defines the matching logic. UNION is the default: a user needs to match at least one tag to be governed. INTERSECTION requires a user to match every specified tag.

You can also keep all users in scope while excluding a subset. The EXCLUDE_USERS option lets you carve out power users or service accounts that should not be subject to the same caps.

Scoping Mode Behavior Use Case
All users (default) Covers everyone, auto-includes new users Simple org-wide cap
Tag-based UNION Includes users matching any tag Broad team coverage
Tag-based INTERSECTION Includes users matching every tag Narrow role-based limits
EXCLUDE_USERS All users except a tagged subset Carve out service accounts

What changed between preview and GA?

The GA release shipped in the October 2026 release notes brought several concrete improvements over the public preview. If you tested quotas during preview, these are the deltas that matter:

Capability Preview GA
Enforcement propagation Up to 15 minutes 5 to 10 minutes
Block email notifications Not configurable Admin-controlled via second boolean argument
Notification targeting Monthly only Monthly or daily via fourth argument
Block history view Not available ACCOUNT_USAGE.QUOTA_ACCESS_BLOCK_HISTORY
Active blocks function GET_ACTIVE_BLOCKS() GET_ACTIVE_BLOCKS_V2()
Refresh tier setting SET_REFRESH_TIER() required Built in, no configuration
Bar chart comparing per-user quota enforcement propagation time: 15 minutes in preview versus 10 minutes at GA, showing the improvement at general availability.
Enforcement propagation time for per-user quotas: up to 15 minutes in preview, down to 5 to 10 minutes at GA. Source: Snowflake release notes October 2026.

The faster propagation is the headline change. In preview, configuration changes could take up to 15 minutes to take effect. GA cuts that to 5 to 10 minutes. That is still not real-time, so if you raise a user's limit in an emergency, expect a short delay before the new limit is live.

The new ACCOUNT_USAGE view gives you account-wide visibility into every block event across all quotas. Query it to audit who was blocked, when, and why:

SELECT
    user_name,
    quota_name,
    block_reason,
    blocked_at,
    released_at
FROM SNOWFLAKE.ACCOUNT_USAGE.QUOTA_ACCESS_BLOCK_HISTORY
WHERE block_date >= DATEADD('day', -7, CURRENT_DATE())
ORDER BY blocked_at DESC;

For a real-time check on currently blocked users, use the replacement function:

SELECT * FROM TABLE(GET_ACTIVE_BLOCKS_V2());

The old GET_ACTIVE_BLOCKS() function is deprecated. GET_PER_USER_USAGE_PREVIEW() and SET_REFRESH_TIER() are gone entirely, since fast evaluation is now built in for all accounts.

When is a per-user quota the wrong tool?

Per-user quotas are a targeted guardrail for AI spend, not a universal cost solution. Here is where they fall short.

Warehouse cost control. You can track warehouse credits per user, but without block enforcement, a quota only gives you attribution data after the fact. If your primary problem is warehouse overspend, adaptive compute and resource monitors are still your tools.

Custom billing cycles. Quotas reset on the UTC calendar month. If your fiscal month starts on the 15th, or you need weekly resets, you are out of luck. The docs are explicit: custom quota cycles such as weekly or custom start dates are not supported. You can work around this with daily limits, but you cannot align the monthly cycle to your fiscal calendar.

Aggregate team budgets. Per-user quotas cap individuals. They do not enforce a team-level ceiling. Ten users with a 500-credit monthly limit can collectively spend 5,000 credits. If you need a department-wide cap, pair per-user quotas with Snowflake Budgets for aggregate tracking. For a deeper look at that layered approach, see our earlier guide to per-user quotas and cost governance.

Real-time prevention. Enforcement happens within minutes, not seconds. A fast-running batch of AI_COMPLETE calls can still accumulate charges before the block takes effect. The system catches overspend quickly, but it is not a hard wall at the credit boundary.

What should you do in the first week after GA?

Start with the AI domains, not warehouse compute. AI functions are where a single user can burn the most credits fastest, and they are where block enforcement actually works.

Set a generous daily limit first. Look at your current AI spend in Snowsight's per-user utilization view, find the 95th percentile of daily per-user consumption, and set the daily cap at roughly 2x that number. This catches true outliers without blocking legitimate work.

Enable block enforcement with email notifications turned on. Users should know when they are blocked and why, so they can self-correct or request a limit increase. The second argument to SET_BLOCK_ENFORCEMENT_ENABLED controls this, and it defaults to off in GA.

If you are running Cortex Agents in production, pair per-user quotas with the Cortex AI Gateway for a layered governance model. The gateway controls which external tools agents can access; the quota controls how much each user can spend. Together they answer the two questions a security reviewer will ask: who can call what, and how much can it cost.

Use custom actions sparingly. The block enforcement is built in and requires no stored procedures. Custom actions via stored procedures are available for advanced scenarios like suspending a warehouse or revoking a role, but the built-in block handles the common case. Start simple.

The shape of individual AI spend control

The block is what makes per-user quotas worth turning on. A quota without enforcement is a reporting view. A quota with automatic, per-user, per-domain blocking that lifts itself at the next cycle boundary is a policy you can actually run. Snowflake built the enforcement pipeline on their own infrastructure, made it free to operate, and made it work within minutes. The gap that remains, the absence of warehouse block enforcement, is a design constraint worth respecting.

Sources