Snowflake FinOps for telecom is the discipline of pricing every unit of data freshness a network operator buys, then attributing, guarding and reviewing that spend with the same rigour applied to spectrum or backhaul. Our finding across telecom data platforms is consistent: the largest avoidable Snowflake cost is rarely a slow query. It is freshness bought at a latency no consumer uses, served by compute shapes that were never matched to the workload.
This paper sets out seven Snowflake FinOps for telecom controls, a reference architecture, runnable SQL and Python, and a 90-day operating plan. It is written for the CTO, CDO and CFO who jointly own a real-time analytics platform on Snowflake, and for the engineering leads who have to make the numbers move. Product behaviour cited here was verified against Snowflake documentation on 4 November 2026; Snowflake ships changes frequently, so confirm the current behaviour for your edition and region before acting.
Executive summary: what leaders should take away
- In Snowflake FinOps for telecom, real-time is a portfolio, not a setting. Classify every telecom workload into a freshness tier and refuse to pay for latency below the tier.
- Ingest is now a volume meter. Snowpipe Streaming with the high-performance architecture bills on uncompressed bytes ingested, so payload design upstream is a cost decision.
- Interactive warehouses carry a one-hour minimum and a 24-hour auto-suspend floor. They are excellent for a 24x7 network operations centre and expensive for anything intermittent.
- Gen2 is the default for new standard warehouses, with Query Acceleration enabled at a maximum scale factor of 8. Cap it deliberately.
- Run the platform on one unit metric, credits per million network events, attributed by domain through tags and query attribution.
Why telecom real-time analytics breaks Snowflake budgets
Telecom data has a shape that most cost models underestimate. Event volumes are continuous rather than diurnal, because the network never sleeps. The sources are heterogeneous: xDRs and signalling events from the 5G core and probes, CDRs and IPDRs from mediation, RAN performance counters from OSS, and fraud signals such as SIM box, IRSF and Wangiri patterns. Each source arrives at a different natural cadence, yet platforms are frequently configured with a single, aggressive freshness target for all of them.
The economic consequence is structural. A uniform one-minute target applied to a 15-minute counter feed buys fourteen refresh cycles that find nothing new. A dashboard served by a warehouse that resumes and suspends all day pays repeated minimum billing periods and loses its cache each time. None of this shows up as a slow query, which is why Snowflake cost optimization through performance tuning alone does not fix a telecom Snowflake bill. Snowflake FinOps for telecom starts from the cost shape, not the query.
We see three recurring patterns in operator environments. First, freshness is negotiated once, at platform launch, and never re-priced. Second, the cost of streaming ingest is treated as fixed, when it moves directly with payload width. Third, nobody can answer the CFO's simplest question: what does it cost to analyse one million network events, and is that number falling?
Reference architecture: Snowflake FinOps for telecom real-time analytics
The architecture below places a billing meter on every hop. The point of drawing it this way is that each design decision maps to exactly one meter, and each meter maps to exactly one telemetry view. If a hop cannot be measured, it cannot be governed, and Snowflake FinOps for telecom depends on governing every hop.
Figure 1. Snowflake FinOps for telecom: each layer carries its own billing meter, and the control plane spans all of them.
Network domains publish to Apache Kafka, one topic per domain, with payloads trimmed at source. Snowpipe Streaming lands events in append-only raw tables. Dynamic tables carry the transformation graph with tiered target lag. Serving splits by access pattern: interactive tables on an interactive warehouse for the always-on operations centre and low-latency fraud APIs, and a Gen2 standard warehouse for ad hoc analysis and model features.
Snowflake FinOps for telecom cost anatomy: meter, telemetry and lever
| Layer | Billing meter | Telemetry source | Primary lever |
|---|---|---|---|
| Streaming ingest | Uncompressed GB ingested | METERING_HISTORY, SERVICE_TYPE = 'SNOWPIPE_STREAMING' | Payload width at source |
| Transformation | Refresh warehouse credits plus cloud services | DYNAMIC_TABLE_REFRESH_HISTORY | Target lag per tier |
| Low-latency serving | Interactive warehouse, one-hour minimum | WAREHOUSE_METERING_HISTORY | Always-on only where demand is 24x7 |
| Ad hoc and features | Gen2 per-second credits, Query Acceleration | QUERY_ATTRIBUTION_HISTORY | Size, auto-suspend, QAS cap |
| Storage | Active, Time Travel, Fail-safe bytes | TABLE_STORAGE_METRICS | Table type and retention days |
Start every engagement with a 30-day baseline by service type. The query below is read-only and safe to run on production; ACCOUNT_USAGE views carry latency of up to a few hours, so treat the last day as provisional.
-- Snowflake FinOps for telecom: 30-day credit baseline by service type
-- Read-only. Requires access to the SNOWFLAKE database (e.g. a role granted
-- SNOWFLAKE.USAGE_VIEWER). ACCOUNT_USAGE latency applies to the latest rows.
SELECT
service_type,
DATE_TRUNC('day', start_time) AS usage_day,
SUM(credits_used_compute) AS compute_credits,
SUM(credits_used_cloud_services) AS cloud_services_credits,
SUM(credits_used) AS total_credits
FROM snowflake.account_usage.metering_history
WHERE start_time >= DATEADD('day', -30, CURRENT_TIMESTAMP())
GROUP BY service_type, usage_day
ORDER BY usage_day, total_credits DESC;
Control 1: price freshness with tiered target lag
The most valuable conversation in Snowflake FinOps for telecom is the one about latency. We classify telecom workloads into four Snowflake FinOps for telecom freshness tiers and require each consuming team to sign up to a tier. The tier then dictates the Snowflake pattern and therefore the meter.
Figure 2. Freshness tiers in Snowflake FinOps for telecom: latency is purchased per workload, never platform-wide.
The T2 tier deserves particular attention. RAN performance counters are collected per result output period (ROP), commonly 15 minutes. A dynamic table over that feed with a one-minute lag runs change detection every minute and finds new data roughly once per period. Snowflake documents that cycles with no upstream change keep the warehouse suspended but still consume cloud services for change detection, and that intermediate tables can inherit their schedule with TARGET_LAG = DOWNSTREAM.
-- Snowflake FinOps for telecom: freshness tiers expressed as target lag.
-- Test in a non-production account first; CREATE OR REPLACE rebuilds the table.
-- T2: RAN PM counters, aligned to the 15-minute ROP
CREATE OR REPLACE DYNAMIC TABLE ran_kpi.cell_kpi_15m
TARGET_LAG = '15 minutes'
WAREHOUSE = wh_transform_t2
REFRESH_MODE = INCREMENTAL
AS
SELECT
cell_id,
TIME_SLICE(rop_end_ts, 15, 'MINUTE') AS rop_slot,
SUM(rrc_conn_attempts) AS rrc_attempts,
SUM(rrc_conn_success) AS rrc_success,
SUM(dl_prb_used) / NULLIF(SUM(dl_prb_avail), 0) AS dl_prb_utilisation
FROM raw.ran_pm_counters
GROUP BY cell_id, rop_slot;
-- Intermediate step in the T1 NOC chain: refresh only when a consumer needs it
CREATE OR REPLACE DYNAMIC TABLE noc.session_events_enriched
TARGET_LAG = DOWNSTREAM
WAREHOUSE = wh_transform_t1
REFRESH_MODE = INCREMENTAL
AS
SELECT
e.event_ts,
e.imsi_hash,
e.cell_id,
e.event_type,
c.region_code,
c.slice_id
FROM raw.core_session_events AS e
JOIN ref.cell_topology AS c
ON c.cell_id = e.cell_id;
-- T1 consumer: the only table in the chain carrying a short lag
CREATE OR REPLACE DYNAMIC TABLE noc.slice_health_1m
TARGET_LAG = '1 minute'
WAREHOUSE = wh_transform_t1
REFRESH_MODE = INCREMENTAL
AS
SELECT
slice_id,
region_code,
TIME_SLICE(event_ts, 1, 'MINUTE') AS minute_slot,
COUNT_IF(event_type = 'SESSION_SETUP_FAIL') AS setup_failures,
COUNT_IF(event_type = 'SESSION_SETUP_OK') AS setup_success
FROM noc.session_events_enriched
GROUP BY slice_id, region_code, minute_slot;
Then measure whether the tiers are honest. A high share of NO_DATA refreshes signals lag set tighter than the data arrives; frequent REINITIALIZE actions signal upstream DDL or policy churn that is forcing full reprocessing.
-- Snowflake FinOps for telecom: dynamic table refresh efficiency, last 7 days (read-only)
SELECT
qualified_name,
MAX(target_lag_sec) AS target_lag_sec,
COUNT(*) AS refreshes,
ROUND(100 * COUNT_IF(refresh_action = 'NO_DATA') / COUNT(*), 1) AS pct_no_data,
COUNT_IF(refresh_action = 'FULL') AS full_refreshes,
COUNT_IF(refresh_action = 'REINITIALIZE') AS reinitialisations,
COUNT_IF(state IN ('FAILED', 'UPSTREAM_FAILED')) AS failures
FROM snowflake.account_usage.dynamic_table_refresh_history
WHERE refresh_start_time >= DATEADD('day', -7, CURRENT_TIMESTAMP())
GROUP BY qualified_name
ORDER BY pct_no_data DESC;
For telecom real-time analytics, remember the cloud services rule when reading the result. Cloud services credits are billed only where the account's daily cloud services consumption exceeds 10 percent of that day's warehouse compute. This is where Snowflake dynamic tables cost is most often misread: hundreds of short-lag dynamic tables can push an otherwise lean account over that threshold.
Control 2: meter Snowpipe Streaming cost at the payload
With the high-performance architecture, generally available since September 2025 and since extended across clouds, Snowpipe Streaming moved to a flat rate per uncompressed gigabyte ingested. Snowflake's cost documentation notes that billing is based on input bytes received, and that for JSON only value bytes are counted, not keys. The rate itself is published in the Snowflake Service Consumption Table, and it is the anchor price for any Snowflake FinOps for telecom ingest forecast.
The implication for Snowflake FinOps for telecom is direct: payload width is the lever. Probe records often carry redundant enrichment, verbose enumerations and fields no downstream model reads. Trimming at the Kafka producer or in a stream processor reduces the billed volume one for one, before any warehouse is involved. Agree a data contract per domain that lists the fields that are allowed to cross the boundary.
-- Snowflake FinOps for telecom: Snowpipe Streaming cost by pipe and day (read-only).
-- Join pattern follows Snowflake's cost documentation for the
-- high-performance architecture.
SELECT
p.pipe_catalog || '.' || p.pipe_schema || '.' || p.pipe_name AS pipe_fqn,
DATE_TRUNC('day', m.start_time) AS usage_day,
SUM(m.credits_used) AS streaming_credits
FROM snowflake.account_usage.metering_history AS m
JOIN snowflake.account_usage.pipes AS p
ON m.entity_id = p.pipe_id
AND m.name = p.pipe_name
WHERE m.service_type = 'SNOWPIPE_STREAMING'
AND m.start_time >= DATEADD('day', -30, CURRENT_TIMESTAMP())
GROUP BY pipe_fqn, usage_day
ORDER BY usage_day, streaming_credits DESC;
Pair this with a producer-side byte counter per topic. When credits per pipe rise faster than message count, payload width has drifted, and the fix belongs to the source team rather than the platform team. That division of ownership is a defining trait of mature Snowflake FinOps for telecom programmes.
Control 3: reserve Snowflake interactive warehouses for 24x7 demand
Interactive tables and interactive warehouses, generally available since December 2025, are built for low-latency, high-concurrency serving such as operations dashboards and data APIs. Their commercial terms are different from standard warehouses and must be designed for explicitly:
- The minimum billable period is one hour, then per second. Each suspend and resume starts a new minimum and resets the cache.
- Auto-suspend cannot be set below 86,400 seconds, so the warehouse is effectively always on.
- The statement timeout is fixed at 5 seconds; longer queries must fall back to a standard warehouse.
- Interactive tables support
INSERT OVERWRITEbut not UPDATE or DELETE, and carry no Fail-safe.
For a network operations centre that is staffed around the clock, a common Snowflake FinOps for telecom scenario, an always-on serving tier is the correct shape, and paying for it once is cheaper than paying a standard warehouse to resume hundreds of times a day. For a revenue assurance dashboard opened twice daily, it is the wrong shape. That judgement is the heart of Snowflake FinOps for telecom serving design.
-- Snowflake FinOps for telecom: interactive serving tier for the 24x7 NOC
-- (create on a standard warehouse).
-- The interactive warehouse bills a one-hour minimum and suspends no sooner
-- than 24 hours: size it for sustained, not peak-only, demand.
CREATE INTERACTIVE WAREHOUSE IF NOT EXISTS iwh_noc_serving
WAREHOUSE_SIZE = 'XSMALL';
CREATE INTERACTIVE TABLE IF NOT EXISTS noc.slice_health_serving
CLUSTER BY (slice_id, minute_slot)
TARGET_LAG = '60 seconds'
WAREHOUSE = wh_transform_t1
AS
SELECT
slice_id,
region_code,
minute_slot,
setup_failures,
setup_success,
setup_failures / NULLIF(setup_failures + setup_success, 0) AS failure_ratio
FROM noc.slice_health_1m;
Treat the interactive warehouse as a fixed monthly line item and review it like one: is utilisation sustained across all 24 hours, and does the 5-second ceiling hold for the dashboard queries? If either answer is no, the workload belongs on a Gen2 standard warehouse with an aggressive auto-suspend.
Control 4: cap Query Acceleration on Gen2 warehouses
Generation 2 standard warehouses are now the default when a new standard warehouse is created without a generation, where the region supports Gen2. Snowflake's documentation also states that new Gen2 warehouses have the Query Acceleration Service enabled by default with QUERY_ACCELERATION_MAX_SCALE_FACTOR set to 8. Converting an existing Gen1 warehouse does not change its QAS state.
For telecom analysts scanning months of xDRs, acceleration can be valuable. It is also a separately metered serverless cost that can scale well past the warehouse's own size. In Snowflake FinOps for telecom the decision should be explicit and measured, not inherited from a default. Note that Gen2 credit rates differ from Gen1; check the consumption table and test on your own workload.
-- Snowflake FinOps for telecom: Gen2 warehouse for ad hoc analysis with an
-- explicit QAS ceiling.
-- Current vs proposed: QUERY_ACCELERATION_MAX_SCALE_FACTOR 8 (default) -> 2.
-- Takes effect for new queries; no restart required.
CREATE WAREHOUSE IF NOT EXISTS wh_adhoc_xdr
GENERATION = '2'
WAREHOUSE_SIZE = 'MEDIUM'
AUTO_SUSPEND = 60
AUTO_RESUME = TRUE
ENABLE_QUERY_ACCELERATION = TRUE
QUERY_ACCELERATION_MAX_SCALE_FACTOR = 2;
-- Snowflake FinOps for telecom: where did acceleration credits go in the
-- last 14 days? (read-only)
SELECT
warehouse_name,
query_tag,
COUNT(*) AS accelerated_queries,
SUM(credits_attributed_compute) AS compute_credits,
SUM(credits_used_query_acceleration) AS qas_credits
FROM snowflake.account_usage.query_attribution_history
WHERE start_time >= DATEADD('day', -14, CURRENT_TIMESTAMP())
AND credits_used_query_acceleration IS NOT NULL
GROUP BY warehouse_name, query_tag
ORDER BY qas_credits DESC;
Control 5: Snowflake cost attribution and a unit metric
Snowflake cost attribution is what turns cost data into accountability. We combine three mechanisms: object tags on warehouses, pipes and dynamic tables; a structured QUERY_TAG set by every service and BI connection; and the QUERY_ATTRIBUTION_HISTORY view, which apportions warehouse credits to individual queries per minute and per cluster. Two limits matter. Idle warehouse time is not attributed to any query, and queries of roughly 100 ms or less are excluded, so reconcile attributed credits against warehouse metering and report idle cost as its own line.
-- Tag taxonomy for Snowflake FinOps for telecom (run as a governance role).
CREATE TAG IF NOT EXISTS governance.tags.network_domain
ALLOWED_VALUES 'core', 'ran', 'fraud', 'noc', 'revenue_assurance'
COMMENT = 'Telecom domain that owns the spend';
CREATE TAG IF NOT EXISTS governance.tags.freshness_tier
ALLOWED_VALUES 'T0', 'T1', 'T2', 'T3'
COMMENT = 'Contracted freshness tier';
ALTER WAREHOUSE wh_transform_t1 SET TAG
governance.tags.network_domain = 'noc',
governance.tags.freshness_tier = 'T1';
ALTER WAREHOUSE iwh_noc_serving SET TAG
governance.tags.network_domain = 'noc',
governance.tags.freshness_tier = 'T1';
-- Every service session declares itself in a parseable query tag
ALTER SESSION SET QUERY_TAG = '{"domain":"fraud","service":"irsf_scoring","tier":"T0"}';
The unit metric joins attributed credits to an ingest audit table that each pipeline maintains, holding event counts per domain per day. The result is credits per million network events, the single number we ask executive sponsors to track.
-- Snowflake FinOps for telecom unit economics: credits per million events
-- by domain and day (read-only).
-- ops.ingest_audit(event_day DATE, network_domain VARCHAR, event_count NUMBER)
-- is maintained by each ingestion pipeline.
WITH attributed AS (
SELECT
DATE_TRUNC('day', start_time) AS event_day,
TRY_PARSE_JSON(query_tag):domain::VARCHAR AS network_domain,
SUM(credits_attributed_compute
+ COALESCE(credits_used_query_acceleration, 0)) AS query_credits
FROM snowflake.account_usage.query_attribution_history
WHERE start_time >= DATEADD('day', -30, CURRENT_TIMESTAMP())
GROUP BY event_day, network_domain
)
SELECT
a.event_day,
a.network_domain,
a.query_credits,
i.event_count,
ROUND(a.query_credits / NULLIF(i.event_count / 1e6, 0), 4) AS credits_per_million_events
FROM attributed AS a
JOIN ops.ingest_audit AS i
ON i.event_day = a.event_day
AND i.network_domain = a.network_domain
ORDER BY a.event_day, a.network_domain;
This view excludes streaming ingest, serverless features and storage by design, since query attribution covers warehouse compute only. Add the Control 2 streaming credits per domain, mapped through pipe tags, to produce a fully loaded figure.
Control 6: guardrails with budgets and resource monitors
Guardrails in Snowflake FinOps for telecom must reflect the business criticality of each telecom workload. A fraud scoring pipeline that is suspended by a credit quota is a revenue loss event, so its monitors notify and never suspend. A data science sandbox can be suspended without consequence. Budgets provide tag-scoped visibility and alerts; resource monitors enforce credit quotas on warehouses.
-- Snowflake FinOps for telecom: budget scoped to the fraud domain through tags (SET_RESOURCE_TAGS replaces
-- the deprecated ADD_RESOURCE_TAG). Limit is in credits per month.
CREATE SNOWFLAKE.CORE.BUDGET IF NOT EXISTS finops.budgets.fraud_domain_budget();
CALL finops.budgets.fraud_domain_budget!SET_RESOURCE_TAGS(
[
[(SELECT SYSTEM$REFERENCE('TAG', 'governance.tags.network_domain', 'SESSION', 'APPLYBUDGET')), 'fraud']
],
'UNION');
CALL finops.budgets.fraud_domain_budget!SET_SPENDING_LIMIT(${FRAUD_MONTHLY_CREDITS});
CALL finops.budgets.fraud_domain_budget!SET_EMAIL_NOTIFICATIONS(
'${BUDGET_EMAIL_INTEGRATION}',
'${FINOPS_DL_EMAIL}');
-- Fraud warehouse: notify only. Never suspend a revenue-protecting workload.
CREATE OR REPLACE RESOURCE MONITOR rm_fraud_scoring
WITH CREDIT_QUOTA = ${FRAUD_WH_MONTHLY_CREDITS}
FREQUENCY = MONTHLY
START_TIMESTAMP = IMMEDIATELY
TRIGGERS
ON 75 PERCENT DO NOTIFY
ON 100 PERCENT DO NOTIFY;
ALTER WAREHOUSE wh_fraud_scoring SET RESOURCE_MONITOR = rm_fraud_scoring;
Suspension is reserved for non-production. Because SUSPEND_IMMEDIATE cancels running queries, we write a confirmation gate into the procedure: verify which warehouses the monitor will govern before attaching it, and validate the assignment afterwards.
-- Snowflake FinOps for telecom sandbox guardrail.
-- CONFIRMATION GATE: run the verification query and confirm in the change
-- ticket that ONLY sandbox warehouses are listed before attaching the monitor.
-- Verification (before):
SHOW WAREHOUSES LIKE 'WH_SANDBOX_%';
CREATE OR REPLACE RESOURCE MONITOR rm_sandbox
WITH CREDIT_QUOTA = ${SANDBOX_MONTHLY_CREDITS}
FREQUENCY = MONTHLY
START_TIMESTAMP = IMMEDIATELY
TRIGGERS
ON 80 PERCENT DO NOTIFY
ON 100 PERCENT DO SUSPEND
ON 110 PERCENT DO SUSPEND_IMMEDIATE;
ALTER WAREHOUSE wh_sandbox_ds SET RESOURCE_MONITOR = rm_sandbox;
-- Validation (after): the resource_monitor column must read RM_SANDBOX
-- for sandbox warehouses only.
SHOW WAREHOUSES LIKE 'WH_SANDBOX_%';
-- Rollback: ALTER WAREHOUSE wh_sandbox_ds UNSET RESOURCE_MONITOR;
Snowflake has also added cost anomaly alerting with notification integrations and, during 2026, per-user quotas within budgets. Check the release status for your account before building procedures on any feature still in preview.
Control 7: right-size storage and retention for telecom data
Telecom data is large and long-lived, which makes retention a Snowflake FinOps for telecom lever in its own right. Storage cost compounds through Time Travel and Fail-safe on high-churn tables. Staging and replayable intermediate data, which can be rebuilt from Kafka or the raw layer, belongs in transient tables that carry no Fail-safe. Raw tables need retention aligned to regulatory obligations, which vary by jurisdiction and licence; agree those periods with legal and the regulator-facing team, not with the platform team alone.
-- Snowflake FinOps for telecom storage: replayable staging is transient,
-- with short Time Travel and no Fail-safe.
CREATE TRANSIENT TABLE IF NOT EXISTS staging.xdr_dedup_window (
event_id VARCHAR NOT NULL,
event_ts TIMESTAMP_NTZ NOT NULL,
imsi_hash VARCHAR,
payload VARIANT,
CONSTRAINT pk_xdr_dedup_window PRIMARY KEY (event_id) RELY
)
DATA_RETENTION_TIME_IN_DAYS = 1;
-- Raw xDR: current vs proposed DATA_RETENTION_TIME_IN_DAYS 7 -> 1.
-- Online change, no restart. Confirm the recovery objective first:
-- shorter Time Travel narrows the window for point-in-time recovery.
ALTER TABLE raw.core_session_events
SET DATA_RETENTION_TIME_IN_DAYS = 1;
-- Snowflake FinOps for telecom: where are the bytes? (read-only)
SELECT
table_catalog || '.' || table_schema || '.' || table_name AS table_fqn,
is_transient,
ROUND(active_bytes / POWER(1024, 4), 3) AS active_tb,
ROUND(time_travel_bytes / POWER(1024, 4), 3) AS time_travel_tb,
ROUND(failsafe_bytes / POWER(1024, 4), 3) AS failsafe_tb
FROM snowflake.account_usage.table_storage_metrics
WHERE deleted = FALSE
ORDER BY failsafe_bytes + time_travel_bytes DESC
LIMIT 25;
Automating the Snowflake FinOps for telecom daily report
Dashboards are useful; a daily exception report that lands in the operations channel is what changes behaviour. The script below computes credits per million events by domain and flags any domain whose latest value deviates from its trailing baseline. Credentials are read from the environment and key-pair authentication is used; nothing is hardcoded.
"""Snowflake FinOps for telecom: daily unit-cost exception report.
Requires: snowflake-connector-python 3.x
Environment: SNOWFLAKE_ACCOUNT, SNOWFLAKE_USER, SNOWFLAKE_PRIVATE_KEY_FILE,
SNOWFLAKE_ROLE, SNOWFLAKE_WAREHOUSE
"""
import os
import statistics
from collections import defaultdict
import snowflake.connector
UNIT_COST_SQL = """
WITH attributed AS (
SELECT
DATE_TRUNC('day', start_time)::DATE AS event_day,
TRY_PARSE_JSON(query_tag):domain::VARCHAR AS network_domain,
SUM(credits_attributed_compute
+ COALESCE(credits_used_query_acceleration, 0)) AS query_credits
FROM snowflake.account_usage.query_attribution_history
WHERE start_time >= DATEADD('day', -29, CURRENT_DATE())
GROUP BY 1, 2
)
SELECT
a.event_day,
a.network_domain,
a.query_credits / NULLIF(i.event_count / 1e6, 0) AS credits_per_million
FROM attributed AS a
JOIN ops.ingest_audit AS i
ON i.event_day = a.event_day
AND i.network_domain = a.network_domain
ORDER BY a.network_domain, a.event_day
"""
# Snowflake FinOps for telecom exception thresholds
Z_THRESHOLD = 3.0 # flag deviations beyond three standard deviations
MIN_HISTORY_DAYS = 14 # do not judge a domain on a short baseline
def fetch_unit_costs():
conn = snowflake.connector.connect(
account=os.environ["SNOWFLAKE_ACCOUNT"],
user=os.environ["SNOWFLAKE_USER"],
authenticator="SNOWFLAKE_JWT",
private_key_file=os.environ["SNOWFLAKE_PRIVATE_KEY_FILE"],
role=os.environ["SNOWFLAKE_ROLE"],
warehouse=os.environ["SNOWFLAKE_WAREHOUSE"],
)
try:
cur = conn.cursor()
cur.execute("ALTER SESSION SET QUERY_TAG = "
"'{\"domain\":\"finops\",\"service\":\"daily_report\",\"tier\":\"T3\"}'")
cur.execute(UNIT_COST_SQL)
series = defaultdict(list)
for event_day, domain, cpm in cur.fetchall():
if domain and cpm is not None:
series[domain].append((event_day, float(cpm)))
return series
finally:
conn.close()
def find_exceptions(series):
exceptions = []
for domain, points in series.items():
if len(points) < MIN_HISTORY_DAYS + 1:
continue
*history, (latest_day, latest) = points
values = [v for _, v in history]
mean = statistics.fmean(values)
stdev = statistics.pstdev(values)
if stdev == 0:
continue
z = (latest - mean) / stdev
if abs(z) >= Z_THRESHOLD:
exceptions.append((domain, latest_day, latest, mean, z))
return exceptions
if __name__ == "__main__":
for domain, day, latest, mean, z in find_exceptions(fetch_unit_costs()):
print(f"[{day}] {domain}: {latest:.4f} credits per million events "
f"(baseline {mean:.4f}, z={z:+.1f})")
The Snowflake FinOps operating model for operators
Tools do not sustain savings; operating rhythm does. We align the controls to the Inform, Optimize and Operate phases of the FinOps Foundation framework, with explicit ownership between the platform team, domain owners and finance. Snowflake FinOps for telecom succeeds when all three read the same number.
Figure 3. The Snowflake FinOps for telecom operating loop, anchored on one unit metric.
| Capability | Foundational | Managed | Optimised |
|---|---|---|---|
| Attribution | Warehouse-level only | Tags on all objects, query tags on services | Fully loaded cost per domain, idle reported separately |
| Freshness | One lag for everything | Tiers defined and tagged | Tiers re-priced quarterly with consumers |
| Guardrails | Account-level monitor | Tag-scoped budgets, criticality-aware monitors | Anomaly alerts routed to domain on-call |
| Unit metric | Monthly invoice | Credits per million events, monthly | Daily exceptions, trend in executive review |
A 90-day plan
The plan below is how we sequence a Snowflake FinOps for telecom programme so that measurement always precedes change.
Days 1 to 30, Inform. Baseline by service type, deploy the tag taxonomy, enforce query tags on every service account, stand up the ingest audit table and publish the first unit metric. No configuration changes to production compute in this phase.
Days 31 to 60, Optimize. Agree freshness tiers with each domain owner, re-key target lag, convert replayable staging to transient tables, cap Query Acceleration where it is not earning its cost, and open payload contracts with the source teams for the widest streams.
Days 61 to 90, Operate. Activate tag-scoped budgets and criticality-aware monitors, automate the daily exception report, and institute a monthly review in which finance and domain owners read the same unit metric.
Limits of this guidance
We have not published Snowflake FinOps for telecom savings percentages because they depend entirely on the starting configuration, contracted credit price and workload mix; any figure quoted without that context would mislead. Feature availability differs by cloud and region, interactive analytics and Gen2 included. Query attribution covers warehouse compute only. Every change described here should be tested in a non-production account first, rolled out in stages with a rollback path, and supported by a robust disaster recovery posture.
Frequently asked questions
What is Snowflake FinOps for telecom?
It is the practice of managing Snowflake spend on operator data platforms against business value: pricing data freshness per workload, attributing credits to network domains, enforcing guardrails by criticality and tracking a unit metric such as credits per million network events.
How long does a Snowflake FinOps for telecom programme take?
Our standard sequence runs 90 days: 30 days to inform, 30 to optimize and 30 to operate. Snowflake FinOps for telecom then becomes a monthly operating rhythm rather than a project.
Are Snowflake interactive warehouses cheaper than standard warehouses for dashboards?
Only where demand is sustained. Interactive warehouses bill a one-hour minimum and cannot auto-suspend in under 24 hours, so they suit a 24x7 operations centre. Intermittent dashboards are usually cheaper on a Gen2 standard warehouse with a short auto-suspend.
How is Snowpipe Streaming billed with the high-performance architecture?
At a flat rate per uncompressed gigabyte of data ingested, as described in Snowflake's Snowpipe Streaming cost documentation. Reducing payload width at the source is the most direct lever.
Which Snowflake views should a telecom FinOps team monitor first?
METERING_HISTORY for the service-type baseline, QUERY_ATTRIBUTION_HISTORY for per-query compute, DYNAMIC_TABLE_REFRESH_HISTORY for freshness efficiency, WAREHOUSE_METERING_HISTORY for serving tiers and TABLE_STORAGE_METRICS for retention cost. Further detail is in the dynamic tables cost guide and the interactive analytics documentation.
How MinervaDB supports operators
MinervaDB is a vendor-neutral database infrastructure company trusted by 900+ enterprises. Our Snowflake consulting and support practice runs Snowflake FinOps for telecom assessments, architecture reviews and 24x7 operations for real-time platforms, and our telecom data analytics team brings network-domain depth to the work. For a cross-platform view of cost controls, see our analysis of Snowflake and Databricks FinOps controls. Where Snowflake is not the right fit for a workload, we will say so.
Running this in production?
MinervaDB provides Snowflake Consulting and Data Warehousing Support with 24x7 coverage and a 15-minute S1 response. Talk to an engineer.