<- Case studies
Client name withheld pending approvalImplementation in progress

Equipping a connected-device data platform to scale with dbt.

How a smart-water technology company replaced warehouse-managed transformation logic with a version-controlled, tested, observable dbt workflow—without moving its data or adding another orchestration platform.

Industry

Smart water technology

Platform

Snowflake · dbt Core · GitHub Actions

Objective

Prepare for growth toward 100,000 devices

Scope

Transformation architecture and delivery system

Context

Preparing the platform for its next stage of growth

The client develops connected water-monitoring technology that helps customers understand consumption, identify abnormal behavior, and manage resources more effectively.

As the company worked toward supporting 100,000 connected devices, its engineering team recognized that decisions made today would shape the reliability, cost, and maintainability of its data systems at that scale.

The engagement began while investigating an immediate production pipeline issue. That investigation exposed a broader architectural risk: business-critical Snowflake transformations were running, but much of their logic existed primarily as database procedures, functions, and scheduled tasks.

The immediate issue could be fixed. The more important opportunity was to strengthen the system around it before the company's device footprint—and the operational cost of a failure—grew substantially larger.

The challenge

Operational logic without a complete engineering system

The client had already built a capable IoT pipeline for moving device telemetry through AWS and into Snowflake. Snowflake handled ingestion, transformation, historical state, partner-facing data, and the publication of calculated corrections back to the application.

The active flow-correction workflow included:

  • Hourly ingestion from an S3-backed Snowflake stage
  • A multi-step zero-correction algorithm implemented inside a stored procedure
  • Permanent intermediate tables recreated during each run
  • Updates to meter state and correction history
  • A Snowflake Python function that submitted correction results to the client API
  • A task graph coordinating ingestion, transformation, history, and publishing

Although operational, the architecture lacked several controls normally expected in a production software system. Changes were difficult to review before execution. Dependencies had to be reconstructed from stored-procedure code. Developers lacked isolated environments. Data-quality expectations were not consistently executable, and missed hourly ingestion had no straightforward recovery mechanism.

A static DDL export also proved insufficient as an authoritative representation of the warehouse: it omitted objects and columns present in the live Snowflake environment.

Architecture

Modernize the transformation layer, not the entire platform

Rather than replacing working ingestion infrastructure or introducing a new external platform, the solution focused on modernizing the transformation layer around Snowflake.

dbt Core became the framework through which warehouse transformations would be defined, reviewed, tested, documented, and deployed. Snowflake remained the system of record and execution engine. This was a transformation migration—not a data migration. Historical data remained in place, and existing ingestion continued throughout implementation.

Before

Working pipeline, concentrated transformation logic

Initial operating model

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

Multi-step algorithm concentrated in a stored procedure and numbered intermediate tables.

Change validation

Dependencies reconstructed manually; shared objects made isolated testing difficult.

Recovery and visibility

Investigation-driven detection and no standard operator workflow for missed hourly ingestion.

After

Explicit transformation graph with owned delivery controls

Implemented target architecture

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

Nine-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.

01

Git defines the transformation system

Models, tests, functions, deployment configuration, and operational documentation are reviewed and versioned together.

02

Every execution environment is isolated

Developers and pull requests build into dedicated Snowflake schemas without overwriting shared or production relations.

03

Migration confidence comes from reconciliation

The dbt implementation is compared directly with the existing production logic using identical point-in-time inputs.

04

Operational behavior is observable and recoverable

Data-quality failures, stalled pipelines, and missed ingestion windows produce actionable signals and documented recovery paths.

05

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, and tasks
  • The client's exported DDL as a supplemental snapshot

The discovery process identified three active production domains—flow correction, full-datapoint ingestion, and partner data sharing—and uncovered operational behavior that table definitions alone did not reveal, including a Python function used to publish calculated corrections to the client API.

Publishing was brought under version control while remaining separately governed so ordinary local and CI builds could never make outbound production calls.

Implementation proof

A maintainable transformation layer

The existing zero-correction stored procedure was decomposed into an explicit dbt model graph. Each stage became a named, testable model with documented upstream and downstream dependencies. Staging and mart models represented the full-datapoint source and both internal and partner-facing outputs.

17
dbt models
30
automated tests
28
declared sources
9
reconciliation comparisons

The generated lineage graph gives engineers a visual map of the system and makes the effect of a proposed change visible before deployment.

Migration confidence

Proving equivalence before cutover

Migration was designed around evidence rather than assumption. The reconciliation workflow creates two isolated Snowflake environments from the same point-in-time data using zero-copy cloning. It runs the existing procedure against one environment and the dbt model chain against the other.

Every intermediate output is compared in both directions across nine stages of the zero-correction transformation. This validates more than a final table: it makes any difference throughout the algorithm locatable and explainable.

Current status: the reconciliation framework and comparison suite are implemented. Final credentialed validation, production-readiness checks, and controlled cutover remain part of the active implementation.

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.

CLIENT_DBT_DEV.DBT_<SNOWFLAKE_USER>

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.

CI/CD authenticates through GitHub OIDC. No Snowflake password, private key, personal access token, or refresh token is stored in GitHub. Snowflake Workspaces connects to the same Git-governed project for native execution and inspection.

Operations

Recovery and visibility are part of the implementation

The rollout includes an operator-triggered backfill workflow for missed flow-correction ingestion. It determines which completed UTC hours are missing, restores the relevant S3 stage partitions in order, rebuilds the affected dbt path, and preserves approval and validation evidence in GitHub.

Snowflake's loaded-file tracking keeps normal retries idempotent. Monitoring definitions cover pipeline execution, source freshness, and critical data-quality conditions, with actionable alerts linked to the appropriate runbook.

One protective test addresses devices reporting meaningful flow rates while recording effectively zero volume. The upstream calculation fix addresses the source behavior; the dbt test provides downstream protection against recurrence.

Before and after

From warehouse objects to an owned engineering system

CapabilityInitial stateImplemented design
Transformation ownershipLogic maintained primarily inside Snowflake proceduresModels, functions, tests, and configuration maintained in Git
DevelopmentChanges tested against shared database objectsPersonal Snowflake schema for every developer
Pull-request validationPrimarily manualIsolated Snowflake build and automated test suite
Migration validationFinal outputs inspected manuallyNine bidirectional reconciliation comparisons
DependenciesReconstructed from procedures and tasksGenerated documentation and interactive lineage
CI authenticationLong-lived credentials would be requiredGitHub OIDC with no long-lived Snowflake secrets
Production executionNative stored-procedure task graphSnowflake-native dbt Project execution
PublishingPython function represented primarily as warehouse DDLVersioned dbt Python function with controlled publishing nodes
Missed ingestionManual investigation with no standard recovery pathAuditable, operator-triggered hourly backfill
MonitoringFailures discovered through investigationAutomated data tests and pipeline alerts
Team ownershipWarehouse knowledge concentrated in individualsShared runbooks, examples, onboarding, and repeatable workflows

Result

A foundation designed to scale with the business

The implementation establishes the components of a version-controlled transformation system: explicit models, executable tests, documented sources and lineage, isolated development, secure CI/CD, reconciliation, recovery workflows, monitoring definitions, and team-facing operational documentation.

Production adoption is being handled as a separate engineering milestone. Final validation, operator testing, onboarding, and cutover will determine the observed operational outcomes; they are not being presented here as completed business results.

The intended result is not simply a dbt repository. It is a shared engineering system that lets the client's team understand, review, test, operate, and extend how production data changes—from the first source record through the final operational output.

Start a conversation

Working through a similar transformation problem?

Bring the current architecture, the operational constraint, and the outcome your team needs to own.

Book a consultation ->