NGL and Condensate Systems

Fractionation cascades, diluent arithmetic, and the Cochin reversal

2026-03-10

Moving a million barrels of Alberta bitumen per day requires almost 430,000 barrels of condensate — imported from the United States through a pipeline that used to flow in the opposite direction.

That single fact contains the entire structure of this essay. Alberta’s oil sands produce bitumen, not crude oil. Bitumen in its natural state cannot be pumped: at reservoir temperature, viscosity can exceed 10,000 centipoise (cP), compared to roughly 5 cP for diluted bitumen at pipeline operating temperature. The solution is blending with a light hydrocarbon diluent — condensate, the C5+ fraction separated out during natural gas processing — to achieve a viscosity and density specification that satisfies the Enbridge pipeline operating envelope. The diluent requirement is large, it must be sourced continuously, and it travels to Alberta through a system that was literally reversed to supply it.

Natural gas liquids and the fractionation cascade

Natural gas liquids (NGL) are the heavier hydrocarbon components — ethane, propane, butanes, and pentane-plus (condensate) — that are dissolved in natural gas at reservoir conditions and extracted during gas processing. When raw gas enters a processing plant, it passes through a series of chilling and separation steps that pull the NGL out of the gas stream as a mixed liquid. That liquid, called NGL mix or Y-grade, is valuable but not yet sellable: it must be separated into individual product streams.

The fractionation cascade is a series of distillation columns that exploit the different boiling points of each NGL component:

Column What it removes Boiling point
Demethanizer Methane (residue gas) −161°C
Deethanizer Ethane (C₂) −89°C
Depropanizer Propane (C₃) −42°C
Debutanizer Butanes (C₄) −12 to −1°C
Residue Condensate / pentane+ (C₅+) +36°C and above

The mass balance through the cascade is simple: what enters equals what leaves, distributed across four product streams.

in = C2 + C3 + C4 + C5+

Symbol Meaning Typical yield (mass fraction)
in NGL mix inlet mass flow rate kg/day
C2 Ethane product stream 0.18–0.22 of inlet
C3 Propane product stream 0.30–0.38 of inlet
C4 Butane product stream 0.18–0.24 of inlet
C5+ Condensate / pentane+ product 0.18–0.25 of inlet

Fort Saskatchewan, AB is the largest NGL fractionation hub in Canada. Three major facility clusters — operated by Pembina, Keyera, and their joint venture partners — process combined inlet volumes of 350,000+ bbl/day of NGL mix. The products move outward by pipeline and rail: ethane to petrochemical facilities (Nova Chemicals’ Joffre complex, less than 100 km south); propane to export and heating fuel markets; butane to blending and export; condensate southward and westward as diluent for the oil sands.

Facility Operator NGL inlet capacity (bbl/day)
Redwater Fractionator Pembina ~110,000
Keyera Fort Saskatchewan Keyera ~90,000
Other hub facilities Various distributed
Total hub capacity ~350,000+

Sources: Company investor presentations; AER production data.

The diluent problem — and the Cochin reversal

Oil sands bitumen has an API gravity of roughly 8–10° and viscosity at reservoir temperature that far exceeds pipeline specification. Enbridge Mainline acceptance standards require a minimum of ~19° API and viscosity below approximately 350 cSt at operating temperature. Raw bitumen meets neither requirement.

The solution is dilbit — diluted bitumen, blended with enough condensate (C5+ fraction) to bring the mixture within specification. The blend ratio is governed by a simple volumetric mass balance:

V\_{\text{dilbit}} = \frac{V\_{\text{bitumen}}}{x\_{\text{bitumen}}} \qquad V\_{\text{diluent}} = V\_{\text{dilbit}} \cdot (1 - x\_{\text{bitumen}})

Symbol Meaning Units / range
Vbitumen Volume of bitumen to be moved m³ or bbl
xbitumen Bitumen volume fraction in dilbit blend dimensionless — typically 0.65–0.75
Vdilbit Total diluted bitumen volume m³ or bbl
Vdiluent Diluent (condensate) volume required m³ or bbl

At xbitumen = 0.70 (the industry standard, consistent with Enbridge specifications), a 1,000-barrel shipment of bitumen requires 286 barrels of condensate and occupies 1,286 barrels of pipeline capacity as dilbit. At provincial bitumen production of approximately 1 million bbl/day, the diluent requirement is:

V\_{\text{diluent}} = 1{,}000{,}000 \times \frac{0.30}{0.70} \approx 429{,}000 \text{ bbl/day}

That 429,000 bbl/day of condensate must come from somewhere. Alberta does not produce enough to meet its own demand. The shortfall is supplied largely by imported U.S. condensate — and this is where the geography becomes unusual.

The Cochin pipeline (Kerrobert, SK to Kankakee, IL) was originally built in 1978 to move propane westward from Saskatchewan. In 2015, Kinder Morgan Canada (now Pembina, following its 2019 acquisition) reversed the flow direction: Cochin now moves condensate eastward from North Dakota Bakken production into Alberta, delivering approximately 95,000 bbl/day of diluent to the Fort Saskatchewan hub. The reversal was an infrastructure response to the scale of bitumen production — when the oil sands ramp up, diluent demand rises, and the condensate market responds by rerouting supply.

