Preparing a Snowflake transformation platform for continued growth with dbt.
How a growing connected-device company evolved its Snowflake transformation workflow into an explicit dbt graph with automated validation, recovery controls, and stateful downstream anomaly detection without moving its data or adding another orchestration platform.
Client
Growing connected-device company
Platform
Snowflake + dbt Core + GitHub Actions
Objective
Create an owned production transformation system
Status
Deployed with parallel production validation
Architecture at a glance
The ingestion foundation stayed. The engineering model changed.
The implementation retained the existing device, AWS, and Snowflake foundation while adding explicit dbt lineage, isolated development, controlled delivery, exact reconciliation, and operational safeguards.
Before
Operational pipeline governed through mutable warehouse state
Connected devices
Telemetry and meter signals
AWS + S3
Hourly staged ingestion
Snowflake task graph
Ingestion, stored procedure, history, and publishing coordinated inside the warehouse
Operational outputs
Meter state, correction history, partner data, and client API
Transformation logic
8 transformation stages and a state-changing merge concentrated in 1 procedure; 9 permanent tables recreated as working state.
Change validation
No authoritative Git source or isolated build; dependencies and side effects reconstructed manually.
Recovery and visibility
Investigation-driven failure detection with no standard operator backfill for missed hourly ingestion.
After
Explicit transformation graph with owned delivery controls
Connected devices
Existing telemetry sources remain unchanged
AWS + S3
Existing ingestion foundation remains in place
Snowflake + dbt
28 sources → staging → explicit intermediate models → marts and controlled publishing
Owned outputs
Internal state, history, partner data, and separately governed API publishing
Development plane
Personal developer schemas, temporary pull-request schemas, generated documentation, and lineage.
Delivery plane
Git-reviewed changes, GitHub Actions validation, OIDC authentication, and Snowflake-native execution.
Operations plane
9-stage reconciliation, executable tests, freshness checks, alerts, runbooks, and hourly backfill.
The migration changes how transformations are developed and operated. It does not move historical data or replace the existing ingestion path.
Context
Continued growth required a stronger transformation operating model
The company had built a functioning IoT platform and was preparing its data architecture for continued growth. As transformation responsibilities expanded, the engineering team identified an opportunity to strengthen how critical Snowflake logic was developed, validated, deployed, and operated.
The existing architecture had supported an earlier stage of the platform. Business-critical behavior lived across Snowflake procedures, tasks, tables, and downstream operational outputs without 1 authoritative Git source. A static DDL export did not match the live catalog, and understanding 1 production path required reconstructing execution order, state changes, and external side effects by hand.
Those constraints were addressed proactively before greater device volume and product dependence made them more expensive. The target operating model added isolated development, pull-request builds, executable quality gates, exact migration tests, dependable lineage, and standard recovery paths.
The challenge
Production behavior depended on implicit warehouse state
The company had a functioning IoT pipeline moving device telemetry through AWS and into Snowflake. Snowflake handled ingestion, transformation, historical state, data sharing, and publication of calculated results back to the application.
The active transformation workflow included:
- Hourly ingestion from an S3-backed Snowflake stage
- A monolithic procedure combining 8 transformation stages with a state-changing merge
- 9 numbered permanent tables recreated as intermediate working state on every run
- Updates to device state and correction history
- A Snowflake Python function publishing calculated results to an application API
- A task graph coordinating ingestion, transformation, history, and publishing
Pure transformation, persistent state mutation, scheduling, and outbound publishing were coupled in 1 operational chain. Changes were difficult to review before execution; developers lacked isolated environments; data-quality expectations were not consistently executable; and missed hourly ingestion had no standard recovery mechanism.
1 parameter lookup used LIMIT 1without an ordering rule, making its result nondeterministic if the table ever contained multiple rows. The supplied DDL export also omitted live relations, metadata, and entire production domains. The migration therefore began by treating the live catalog, rather than the export or anyone's memory, as authoritative.
Architecture
Modernize the transformation layer, not the entire platform
The solution focused on the transformation layer rather than replacing infrastructure that already moved and stored production data successfully.
dbt Core became the framework through which warehouse transformations are defined, reviewed, tested, documented, and deployed. Snowflake remains the system of record and execution engine. This is a transformation migration, not a historical data migration.
Git defines the transformation system
Models, tests, functions, deployment configuration, and operational documentation are reviewed and versioned together.
Every execution environment is isolated
Developers and pull requests build into dedicated Snowflake schemas without overwriting shared or production relations.
Migration confidence comes from reconciliation
The dbt implementation is compared directly with the existing production logic using identical point-in-time inputs.
Operational behavior is observable and recoverable
Data-quality failures, stalled pipelines, and missed ingestion windows produce actionable signals and documented recovery paths.
The existing platform is reused
Snowflake-native execution, authentication, cloning, scheduling, and alerting avoid unnecessary infrastructure and licensing.
Discovery
Establishing the live warehouse as the source of truth
The project combined several forms of discovery:
- Live Snowflake catalog inspection using SHOW and GET_DDL
- dbt-codegen generation against live relations and columns
- Historical Snowflake task execution analysis
- Dependency tracing through procedures, functions, tasks, and application publishing
- The existing DDL export as a supplemental snapshot
This work identified the active production domains and operational behavior that table definitions alone did not expose. Publishing was brought under version control while remaining separately governed so local and CI builds cannot make outbound production calls.
Implementation proof
A maintainable transformation and delivery layer
The stored-procedure workflow was decomposed into an explicit dbt graph. Each stage became a named, testable model with documented upstream and downstream dependencies. The same repository now governs development, validation, deployment, monitoring definitions, recovery procedures, and onboarding.
Generated documentation and lineage make the transformation graph inspectable. GitHub OIDC lets CI/CD authenticate without storing Snowflake passwords, private keys, personal access tokens, or refresh tokens.
Migration confidence
Proving equivalence before final cutover
Validation creates 2 isolated Snowflake environments from the same point-in-time data using zero-copy cloning. It runs the existing procedure against 1 environment and the dbt model chain against the other.
Every intermediate output is compared in both directions across 9 stages. This validates more than a final table and makes any difference throughout the algorithm locatable and explainable.
Developer experience
A workflow the engineering team can own
A cross-platform setup process installs the locked development environment, authenticates engineers through Snowflake's browser-based flow, and verifies the dbt connection.
Each engineer receives a personal Snowflake schema. Pull requests follow the same isolation principle: GitHub Actions creates a temporary schema, runs the build and test suite, and removes temporary objects when the pull request closes.
Snowflake Workspaces connects to the same Git-governed project for native execution and inspection. Git, not a browser editor, remains the source of truth.
Operations
Recovery and visibility are part of the implementation
An operator-triggered backfill workflow identifies completed UTC hours missing from ingestion, restores the relevant staged partitions in order, rebuilds the affected dbt path, and preserves approval and execution evidence.
Snowflake loaded-file tracking keeps ordinary retries idempotent. Monitoring covers task execution, source freshness, and critical data-quality conditions, with Slack alerts linked directly to response runbooks.
Production ingestion procedures and schedules are now defined in Git and deployed through CI/CD with fail-closed verification of ownership, state, schedule, and required grants.
Operational capability
A product-level system for persistent flow anomalies
The new foundation also became the delivery system for a stateful detector. A device that loses its expected daily quiet periods may have developed sensor drift or may be reporting a genuine continuous-flow event. A single threshold cannot distinguish persistent behavioral change from noise, missing readings, or 1 isolated abnormal day.
The detector builds a daily profile for each device, evaluates complete days against that device's own lagged baseline, and preserves durable episode history. Recovery requires a configured streak of clean days, preventing state from oscillating when readings hover near a boundary.
NORMAL
The latest complete day remains consistent with the device's established baseline.
SUSPECT
The abnormal condition is present, but the persistence requirement has not yet been met.
ALERTING
A persistent episode is open with a stable identity, duration, and estimated magnitude.
STALE
Recent ingestion is not current enough to support a trustworthy evaluation.
INSUFFICIENT_DATA
The day lacks enough usable readings to make a reliable determination.
INELIGIBLE
The device lacks a trustworthy baseline or is intentionally excluded from this detection path.
This is a downstream operational system, not a threshold query. It includes durable episode identity, transition history, streak counters, closure behavior, coverage and eligibility guards, deterministic evaluation dates, bounded state replay, isolated backtesting, deduplicated Slack delivery, deployment controls, and operator runbooks. A fleet-wide summary reports the daily count in every state.
Before and after
From warehouse objects to an owned engineering system
| Capability | Initial state | Implemented system |
|---|---|---|
| Transformation ownership | No authoritative Git source; critical logic lived primarily inside mutable Snowflake procedures and tables | Models, functions, tests, and configuration maintained in Git |
| Development | Changes executed against shared warehouse objects | Personal Snowflake schema for every developer |
| Pull-request validation | No isolated automated build | Temporary Snowflake schema and full automated test suite |
| Migration validation | Final outputs inspected manually | 9 bidirectional reconciliation comparisons |
| Dependencies | Reconstructed manually from procedures, tasks, tables, and side effects | Generated documentation and interactive lineage |
| CI authentication | Long-lived credentials would be required | GitHub OIDC without stored Snowflake secrets |
| Production execution | Native stored-procedure task graph | Snowflake-native dbt Project execution |
| Missed ingestion | Manual investigation without a standard recovery path | Auditable, operator-triggered hourly backfill |
| Monitoring | Failures and stale data discovered through manual investigation | Automated task, freshness, and data-quality alerts |
| Team ownership | Warehouse knowledge concentrated in individuals | Shared runbooks, examples, onboarding, and repeatable workflows |
Result
A production foundation the client can inspect, operate, and extend
The delivered system combines 21 explicit models, 83 dbt tests, 28 documented sources, 9-stage exact reconciliation, isolated development, secure CI/CD, recovery workflows, monitoring, alerting, and team-facing operational documentation.
Those are implemented capabilities, not estimates of future savings. Final transformation cutover and any resulting business outcomes remain separately governed milestones.
The result is more than a dbt repository. It is an owned engineering system that makes production data behavior visible, reviewable, testable, recoverable, and transferable to the client's team.
Start a conversation
Working through a similar transformation problem?
Bring the current architecture, the operational constraint, and the outcome your team needs to own.
Schedule a consultation →