Fluid Forge
Why Forge
Concepts
Get Started
  • Consume a Data Product
  • See it run
  • Demos
  • Local (DuckDB)
  • Source-Aligned (Postgres → DuckDB)
  • AI Forge + Data Models
  • MCP Output Port — Serve to AI Agents
  • GCP (BigQuery)
  • Snowflake Team Collaboration
  • Declarative Airflow
  • Orchestration Export
  • Jenkins CI/CD
  • Universal Pipeline
  • 11-Stage Production Pipeline
  • Catalog Forge End-to-End
CLI Reference
  • Agent Policy (concept)
  • MCP Output Port — Serve to Agents
  • MCP deep-dive
  • AI-assisted authoring
  • LLM providers & backends
  • Overview
  • Quickstart
  • Examples
  • Your own CI
  • Your own scaffolding
  • Custom validator
  • Apply hook
  • Reference
  • Overview
  • Architecture
  • GCP (BigQuery)
  • AWS (S3 + Athena)
  • Snowflake
  • Local (DuckDB)
  • Custom Providers
  • Roadmap
GitHub
Why Forge
Concepts
Get Started
  • Consume a Data Product
  • See it run
  • Demos
  • Local (DuckDB)
  • Source-Aligned (Postgres → DuckDB)
  • AI Forge + Data Models
  • MCP Output Port — Serve to AI Agents
  • GCP (BigQuery)
  • Snowflake Team Collaboration
  • Declarative Airflow
  • Orchestration Export
  • Jenkins CI/CD
  • Universal Pipeline
  • 11-Stage Production Pipeline
  • Catalog Forge End-to-End
CLI Reference
  • Agent Policy (concept)
  • MCP Output Port — Serve to Agents
  • MCP deep-dive
  • AI-assisted authoring
  • LLM providers & backends
  • Overview
  • Quickstart
  • Examples
  • Your own CI
  • Your own scaffolding
  • Custom validator
  • Apply hook
  • Reference
  • Overview
  • Architecture
  • GCP (BigQuery)
  • AWS (S3 + Athena)
  • Snowflake
  • Local (DuckDB)
  • Custom Providers
  • Roadmap
