Attributing cost¶
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.
Types of cost attribution scenarios¶
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.
Viewing cost by tag in SQL¶
You can attribute costs within an account or across accounts in an organization:
Attributing costs within an account
You can attribute costs within an account by querying the following views in the ACCOUNT_USAGE schema:
TAG_REFERENCES view: Identifies objects (for example, warehouses and users) that have tags.
WAREHOUSE_METERING_HISTORY view: Provides credit usage for warehouses.
QUERY_ATTRIBUTION_HISTORY view: Provides the compute costs for queries. The cost per query is the warehouse credit usage for executing the query.
For more information on using this view, see About the QUERY_ATTRIBUTION_HISTORY view.
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.
The next sections explain how to attribute costs for some of the common cost-attribution scenarios:
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:
ALTER SESSION SET QUERY_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.
Calculating the cost of queries (excluding idle time) by query tag
Calculating the cost of queries (including idle time) by query tag
Calculating the cost of queries by department¶
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.
Note that the costs exclude idle time.
SELECT
query_tag,
SUM(credits_attributed_compute) AS compute_credits,
SUM(credits_used_query_acceleration) AS qas
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_ATTRIBUTION_HISTORY
WHERE query_tag = 'COST_CENTER=finance'
GROUP BY query_tag;
+---------------------+-----------------+------+
| QUERY_TAG | COMPUTE_CREDITS | QAS |
|---------------------+-----------------|------|
| COST_CENTER=finance | 0.00576115 | null |
+---------------------+-----------------+------+
Calculating the cost of queries (excluding idle time) by query tag¶
The following example calculates the cost of queries by query tag and includes queries without tags (identified as “untagged”).
SELECT
COALESCE(NULLIF(query_tag, ''), 'untagged') AS tag,
SUM(credits_attributed_compute) AS compute_credits,
SUM(credits_used_query_acceleration) AS qas
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_ATTRIBUTION_HISTORY
WHERE start_time >= DATEADD(MONTH, -1, CURRENT_DATE)
GROUP BY tag
ORDER BY compute_credits DESC;
+-------------------------+-----------------+------+
| TAG | COMPUTE_CREDITS | QAS |
|-------------------------+-----------------+------+
| untagged | 3.623173449 | null |
| COST_CENTER=engineering | 0.531431948 | null |
|-------------------------+-----------------+------+
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.
WITH
wh_bill AS (
SELECT SUM(credits_used_compute) AS compute_credits
FROM SNOWFLAKE.ACCOUNT_USAGE.WAREHOUSE_METERING_HISTORY
WHERE start_time >= DATE_TRUNC('MONTH', CURRENT_DATE)
AND start_time < CURRENT_DATE
),
tag_credits AS (
SELECT
COALESCE(NULLIF(query_tag, ''), 'untagged') AS tag,
SUM(credits_attributed_compute) AS credits
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_ATTRIBUTION_HISTORY
WHERE start_time >= DATEADD(MONTH, -1, CURRENT_DATE)
GROUP BY tag
),
total_credit AS (
SELECT SUM(credits) AS sum_all_credits
FROM tag_credits
)
SELECT
tc.tag,
tc.credits / t.sum_all_credits * w.compute_credits AS attributed_credits
FROM tag_credits tc, total_credit t, wh_bill w
ORDER BY attributed_credits DESC;
+-------------------------+--------------------+
| TAG | ATTRIBUTED_CREDITS |
+-------------------------+--------------------|
| untagged | 9.020031304 |
| COST_CENTER=finance | 1.027742521 |
| COST_CENTER=engineering | 1.018755812 |
| COST_CENTER=marketing | 0.4801370376 |
+-------------------------+--------------------+
Viewing cost by tag in Snowsight¶
You can attribute costs by reporting on the use of resources that have the cost_center
tag. You can access this data in
Snowsight.
Switch to a role that has access to the ACCOUNT_USAGE schema.
Navigate to Admin » Cost Management.
Select Consumption.
From the Tags drop-down, select the
cost_center
tag.To focus on a specific cost center, select a value from the list of the tag’s values.
Select Apply.
For more details about filtering in Snowsight, see Filter by tag.
About the QUERY_ATTRIBUTION_HISTORY view¶
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.
Additional examples of queries¶
The next sections provide additional queries that you can use for cost attribution:
Grouping similar queries¶
For recurrent or similar queries, use the query_hash
or query_parameterized_hash
to group costs
by query.
To find the most expensive recurrent queries for the current month, execute the following statement:
SELECT query_parameterized_hash,
COUNT(*) AS query_count,
SUM(credits_attributed_compute) AS total_credits
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_ATTRIBUTION_HISTORY
WHERE start_time >= DATE_TRUNC('MONTH', CURRENT_DATE)
AND start_time < CURRENT_DATE
GROUP BY query_parameterized_hash
ORDER BY total_credits DESC
LIMIT 20;
For an additional query based on query ID, see Examples.
Attributing costs of hierarchical queries¶
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:SET query_id = '<query_id>'; SELECT query_id, parent_query_id, root_query_id, direct_objects_accessed FROM SNOWFLAKE.ACCOUNT_USAGE.ACCESS_HISTORY WHERE query_id = $query_id;
For more information, see Example: Ancestor queries with stored procedures.
To sum the query cost for the entire procedure, replace
<root_query_id>
and execute the following statements:SET query_id = '<root_query_id>'; SELECT SUM(credits_attributed_compute) AS total_attributed_credits FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_ATTRIBUTION_HISTORY WHERE (root_query_id = $query_id OR query_id = $query_id);