An open-source data quality testing framework that uses a simple YAML-based language (SodaCL) to define data quality checks and integrates with any data source.
Soda Core is the YAML-first data quality framework that makes data testing accessible to people who aren't Python engineers. That's the main pitch and it's a real one: analysts, data stewards, and domain experts can write missing_count(email) = 0 in YAML without learning Python's import system or GX's Context/Checkpoint model. Pair that with SodaCL (Soda Checks Language), which has first-class support for common patterns like freshness, schema validation, and distribution anomalies, and Soda hits a sweet spot for teams that want checks-as-config.
Soda sits alongside dbt tests and Great Expectations in the data-quality tooling landscape. It's the closest to dbt tests in simplicity but richer in check types, and the closest to GX in feature breadth but significantly simpler to adopt. Native connectors for Snowflake, BigQuery, Redshift, Databricks, Postgres, and Spark mean it works anywhere your data lives. Runs on CLI, in CI/CD (GitHub Actions, GitLab), inside Airflow/Dagster, or as the managed Soda Cloud SaaS with dashboards and alerting built in.
A client with a 15-person analytics team (mostly analysts, two data engineers) had adopted dbt for transformation but was drowning in quality issues the analysts couldn't fix themselves. Schema was the data engineers' job, so the feedback loop was slow. We introduced Soda Core with an empty YAML file template per source table and taught the analyst team SodaCL in a 90-minute workshop. Within two weeks, analysts had written 400 checks across 80 tables without data-engineering involvement. The checks covered the business rules the analysts knew and the data engineers didn't: "this column should always be positive," "these IDs must match the CRM," "this text field should never contain the word 'TEST'." Quality incidents dropped sharply. Lesson: the bottleneck wasn't technical; it was the gap between who knew the data (analysts) and who could express checks (engineers). Soda closed that gap.
Soda Core is an open-source data quality framework that enables data engineers to write data quality checks using a simple, human-readable YAML-based language called SodaCL (Soda Checks Language). Unlike code-heavy alternatives, Soda is designed to make data quality testing accessible to anyone who understands the data — not just engineers.
Data quality issues are the #1 source of broken dashboards, failed ML models, and lost trust in data. Soda makes it easy to:
# checks for orders table
checks for orders:
# Row count should be positive
- row_count > 0
# No null values in critical columns
- missing_count(order_id) = 0
- missing_count(customer_id) = 0
# Revenue should be positive
- min(revenue) >= 0
# Freshness — data should be recent
- freshness(created_at) < 1d
# Duplicate check
- duplicate_count(order_id) = 0
# Schema validation
- schema:
fail:
when required column missing: [order_id, customer_id, revenue]| Feature | Soda Core | Great Expectations |
|---|---|---|
| Language | YAML (SodaCL) | Python |
| Learning Curve | Low (YAML) | Medium (Python) |
| Setup | Simple CLI | More configuration |
| Non-Engineer Friendly | Yes | Limited |
| Anomaly Detection | Built-in | Via plugins |
| Enterprise Features | Soda Cloud | GX Cloud |
Soda Core pitfalls to watch for:
missing_count(col) = 0 means "zero NULLs," but missing_percent(col) < 5 counts rows differently if you have other missing_values configured. Read the SodaCL reference carefully; the convenient syntax hides some complex defaults.duplicate_count(*) check on a 2-billion-row Snowflake table scans the table. Batch checks, filter with sample or where, or use Snowflake's sample clauses to reduce compute. Watch your Snowflake credit usage after adding Soda.freshness(created_at) < 1d fails silently if created_at is optional or NULL-heavy. Prefer a non-nullable, pipeline-assigned _loaded_at or _ingested_at column for freshness.when forbidden column present: [deprecated_col] is strict; when required column missing: [...] is lax. Combine both for safety, and version your expected schema in git alongside the check.fact.customer_id values exist in dim_customer requires a join at check time. On big facts, this can dominate pipeline runtime. Use sample or check only recent partitions.${VAR} substitution for reusable checks across environments. Nice, but also the most common source of "check didn't run as expected" bugs. Keep templating minimal.Soda Core is an open-source data quality framework that lets you write data quality checks in YAML using SodaCL (Soda Checks Language). You define checks like `row_count > 0`, `missing_count(email) = 0`, or `freshness(created_at) < 1d` and run them via CLI against any supported data source (Snowflake, BigQuery, Redshift, Databricks, Postgres, Spark). The output is pass/fail results you can integrate with alerting, CI/CD, or orchestrators like Airflow and Dagster. It's designed to make data quality accessible to analysts and data stewards, not just Python engineers.
"Better" depends on team profile. Soda is YAML-first, deliberately simpler, accessible to non-engineers — better for SQL-centric teams and organizations where analysts need to define checks. Great Expectations is Python-first, more expressive, and supports Pandas/Spark natively — better for ML pipelines and teams comfortable with Python. Soda's SodaCL covers ~85% of common data-quality patterns in a much simpler syntax; GX covers 100% but requires Python literacy. If your team has analysts defining checks, choose Soda; if your team is all Python engineers, choose GX; if you're hybrid, consider using both.
Yes — Soda Core is 100% free and open-source (Apache 2.0). You can self-host the CLI and run checks locally or in CI/CD at no cost. The commercial product is Soda Cloud, a SaaS with hosted dashboards, alerting, incident management, collaboration features, anomaly detection, and enterprise support. Pricing is tier-based. Many teams run Soda Core alone for a long time; Soda Cloud becomes worth it when you need centralized governance, advanced anomaly detection, or non-engineer dashboards for data-quality status.
Several patterns: (1) run Soda checks as a post-hook after `dbt run` to validate model outputs; (2) run Soda checks in the CI pipeline alongside `dbt build` in GitHub Actions/GitLab CI; (3) use Soda Cloud's dbt integration to monitor dbt models continuously from a central dashboard; (4) for Airflow-orchestrated dbt runs, chain Soda check tasks after dbt tasks. The tools are complementary — dbt tests cover quick schema-level checks (unique, not_null); Soda covers richer checks (distributions, freshness, cross-table references) that dbt tests don't express well.
SodaCL (Soda Checks Language) is the declarative YAML-based language for defining Soda checks. It includes primitives for: basic checks (`row_count`, `missing_count`, `duplicate_count`), aggregations (`min`, `max`, `avg`, `stddev`), text checks (`invalid_count` with regex), freshness (`freshness(col) < 1d`), schema validation, reference/referential-integrity checks, cross-check comparisons, user-defined SQL checks, and anomaly detection. The language is designed to read like English (`missing_count(email) = 0` is immediately understandable) while compiling to efficient SQL under the hood. Full reference at docs.soda.io/soda-cl.
Soda Core supports 20+ data sources including Snowflake, BigQuery, Redshift, Databricks, PostgreSQL, MySQL, SQL Server, Oracle, Athena, Trino/Presto, Apache Spark, Dask, DuckDB, MotherDuck, ClickHouse, and more. File-based checks work via Spark or Dask connectors for Parquet/CSV. Each connector is installed as a separate pip package (`soda-core-snowflake`, `soda-core-bigquery`, etc.) so you only pull what you need. For cloud warehouses, checks compile to native SQL; for Spark/Dask, they use the engine's DataFrame APIs.
Common patterns: (1) CLI in scheduled jobs: `soda scan -d my_warehouse checks.yml` invoked from cron or CI; (2) Airflow: use the `SodaScanOperator` in a DAG to run checks as pipeline tasks; (3) Dagster: Soda has asset-check integration; (4) GitHub Actions / GitLab CI: run `soda scan` on every PR that touches data transformations; (5) Soda Cloud: set up agents that run checks continuously and report to the cloud dashboard. For failures, wire the check output to Slack/PagerDuty either via Soda Cloud's alerting or by parsing exit codes in your orchestrator.