An organization can apportion the cost of using Snowflake to logical units within the organization (for example, to different
departments, environments, or projects). This chargeback or showback model is useful for accounting purposes and pinpoints
areas of the organization that could benefit from controls and optimizations that can reduce costs.
To attribute costs to different groups like departments or projects, use the following recommended approach:
Use object tags to associate resources and users with departments or projects.
Use query tags to associate individual queries with departments or projects when the queries are
made by the same application on behalf of users belonging to multiple departments.
The following cost attribution scenarios are the most commonly encountered. In these scenarios, warehouses are used as an
example of a resource that incurs costs.
Resources used exclusively by a single cost center or department: An example of this is using object tags to associate
warehouses with a department. You can use these object tags to attribute the costs incurred by those warehouses to that
department entirely.
Resources that are shared by users from multiple departments: An example of this is a warehouse shared by users from
different departments. In this case, you use object tags to associate each user with a department. The costs of queries are
attributed to the users. Using the object tags assigned to users, you can break down the costs by department.
Applications or workflows shared by users from different departments: An example of this is an application that issues
queries on behalf of its users. In this case, each query executed by the application is assigned a query tag that identifies
the team or cost center of the user on whose behalf the query is being made.
The next sections explain how to set up object tags in your accounts and provide the details for each of these cost attribution
scenarios.
When you set up tags to represent the groupings that you want to use for cost attribution, you should determine if the
groupings apply to a single account or multiple accounts. This determines how you set up your tags.
For example, suppose that you want to attribute costs based on department.
If the resources used by the department are located in a single account, you create the tags in a database in that account.
If the resources used by the department span multiple accounts, you create the tags
in a key account in your organization (for example, in your organization account),
and you make those tags available in other accounts through replication.
The next sections explain how to create the tags, replicate the tags, and apply the tags to resources.
The examples in these sections use the custom role tag_admin, which is assumed to have been granted the privileges to
create and manage tags. Within your organization, you can use more granular
privileges for object tagging to develop a secure tagging strategy.
As part of designing the strategy, decide on the database and schema where you plan to create the tags.
You can create a dedicated database and schema for the tags.
If you want to tag resources in different accounts across your organization, you can create the tags in a key account in your
organization (for example, in your organization account).
The following example creates a database named cost_management and a schema named tags for the tags that you plan to use:
With cost_management and tags selected as the current database and schema, create a tag named cost_center and set
the values allowed for the tag to the names of cost centers:
For example, to replicate the tags to the accounts named my_org.my_account and my_org.my_account_2, execute this
statement in your organization account:
Then, in each account in which you want to make the tags available, create a secondary replication group, and refresh this
group from the primary group:
After creating and replicating the tags, you can use these tags to identify the warehouses and users belonging to each
department. For example, because the sales department uses both warehouse1 and warehouse2, you can set the
cost_center tag to 'SALES' for both warehouses.
Tip
Ideally, you should have workflows that automate the process of applying these tags when you create resources and users.
If you want to automate the process of tagging users for cost attribution, you can do so by provisioning
Snowflake users through a SCIM identity provider such as Microsoft Entra ID or
Okta. With SCIM, you can automatically apply cost attribution tags to users when
they’re created or updated, eliminating the need to run ALTERUSER<user_name>SETTAG manually for each new
user and keeping your cost attribution tags consistent as users join or move between departments.
When using SCIM, the snowflakeTags custom attribute accepts a comma-separated list of fully qualified tag
references. For example, to assign a user to the finance cost center at provisioning time, include the
following value in the SCIM user payload:
Tags set through SCIM appear in the same TAG_REFERENCES views
and work with Snowsight tag filters (see Viewing cost by tag in Snowsight), so your existing
cost attribution queries and dashboards work without changes.
To get started with this approach, you need to:
Create the tags in Snowflake, as described in Creating the tags above.
Grant the SCIM provisioner role USAGE on the tag schema and APPLY on each tag.
For the complete setup steps, prerequisite grants, and API examples, see the “Populating Snowflake tags with SCIM
integrations” section in:
Attributing costs across accounts in an organization
Within an organization, you can also attribute costs for resources that are used exclusively by a single department by
querying views in the ORGANIZATION_USAGE schema from the
organization account.
Note
In the ORGANIZATION_USAGE schema, the TAG_REFERENCES view is only available in the organization account.
The QUERY_ATTRIBUTION_HISTORY view is only available in the ACCOUNT_USAGE schema for an account. There is no
organization-wide equivalent of the view.
Suppose that you want to attribute costs by department and that each department uses a set of dedicated warehouses.
If you tag warehouses with a cost_center tag to identify the department that owns the warehouse, you can join the
ACCOUNT_USAGE TAG_REFERENCES view with the
WAREHOUSE_METERING_HISTORY view on the object_id and warehouse_id columns to get usage
information by warehouse, and you can use the tag_value column to identify the departments that own those warehouses.
You can run a similar query to perform the same attribution for all the accounts in your organization using views in the
ORGANIZATION_USAGE schema from the organization account. The rest of the query
does not change.
Resources shared by users from different departments¶
Suppose that users in different departments share the same warehouses and you want to break down the credits used by each
department. You can tag the users with a cost_center tag to identify the department that they belong to, and you can join
the TAG_REFERENCES view with the QUERY_ATTRIBUTION_HISTORY view.
Note
You can only get this data for a single account at a time. You cannot execute a query that retrieves this data across
accounts in an organization.
The next sections provide examples of SQL statements for attributing costs for shared resources.
Calculating the cost of user queries by department without idle time¶
The following example attributes the compute cost to each department through the queries executed by users in that department.
This query depends on the user objects having a tag that identifies their department.
Calculating the cost of queries by users without tags¶
The following example calculates the cost of queries by users who are not tagged. You can use this to verify that tags are
being applied consistently to users.
Resources used by applications that need to attribute costs to different departments¶
The examples in this section calculate the costs for one or more applications that are powered by Snowflake.
The examples assume that these applications set query tags that identify the application for all queries executed. To set the
query tag for queries in a session, execute the ALTER SESSION command. For example:
ALTERSESSIONSETQUERY_TAG='COST_CENTER=finance';
This associates the COST_CENTER=finance tag with all subsequent queries executed during the session.
You can then use the query tag to trace back the cost incurred by these queries to the appropriate departments.
The next sections provide examples of using this approach.
The following example calculates the compute credits and the credits used for the
query acceleration service for the finance department. This depends on the
COST_CENTER=finance query tag being applied to the original queries that were executed.
Calculating the cost of queries (including idle time) by query tag¶
The following example distributes the idle time that is not captured in the per-query cost across departments in proportion
to their usage of the warehouse.
You can use the QUERY_ATTRIBUTION_HISTORY view to attribute cost based on queries. The cost per
query is the warehouse credit usage for executing the query. This cost does not include any other credit usage that is incurred
as a result of query execution. For example, the following are not included in the query cost:
Data transfer costs
Storage costs
Cloud services costs
Costs for serverless features
Costs for tokens processed by AI services
For queries that are executed concurrently, the cost of the warehouse is attributed to individual queries based on the weighted
average of their resource consumption during a given time interval.
The cost per query does not include warehouse idle time. Idle time is a period of time in which no queries are running in the
warehouse and can be measured at the warehouse level.
For stored procedures that issue multiple hierarchical queries, you can compute the attributed query costs for the
procedure by using the root query ID for the procedure.
To find the root query ID for a stored procedure, use the ACCESS_HISTORY view. For example,
to find the root query ID for a stored procedure, set the query_id and execute the following statements: