Reviewability is a data platform feature
Reviewability is not decoration for data work. It is part of whether a shared platform can change safely once more than one person has to reason about the same models and workflows.
Reviewability is the platform’s ability to make a change understandable before production explains it more forcefully.
A repository isn’t reviewable merely because transformations live in Git. The reviewer needs to see the decision, compiled behavior, affected objects, data risk, and operational path without a guided tour from the author.
That capability affects delivery speed as directly as runtime performance. When changes are expensive to understand, teams either move slowly or approve from trust in the person rather than trust in the system.
Review the semantic change
A useful pull request explains what business meaning changed.
Changing a join, filter, key, or time boundary can alter grain, history, and downstream metrics even when the SQL diff is small. The model should state one-row meaning, key, materialization, freshness, and important assertions close enough that the reviewer can compare the new contract with the old one.
Names and layers matter. A file called customer_activity.sqlx should define customer activity, not invoke a helper that quietly decides eligibility elsewhere. If the important rule is hidden behind generic macros or workflow flags, the visible diff isn’t the real change.
Show compiled behavior
SQLX, macros, configuration, and environment variables can make source code differ materially from executed SQL. CI should compile the project and expose meaningful changes in the generated actions.
A reviewer should be able to inspect:
- final SQL or operations for changed models
- dependency additions and removals
- materialization and partition changes
- incremental predicates and merge keys
- selected environment values without secrets
- assertions attached to the output
Generated output doesn’t need to flood every pull request. It needs to be available and summarized where the source abstraction hides consequential behavior.
Make blast radius visible
Use the dependency graph to list downstream models, reports, exports, and operational consumers affected by the change. Distinguish direct rebuilds from semantic consumers that won’t automatically fail when meaning changes.
Estimate data impact where practical: partitions rewritten, historical range touched, row-count change, bytes processed, and expected runtime. A one-line predicate change that rebuilds seven years of data deserves a different review than a column description.
Tagging everything “data” isn’t impact analysis. The graph and ownership metadata should identify who needs to care.
Provide evidence proportional to risk
For a low-risk additive column, compilation and schema checks may be enough. A key or grain change may need before-and-after samples, uniqueness tests, reconciliation against the old model, and report validation. An incremental change should prove transition behavior and convergence with a full build.
Use production-shaped fixtures and bounded production comparisons. Synthetic happy paths are useful for logic. They rarely contain the duplicate IDs, late children, null ownership, and timezone damage that made the model interesting.
The pull request should say what was tested and what remains uncertain. Confidence isn’t a substitute for evidence, although it’s much easier to type.
Keep one route from source to production
Reviewability collapses when scheduled runs, manual repairs, and backfills use different implementations.
The same declarative model should support ordinary execution and wider affected sets. Orchestration may choose schedule, range, and concurrency, but it shouldn’t contain an alternative business definition. Emergency scripts should be retired or promoted into the reviewed path after use.
A change that can’t be reproduced outside the author’s terminal isn’t ready to become shared platform behavior.
Design abstractions for the caller
A helper earns its place when a reviewer can understand the calling model more easily and inspect the helper’s contract independently. It fails when the call site becomes concise but opaque.
Prefer domain-specific names over generic wrappers. resolve_order_currency() carries more useful intent than apply_transform(config). Keep parameter sets small. Avoid Boolean switches that turn one helper into several hidden programs.
Duplication is often cheaper than an abstraction whose behavior varies by context. Review cost, not line count, is the deciding metric.
Include operational behavior
The reviewer also needs to know how the change deploys and fails.
Will it replace a table, merge rows, or delete partitions? Can old and new schemas overlap safely? What happens if the run fails halfway? Can it be retried? Is rollback a code revert, a data restore, or a rebuild? Which alerts will detect a bad outcome?
These questions belong in review because data deployments persist state. Reverting SQL doesn’t automatically revert the rows already written.
Measure whether the platform is reviewable
Useful signals include review cycle time by risk, defects found before merge, emergency fixes after deployment, models with missing owners or tests, and changes that require synchronous explanation from one person.
The goal isn’t faster approval. It’s faster justified approval.
A reviewable platform carries its own explanation through named models, explicit contracts, dependency graphs, compiled output, assertions, and repeatable execution. Once shared ownership begins, that isn’t documentation polish. It’s part of the system’s ability to change.
More in this domain: Data
Browse allBigQuery freshness checks that detect partial loads
A recent row doesn’t prove a load is complete. Track expected source scopes, validated source coverage, and successful publication separately so missing data can’t look healthy.
Dataform assertions: make failures block downstream models
A failed assertion won’t automatically stop a consumer of the tested table. Add the assertion dependency, include it in the run, and publish only from a stable, validated candidate.
BigQuery physical vs. logical storage: compare the full bill
Physical billing rewards compression, but retained versions can consume the savings. Compare both models using the dataset’s current data, rewrite history, and recovery requirements.
BigQuery primary keys are NOT ENFORCED: what to validate
BigQuery can use primary and foreign keys to optimize queries without checking whether the data satisfies them. Validate the full relationship before declaring it, then protect it during publication.
Dataform vs. transformation scripts: keeping warehouse changes reviewable
Use Dataform when shared BigQuery transformations need explicit dependencies, materialization, and checks. Keep scripts where they remain simpler, and judge both by how safely someone else can change them.
Related patterns
BigQuery cost guardrails that won't break your teams
BigQuery cost control works when guardrails are designed around workload shape and blast radius, not around shaming whoever happened to run the last expensive query.
Incremental models are only safe when change detection is explicit
Incremental models are trustworthy only when they can deliberately identify which records need another pass after late or changed upstream data shows up.
What we keep out of orchestration in data platforms
We use orchestration to sequence work, not to become the real home of model semantics, cleanup logic, or hidden branching behavior in the data platform.
Streaming buffer is your hidden constraint
When BigQuery streaming pain shows up as a DML error, the real problem is usually workload shape. Streaming wants append-and-reconcile thinking, not row-by-row sync fantasies.