Cochin pipeline (post-reversal): - Operator: Pembina Pipeline - Direction: Kankakee, IL → Kerrobert, SK → Fort Saskatchewan, AB - Product: condensate (C5+) - Capacity: ~95,000 bbl/day - Purpose: diluent supply for oil sands bitumen blending

Cochin covers roughly 22% of diluent demand at 1 million bbl/day bitumen production. The remainder is supplied by local condensate production from NGL fractionation (the C5+ fraction from Fort Saskatchewan’s own output) and rail imports. The diluent supply chain is a structural feature of the Alberta energy economy — not a temporary workaround, but a permanent logistical requirement built into every barrel of dilbit shipped on the Mainline.

Fractionation mass balance — worked example

Consider Pembina’s Redwater Fractionator at 110,000 bbl/day NGL inlet capacity, using a representative Alberta NGL mix yield:

Product Yield (mass fraction)
Ethane (C₂) 0.20
Propane (C₃) 0.34
Butane (C₄) 0.21
Condensate (C₅+) 0.25

With mixed NGL density approximately 580 kg/m³ (≈ 0.092 tonnes/bbl):

The condensate stream — 27,500 bbl/day from this one fractionator — flows directly into the diluent supply chain. Across the full Fort Saskatchewan hub (350,000+ bbl/day NGL inlet), the C₅+ output contributes roughly 90,000 bbl/day of diluent, almost matching Cochin’s import volume on its own.

Note the ethane disposition decision: ethane can be left in the gas stream (“ethane rejection” mode, where it contributes heating value to gas sales) or extracted for petrochemical feedstock (“ethane extraction” mode). This is purely an economic decision driven by the ethane contract price relative to the AECO gas price. When ethane prices are high relative to gas, fractionators extract; when gas prices are high, they reject. The yield fractions shown above assume extraction mode.

Reference implementation

import numpy as np

def dilbit_volumes(bitumen_bbl: float, bitumen_fraction: float = 0.70) -> dict:
    """
    Calculate diluent requirement and total dilbit volume for a bitumen shipment.

    Parameters
    ----------
    bitumen_bbl      : volume of bitumen to transport (bbl)
    bitumen_fraction : target bitumen fraction in the dilbit blend (dimensionless)
                       Industry standard: 0.65–0.75. Enbridge spec: ~0.71

    Returns
    -------
    dict with keys: dilbit_bbl, diluent_bbl, diluent_pct, diluent_per_bitumen
    """
    dilbit_bbl  = bitumen_bbl / bitumen_fraction          # bbl
    diluent_bbl = dilbit_bbl * (1 - bitumen_fraction)     # bbl

    return {
        "bitumen_bbl":         bitumen_bbl,
        "dilbit_bbl":          dilbit_bbl,
        "diluent_bbl":         diluent_bbl,
        "diluent_pct":         (1 - bitumen_fraction) * 100,
        "diluent_per_bitumen": diluent_bbl / bitumen_bbl,   # ratio
    }


def fractionation_mass_balance(inlet_tonnes_day: float,
                               yields: dict = None) -> dict:
    """
    Mass balance through a simple NGL fractionation cascade.

    Parameters
    ----------
    inlet_tonnes_day : total NGL inlet mass flow (tonnes/day)
    yields           : mass fractions for each product stream
                       default: representative Alberta NGL mix

    Returns
    -------
    dict mapping product name → tonnes/day
    """
    if yields is None:
        yields = {
            "ethane (C2)":      0.20,   # ethane-rich — Pembina spec
            "propane (C3)":     0.34,
            "butane (C4)":      0.21,   # mixed butanes
            "condensate (C5+)": 0.25,   # pentane+ / natural gasoline
        }

    total_yield = sum(yields.values())
    if not np.isclose(total_yield, 1.0, atol=0.001):
        raise ValueError(f"Yields sum to {total_yield:.4f}, not 1.0 — check inputs")

    return {product: inlet_tonnes_day * frac for product, frac in yields.items()}


# ── Reference values — Fort Saskatchewan fractionation hub ────────────────
NGL_DENSITY_T_PER_BBL = 0.092   # tonnes/bbl (mixed NGL)
inlet_bbl_day  = 110_000         # bbl/day — representative Fort Saskatchewan unit
inlet_t_day    = inlet_bbl_day * NGL_DENSITY_T_PER_BBL

products_t_day = fractionation_mass_balance(inlet_t_day)

print("Fractionation mass balance — 110,000 bbl/day NGL inlet")
print(f"{'Inlet (NGL mix)':<25}: {inlet_t_day:>10,.0f} t/day")
print()
for product, mass in products_t_day.items():
    bbl = mass / NGL_DENSITY_T_PER_BBL
    print(f"  {product:<23}: {mass:>10,.0f} t/day  ({bbl:>8,.0f} bbl/day)")