GitHub
  • Introduction

    • Home
    • Why Fluid Forge
    • Getting Started
    • Snowflake Quickstart
    • See it run
    • Forge Data Model
    • Vision & Roadmap
    • Playground
    • FAQ
  • Concepts

    • Concepts
    • Builds, Exposes, Bindings
    • What is a contract?
    • Quality, SLAs & Lineage
    • Governance & Policy
    • Agent Policy (LLM/AI governance)
    • Providers vs Platforms
    • Fluid Forge vs alternatives
  • Data Products

    • Consume a Data Product
    • Product Types — SDP, ADP, CDP
  • Walkthroughs

    • Walkthrough: Local Development
    • Source-Aligned: Postgres → DuckDB → Parquet
    • AI Forge And Data-Model Journeys
    • Walkthrough: MCP Output Port
    • Walkthrough: Deploy to Google Cloud Platform
    • Walkthrough: Snowflake Team Collaboration
    • Declarative Airflow DAG Generation - The FLUID Way
    • Generating Orchestration Code from Contracts
    • Jenkins CI/CD for FLUID Data Products
    • Universal Pipeline
    • The 11-Stage Pipeline
    • End-to-End Walkthrough: Catalog → Contract → Transformation
  • CLI Reference

    • CLI Reference
    • Core workflow

      • fluid init
      • fluid demo
      • fluid forge
      • fluid validate
      • fluid plan
      • fluid apply
      • fluid diff
      • fluid status
    • Build & ship

      • fluid bundle
      • fluid generate
      • fluid generate artifacts
      • fluid validate-artifacts
      • fluid verify-signature
      • fluid generate iac
      • fluid generate-airflow
      • fluid generate-pipeline
      • fluid viz-graph
      • fluid publish
      • fluid ship
      • fluid rollback
      • fluid schedule-sync
    • AI & Agents

      • fluid ai
      • fluid agents
      • fluid mcp
      • fluid memory
      • fluid stats
      • fluid skills
    • Quality & governance

      • fluid test
      • fluid verify
      • fluid contract-tests
      • fluid contract-validation
      • fluid policy
      • fluid policy check
      • fluid policy compile
      • fluid policy apply
    • Standards & interoperability

      • fluid odps
      • fluid odps-bitol
      • fluid odcs
      • fluid export
      • fluid export-odps
      • fluid exporters
      • fluid import
      • fluid market
      • fluid datamesh-manager
    • Project & workspace

      • fluid product-new
      • fluid product-add
      • fluid workspace
      • fluid contract
      • fluid split
      • fluid config
      • fluid providers
      • fluid plugins
      • fluid provider-init
      • fluid auth
      • fluid secrets
      • fluid ide
      • fluid scaffold-ci
      • fluid scaffold-composer
      • fluid scaffold-ide
      • fluid docs
      • fluid runs
      • fluid retention
      • fluid describe
      • fluid doctor
      • fluid roadmap
      • fluid version
    • Catalog adapters

      • Source Catalog Integration (V1.5)
      • Publishing to a Catalog — Overview
      • BigQuery Catalog
      • Snowflake Horizon Catalog
      • Databricks Unity Catalog
      • Google Dataplex Catalog
      • AWS Glue Data Catalog
      • DataHub Catalog
      • Data Mesh Manager Catalog
      • OpenMetadata Catalog
    • CLI by task

      • CLI by task
      • Add quality rules
      • Add agent governance
      • Debug a failed pipeline run
      • Switch clouds with one line
  • Recipes

    • Recipes
    • Recipe — add a quality rule
    • Recipe — switch clouds with one line
    • Recipe — tag PII in your schema
    • Write a contract that consumes another contract
    • Generate per-environment overlays
  • SDK & Plugins

    • SDK & Plugins
    • Quickstart — your first plugin
    • Examples

      • Runnable examples
      • Example: hello-scaffold — the minimal viable plugin
      • Example: gitlab-ci-scaffold — generate a complete CI project
      • Example: steward-validator — a custom governance rule
      • Example: prod-key-guard — apply-time invariant check
    • Journeys

      • Journeys
      • Your own CI/CD

        • You have your own CI/CD setup, no problem
        • GitLab CI — the bundle template
        • GitHub Actions — the bundle template
        • Jenkins — the bundle template
        • CircleCI — the bundle template
      • You have a strict project layout, no problem
      • You have governance rules, no problem
      • You want a check at apply time, no problem
    • Reference

      • Reference
      • Roles reference
      • Entry points reference
      • Trust model
      • Packaging
      • Companion packages
  • Providers

    • Providers
    • Provider Architecture
    • GCP Provider
    • AWS Provider
    • Snowflake Provider
    • Local Provider
    • Creating Custom Providers
    • Provider Roadmap
  • AI & Agents

    • MCP Server
    • Built-in And Custom Forge Guidance
    • Forge Discovery Guide
    • Forge Memory Guide
    • Authoring Forge Tools
    • Guided fluid forge UX
    • LLM Providers
    • LiteLLM Backend
    • Capability Warnings
    • Cost Tracking
    • FLUID Forge Contract GPT Packet
    • Agentic Primitives
  • Operate & Deploy

    • Airflow Integration
    • Blueprints
    • Source-Aligned Acquisition
  • Govern & Secure

    • Governance, Compliance & the Business Case
    • Governance & Compliance
    • Network Safety
    • Credential Resolver — Security Model
  • Configuration & Reference

    • Environment Variables
    • Typed Errors
    • Typed CLI Errors
    • API Stability — fluid_build.api
  • Architecture & Releases

    • V1.5 Catalog Integration — Architecture Deep-Dive
    • V1.5 + V2 Hardening — Release Notes
  • Project

    • Contributing to Fluid Forge
    • Fluid Forge Docs Baseline: CLI 0.9.0
    • Fluid Forge Docs Baseline: CLI 0.8.11
    • Fluid Forge Docs Baseline: CLI 0.8.10
    • Fluid Forge Docs Baseline: CLI 0.8.9
    • Fluid Forge Docs Baseline: CLI 0.8.8
    • Fluid Forge Docs Baseline: CLI 0.8.7
    • Fluid Forge Docs Baseline: CLI 0.8.6
    • Fluid Forge Docs Baseline: CLI 0.8.5
    • Fluid Forge Docs Baseline: CLI 0.8.4
    • Fluid Forge Docs Baseline: CLI 0.8.3
    • Fluid Forge Docs Baseline: CLI 0.8.0
    • Fluid Forge Docs Baseline: CLI 0.7.11
    • Fluid Forge Docs Baseline: CLI 0.7.9
    • Fluid Forge v0.7.1 - Multi-Provider Export Release

