Skip to content

Channels — one pipeline, many tenants

The question for this lesson: you have one customer_etl pipeline, and several customers (tenants) want the same logic with one number changed. Acme Corp only calls someone “gold” at a much higher lifetime value than everyone else. Do you copy the whole pipeline and edit a line for each tenant? No. You keep one pipeline and add a small channel overlay per tenant.

  • Read a channel overlay and say what it overrides, and what it can’t.
  • Override a pipeline’s declared variable for one deployment, without touching its logic.
  • Apply a channel at run time with --channel.

A channel is a small overlay file that sits on top of a base pipeline and changes its declared variables and config knobs for one deployment, never its nodes, never its CXL. One customer_etl.yaml, many tenants.

It works in two halves. First, the base pipeline declares a variable with a default:

pipeline:
name: customer_etl
vars:
gold_threshold: { type: int, default: 10000 } # the lifetime-value cut for "gold"

and reads it in a CXL expression with $vars:

emit tier = if lifetime_value.to_int() > $vars.gold_threshold then "gold" else "standard"
🌱 New here? — $vars

$vars.gold_threshold reads the value of the gold_threshold variable declared at the top of the pipeline. Declaring a number once, by name, instead of hardcoding 10000 inside the expression, is exactly what lets a channel change it later without editing the logic.

Then a channel overlay supplies a different value for one tenant:

channels/acme-corp/customer_etl.channel.yaml
channel:
name: acme-corp
target: ./customer_etl.yaml # the base pipeline this overlays
vars:
static:
gold_threshold:
type: int
default: 50000 # Acme's higher bar for "gold"

and you apply it at run time with --channel:

clinker run customer_etl.yaml --channel channels/acme-corp/customer_etl.channel.yaml

Same nodes, same CXL, same everything: only gold_threshold changes, and only for Acme. A channel can override declared vars: and config: knobs; it can not add or rewire nodes, or change an expression. If two tenants need different logic, that’s a different pipeline, not a channel.

First, the base on its own, with no channel, so gold_threshold is its declared default, 10000. Predict each customer’s tier, then run.

pipeline.yaml // editable

Only the 80000 customer clears 10000, so only they are gold.

Acme’s channel sets gold_threshold to 50000. The pipeline is identical; only that one number changes.

Now write your own. Bright Start is a tenant that rewards smaller customers: anyone over 3000 lifetime value should count as gold. Write its channel file.

// quick check

What does Acme's channel actually change in the pipeline?