print()

# Dilbit blending — Athabasca bitumen shipment
bitumen_production_bbl = 1_000_000   # bbl/day — approximate AB oil sands output
result = dilbit_volumes(bitumen_production_bbl, bitumen_fraction=0.70)

print("Dilbit blending — 1 million bbl/day bitumen production")
print(f"  Bitumen volume   : {result['bitumen_bbl']:>12,.0f} bbl/day")
print(f"  Dilbit volume    : {result['dilbit_bbl']:>12,.0f} bbl/day  ({result['diluent_pct']:.0f}% diluent)")
print(f"  Diluent required : {result['diluent_bbl']:>12,.0f} bbl/day")
print(f"  Diluent ratio    : {result['diluent_per_bitumen']:.3f} bbl diluent per bbl bitumen")
print()
print("The Cochin pipeline (reversed 2015): 95,000 bbl/day condensate capacity")
print(f"  Cochin covers {95_000 / result['diluent_bbl'] * 100:.1f}% of diluent demand for this bitumen volume")

Output:

Fractionation mass balance — 110,000 bbl/day NGL inlet
Inlet (NGL mix)          :     10,120 t/day

  ethane (C2)             :      2,024 t/day  (  22,000 bbl/day)
  propane (C3)            :      3,441 t/day  (  37,402 bbl/day)
  butane (C4)             :      2,125 t/day  (  23,087 bbl/day)
  condensate (C5+)        :      2,530 t/day  (  27,500 bbl/day)

Dilbit blending — 1 million bbl/day bitumen production
  Bitumen volume   :    1,000,000 bbl/day
  Dilbit volume    :    1,428,571 bbl/day  (30% diluent)
  Diluent required :      428,571 bbl/day
  Diluent ratio    :      0.429 bbl diluent per bbl bitumen

The Cochin pipeline (reversed 2015): 95,000 bbl/day condensate capacity
  Cochin covers 22.2% of diluent demand for this bitumen volume

Run it yourself

The cell below focuses on the diluent economics. The condensate cost is a significant fraction of bitumen revenue — typically 20–40% at current price levels. Tighten the blend ratio (lower xbitumen) and diluent demand rises; relax it and demand falls, but the blend no longer meets pipeline specification below about 0.65. Notice also the sensitivity table: every 0.02 change in xbitumen shifts diluent demand by tens of thousands of barrels per day at the provincial scale.

import numpy as np

# ── Parameters — change these and hit Run ──────────────────────────────────
bitumen_bbl_day  = 1_000_000   # bitumen production to transport (bbl/day) — try: 500_000–1_500_000
bitumen_fraction = 0.70        # bitumen content in dilbit (dimensionless) — range: 0.65–0.75
                               # lower fraction = more diluent needed = more pipeline volume
condensate_price = 75.0        # condensate (diluent) price (USD/bbl) — try: 55–95
bitumen_price    = 55.0        # bitumen price at mine (USD/bbl) — try: 40–70

# ── Dilbit mass balance ────────────────────────────────────────────────────
dilbit_bbl   = bitumen_bbl_day / bitumen_fraction
diluent_bbl  = dilbit_bbl * (1 - bitumen_fraction)

# ── Diluent cost as fraction of revenue ───────────────────────────────────
bitumen_revenue   = bitumen_bbl_day * bitumen_price
diluent_cost      = diluent_bbl * condensate_price
diluent_cost_pct  = diluent_cost / bitumen_revenue * 100

# ── Output ─────────────────────────────────────────────────────────────────
print(f"Bitumen volume       : {bitumen_bbl_day:>12,.0f} bbl/day")
print(f"Dilbit volume        : {dilbit_bbl:>12,.0f} bbl/day  (+{(dilbit_bbl/bitumen_bbl_day - 1)*100:.1f}% pipeline volume)")
print(f"Diluent required     : {diluent_bbl:>12,.0f} bbl/day  ({(1-bitumen_fraction)*100:.0f}% of dilbit)")
print()
print(f"Bitumen revenue      : ${bitumen_revenue:>14,.0f}/day")
print(f"Diluent cost         : ${diluent_cost:>14,.0f}/day  ({diluent_cost_pct:.1f}% of bitumen revenue)")
print()
print("Sensitivity to blend ratio:")
for frac in np.arange(0.65, 0.76, 0.02):
    dil = (bitumen_bbl_day / frac) * (1 - frac)
    print(f"  x_bitumen={frac:.2f}  diluent={dil:>10,.0f} bbl/day")

Where next?

The NGL and condensate system operates in liquid phase — dense, incompressible, amenable to the same Darcy-Weisbach hydraulics as crude oil. Natural gas presents a fundamentally different challenge: compressible flow, where pressure, temperature, and volume interact through the gas equation of state, and the governing equation is the Weymouth formula.

Cluster P — Pipeline Connectivity · Essay 2 of 5 · Difficulty: 2