Local Provider

Status: ✅ Production Ready
Docs Baseline: CLI 0.10.0
Database: DuckDB, SQLite

Why it matters Build and test a real data product on your laptop — no cloud account, no credentials — then ship the same contract to a cloud. binding.platform: local runs embedded on DuckDB; only that one line changes when you later target BigQuery, Snowflake, or Athena.


Overview

The Local provider enables rapid development and testing without cloud costs. Perfect for:

  • 📚 Learning Fluid Forge
  • 🧪 Testing contracts before cloud deployment
  • 💻 Local data analysis with DuckDB
  • 🔬 CI/CD testing pipelines

Quick Start

Installation

pip install data-product-forge duckdb

Minimal Contract

fluidVersion: "0.7.3"
kind: DataProduct
id: example.local_analytics_v1
name: Local Analytics
domain: example

metadata:
  layer: Bronze
  owner:
    team: data-analytics
    email: team@example.com

builds:
  - id: build_customers
    pattern: embedded-logic
    engine: sql
    properties:
      sql: |
        SELECT * FROM read_csv_auto('./data/customers.csv')
    outputs:
      - customers

exposes:
  - exposeId: customers
    kind: table
    binding:
      platform: local
      format: parquet
      location:
        path: ./runtime/out/customers.parquet
    contract:
      schema:
        - name: customer_id
          type: STRING
          required: true

Execute:

fluid apply contract.fluid.yaml --provider local

Supported Features

✅ DuckDB Features

FeatureSupportNotes
Tables✅ FullCREATE TABLE, materialized
Views✅ FullStandard SQL views
CSV/Parquet Loading✅ FullAuto-schema detection
SQL Transformations✅ FullFull SQL:2016 support
Indexes✅ FullB-tree, ART indexes
CTEs & Window Functions✅ FullAdvanced SQL
JSON/Arrays✅ FullNested data structures

⏳ Limitations

  • ❌ No IAM/authentication (local only)
  • ❌ No partitioning (not needed for small data)
  • ❌ No distributed queries
  • ⚠️ Limited to single machine memory

Configuration

The local provider needs no contract-level configuration block. It is selected at the command line with --provider local, and DuckDB itself is managed for you (an in-memory database during a run, or a session-scoped file so tables created by one build are visible to the next).

What you do configure per output is the binding on each expose — the format and the path the local provider writes to:

exposes:
  - exposeId: customers
    kind: table
    binding:
      platform: local
      format: parquet            # or csv
      location:
        path: ./runtime/out/customers.parquet
    contract:
      schema:
        - name: customer_id
          type: STRING
          required: true

Use Cases

1. Development & Testing

Develop contracts locally, then deploy to cloud:

# Test locally
fluid apply contract.yaml --provider local

# Deploy to GCP when ready
fluid apply contract.yaml --provider gcp --project my-project

2. Data Analysis

Analyze local CSV/Parquet files. Source files are read directly inside the build SQL with DuckDB's read_csv_auto / read_parquet functions:

builds:
  - id: build_monthly_revenue
    pattern: embedded-logic
    engine: sql
    properties:
      sql: |
        SELECT
          DATE_TRUNC('month', sale_date) as month,
          SUM(amount) as revenue
        FROM read_csv_auto('./data/sales_*.csv')
        GROUP BY month
    outputs:
      - monthly_revenue

exposes:
  - exposeId: monthly_revenue
    kind: view
    binding:
      platform: local
      format: parquet
      location:
        path: ./runtime/out/monthly_revenue.parquet
    contract:
      schema:
        - name: month
          type: TIMESTAMP
        - name: revenue
          type: NUMERIC

3. CI/CD Testing

Test contracts in GitHub Actions:

# .github/workflows/test.yml
- name: Test Fluid Contract
  run: |
    fluid apply contract.yaml --provider local
    fluid verify contract.yaml --provider local

Performance Tips

1. Use Parquet Instead of CSV

Read Parquet rather than CSV in your build SQL — it is typically ~10x faster and carries its own schema:

builds:
  - id: build_events
    pattern: embedded-logic
    engine: sql
    properties:
      sql: |
        SELECT * FROM read_parquet('./data/events.parquet')
    outputs:
      - events

