Share

From QueryBand to Query Tag

From QueryBand to Query Tag
admin1

How to Track Query and User Activity After Migrating from Teradata to Snowflake

By Roland Wenzlofsky · DWHPro

🎯 Why This Matters

In Teradata, QUERY_BAND has long been a hidden gem — the ability to tag every query or session with metadata like App, Job, or UserGroup.

That little string became the key to workload analytics, usage attribution, and auditing.


Want more practical data engineering analysis like this?

Join DWHPro Letters and get field-tested notes on Teradata, Snowflake, AI, migrations, performance, and enterprise data work. DWHPro Letters is free. Subscribe to get new issues by email.

Get the next issue


When moving to Snowflake, you’ll naturally ask:

“Where is my QueryBand?”

Snowflake’s answer is QUERY_TAG, a cleaner, modern mechanism that integrates directly into its metadata views (ACCOUNT_USAGE.QUERY_HISTORY).

This article explains exactly how to reproduce your Teradata tracking patterns — same logic, new syntax.

🧩 Teradata Recap: QUERY_BAND

Example

SET QUERY_BAND='App=Finance;Job=ReportX;UserGroup=Analytics' FOR SESSION;

Every query inherits those key/value pairs.

They appear in the DBQL logs and can be joined with resource metrics (CPU, I/O, Spool).

Typical use-cases

  • Tag jobs to track their workload footprint
  • Separate usage between teams or environments

Limitations

  • Requires manual parsing from DBQL tables
  • No native cost integration — you must compute it yourself
  • Relies on discipline (developers need to set it consistently)

❄️ Snowflake Equivalent: QUERY_TAG

In Snowflake, tagging happens through the QUERY_TAG session parameter.

Every query you run afterward carries that tag into ACCOUNT_USAGE.QUERY_HISTORY.

🧠 Set a tag for your session

<p< p>

ALTER SESSION SET QUERY_TAG = '{"App":"FinanceDashboard",
                                "Job":"MonthlySummary",
                                "UserGroup":"Reports"}'

All subsequent queries inherit this tag until you clear it:Copy

ALTER SESSION UNSET QUERY_TAG;

It’s exactly the same idea as Teradata’s SET QUERY_BAND = NULL FOR SESSION.

Get the next issue by email.

⚙️ Default tags per user or account

You can define permanent defaults (similar to user profile QueryBands):Copy

-- Account-wide default (requires ACCOUNTADMIN)
ALTER ACCOUNT SET QUERY_TAG = 'DefaultTagForThisAccount';

-- Per-user default
ALTER USER DWHPRO SET QUERY_TAG = '{"App":"ETL","UserGroup":"Ops"}';

Lower-level settings (session or user) override higher-level ones.

💻 Set it from your scripts

Wherever your ETL or application code connects to Snowflake, run this at session start:Copy

ALTER SESSION SET QUERY_TAG = '{"App":"ETL","Job":"Load1","Step":"1"}';

📊 Analyzing Queries by Tag

Once tags are being set, you can use Snowflake’s metadata views to measure workload volume, duration, and user behavior.

✅ Works in every account

<p< p>

SELECT
  COALESCE(query_tag, '<<NO TAG>>') AS query_tag,
  COUNT(*)                           AS num_queries
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY
GROUP BY 1
ORDER BY num_queries DESC;

This shows how often each tag was used — similar to counting Teradata QueryBands in DBQL.

⏱️ Top tags by total runtime

<p< p>

SELECT
  query_tag,
  COUNT(*)                AS num_queries,
  SUM(total_elapsed_time) AS total_time_ms,
  AVG(total_elapsed_time) AS avg_time_ms
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY
WHERE query_tag IS NOT NULL
GROUP BY query_tag
ORDER BY total_time_ms DESC;



🚨 Detect untagged queries

<p< p>

SELECT
  user_name,
  warehouse_name,
  COUNT(*) AS num_untagged,
  MAX(start_time) AS last_seen
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY
WHERE query_tag IS NULL
GROUP BY user_name, warehouse_name
ORDER BY num_untagged DESC;

A simple hygiene check — who’s forgetting to tag?

🕓 Activity in the last 24 hours

<p< p>

SELECT
  query_tag,
  COUNT(*) AS num_queries,
  SUM(total_elapsed_time) AS total_time_ms
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY
WHERE start_time >= DATEADD(hour, -24, CURRENT_TIMESTAMP())
  AND query_tag IS NOT NULL
GROUP BY query_tag
ORDER BY num_queries DESC;

👥 Top users within a tag

<p< p>

SELECT
  query_tag,
  user_name,
  COUNT(*) AS num_queries,
  SUM(total_elapsed_time) AS total_time_ms
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY
WHERE query_tag ILIKE '%"Job":"Load1"%'
GROUP BY query_tag, user_name
ORDER BY num_queries DESC;

Perfect for seeing which users contribute most to a specific workload tag.

💰 Optional: Warehouse-level cost context

Even if per-query credit attribution isn’t available in your region yet, you can still monitor overall warehouse usage:Copy

SELECT
  warehouse_name,
  start_time::date AS day,
  SUM(credits_used) AS credits
FROM SNOWFLAKE.ACCOUNT_USAGE.WAREHOUSE_METERING_HISTORY
GROUP BY warehouse_name, day
ORDER BY day DESC, credits DESC;

Then correlate that with your tagged activity windows.

🔍 Teradata vs Snowflake Quick Comparison

CapabilityTeradata (QUERY_BAND)Snowflake (QUERY_TAG)
Tag typeArbitrary name/value stringFree-form text or JSON
ScopeSession / TransactionAccount / User / Session
Where storedDBQL log tablesACCOUNT_USAGE.QUERY_HISTORY
Cost metricsManual from logsIntegrated via usage views
Discipline neededHighStill high — same principle

🚀 Migration Guidelines

  1. Map existing keys
  2. Set the tag early
  3. Audit tagging coverage
  4. Rebuild your dashboards

✅ Takeaway

If you’ve relied on QUERY_BAND for years, you don’t lose that capability when you migrate to Snowflake — you actually simplify it.

ALTER SESSION SET QUERY_TAG='…'

is your new SET QUERY_BAND.

Everything else — analysis, governance — builds naturally on top of ACCOUNT_USAGE.QUERY_HISTORY.

It’s familiar, lightweight, and cloud-native.

🔄 Migration Cheat Sheet

TeradataSnowflake
SET QUERY_BAND='App=…;Job=…' FOR SESSION;ALTER SESSION SET QUERY_TAG='{"App":"…","Job":"…"}';
Stored in DBQLStored in ACCOUNT_USAGE.QUERY_HISTORY
Analyze CPU/I/O by bandAnalyze elapsed time or credits by tag
Manual cost mappingNative warehouse usage views

✳️ Summary

You can carry your entire QueryBand methodology into Snowflake with almost no conceptual change — just a new command and a richer set of metadata views.

It’s the cleanest one-to-one migration feature you’ll encounter.


Planning or surviving an enterprise data platform migration?

I write regularly about the performance, cost, architecture, and project mistakes that show up in real Teradata, Snowflake, Databricks, and enterprise data work.

Subscribe for free and keep launch access.

Written by Roland Wenzlofsky, founder of DWHPro and author of Teradata Query Performance Tuning. DWHPro has helped data warehouse practitioners for 15+ years.

Subscribe to DWHPro Letters

Practical field notes on enterprise data engineering, production AI systems, platform migration, and the senior engineering market.
Written by Roland Wenzlofsky Founder of DWHPro Author of Teradata Query Performance Tuning
Get the next issue
Subscribe