Pick format: parquet on the expose binding too, so outputs are written in the faster format.

2. Push Work Into SQL

DuckDB is a columnar engine — filter and aggregate inside the build SQL rather than post-processing. Project only the columns you need and let WHERE / GROUP BY run in the engine.

3. Optimize Memory

DuckDB memory and thread settings are managed by the local provider, not declared in the contract. For large datasets, prefer Parquet inputs and narrow projections so less data is held in memory at once.


Example Workflows

Load and Transform CSVs

fluidVersion: "0.7.3"
kind: DataProduct
id: example.csv_pipeline_v1
name: CSV Pipeline
domain: example

metadata:
  layer: Silver
  owner:
    team: data-analytics
    email: team@example.com

builds:
  - id: build_customer_orders
    pattern: embedded-logic
    engine: sql
    properties:
      sql: |
        SELECT
          c.customer_id,
          c.name,
          c.email,
          COUNT(o.order_id) as total_orders,
          SUM(o.amount) as total_spent
        FROM read_csv_auto('./raw/customers.csv') c
        LEFT JOIN read_csv_auto('./raw/orders.csv') o
          ON c.customer_id = o.customer_id
        GROUP BY c.customer_id, c.name, c.email
    outputs:
      - customer_orders

exposes:
  - exposeId: customer_orders
    kind: table
    binding:
      platform: local
      format: parquet
      location:
        path: ./runtime/out/customer_orders.parquet
    contract:
      schema:
        - name: customer_id
          type: STRING
          required: true
        - name: name
          type: STRING
        - name: email
          type: STRING
          sensitivity: pii
        - name: total_orders
          type: INTEGER
        - name: total_spent
          type: NUMERIC

Parquet Data Lake

fluidVersion: "0.7.3"
kind: DataProduct
id: example.data_lake_v1
name: Data Lake Events
domain: example

metadata:
  layer: Silver
  owner:
    team: data-analytics
    email: team@example.com

builds:
  - id: build_daily_events
    pattern: embedded-logic
    engine: sql
    properties:
      sql: |
        SELECT
          DATE(event_time) as date,
          event_type,
          COUNT(*) as event_count
        FROM read_parquet('./lake/events/**/*.parquet')   -- wildcard glob
        WHERE event_time >= CURRENT_DATE - INTERVAL '7 days'
        GROUP BY date, event_type
    outputs:
      - daily_events

exposes:
  - exposeId: daily_events
    kind: view
    binding:
      platform: local
      format: parquet
      location:
        path: ./runtime/out/daily_events.parquet
    contract:
      schema:
        - name: date
          type: DATE
        - name: event_type
          type: STRING
        - name: event_count
          type: INTEGER

Querying Results

Python

import duckdb

conn = duckdb.connect('analytics.duckdb')

# Query data
df = conn.execute("""
    SELECT * FROM main.customers
    WHERE total_spent > 1000
""").fetchdf()

print(df.head())
conn.close()

DuckDB CLI

duckdb analytics.duckdb

-- Interactive SQL
SELECT * FROM main.customers LIMIT 10;

-- Export to CSV
COPY (SELECT * FROM main.customer_summary) 
TO 'export.csv' WITH (HEADER, DELIMITER ',');

-- Export to Parquet
COPY main.customer_summary TO 'export.parquet';

Cloud Migration

When ready to move to production:

1. Update the expose binding:

exposes:
  - exposeId: customer_orders
    kind: table
    binding:
      platform: gcp                 # Changed from 'local'
      format: bigquery_table        # Changed from 'parquet'
      location:
        project: my-project-id
        dataset: analytics
        table: customer_orders
    # contract.schema, builds, governance — all unchanged

2. Deploy:

fluid apply contract.fluid.yaml --provider gcp

That's it! Your local development becomes cloud production.


Next Steps

  • Local Walkthrough - Complete tutorial
  • GCP Walkthrough - Migrate to cloud
  • CLI Reference - Local provider commands

Perfect for development. Deploy to GCP when ready.

Edit this page on GitHub
Last Updated: 6/27/26, 4:58 PM
Contributors: Jeff Watson, jeffwatson-ai, fas89, Claude Opus 4.7 (1M context)
Prev
Snowflake Provider
Next
Creating Custom Providers