SteelheadTracker

Columbia Basin Steelhead Migration Dashboard
Loading...
Data: DART, PTAGIS, FPC, USGS
Read more: Detector networks ↗ Field notes ↗ How accurate is this? ↗ Tracer fish ↗ Q&A ↗

Pick your river

Every major drainage has its own page: this season's timing against past years, how fast its fish actually travel, season totals, and where the run stands right now.
Loading rivers...

Where each run is in the system

One bar per river: how far a typical run has moved by this date, from the ocean side of Bonneville to detections in the river itself. Timing is the median of 2012–2026 (what a normal year looks like today); the projection and rank are this season's. Rivers sorted by how much of the run is in or near the river.
Position is typical timing, not a live count: a fast or slow year shifts these bars by a few weeks. The projection column is this year's estimate.
Loading chart...

Streamflow & Fish Detections Live

USGS observed streamflow (last 30 days) with daily PIT fish entries. Shows flow conditions at key gauges alongside fish arrival patterns. Dual y-axis: discharge (cfs) on left, fish detections on right.

Select a river and click "Load Flow Data" to fetch live streamflow

Data from USGS National Water Information System (waterservices.usgs.gov)

Power tool: drive any dashboard chart to one river
River focus:
Every major river also has its own page (and the Cowlitz, below Bonneville, has one built on hand counts): browse river pages →
Buttons jump to the full chart; the panels below render here, pre-set to your river: same JSONs, one source. Entry-gate heatmap and streamflow keep their own pickers.

Daily Passage: Bonneville Dam Live

Day-of-year overlay across all years. Toggle between raw counts, 7-day, and 14-day averages.
Loading chart...

Daily Passage: Lower Granite Dam Live

Last dam on the Snake River before fish enter tributaries. Key indicator for Clearwater, Salmon, and Grande Ronde runs.
Loading chart...

Annual Run Size by Dam

Total steelhead passage at each major Columbia & Snake River dam, 2010–present.
Loading chart...

Daily Passage by Destination River New

Expanded PIT×DART estimates of daily steelhead passage at each dam, broken down by destination river basin. Select a year and toggle rivers on/off.
Loading chart...
How these bars are calculated. Each day, the dam window counts every steelhead that passes. That is a physical census. Separately, some of those fish carry PIT tags whose later detections tell us which river they ended up in. The day's census is split between rivers in proportion to that day's resolved tags: river's fish = (river's tags that day ÷ all resolved tags that day) × the day's dam count. Hover any bar to see its share. The census is exact; the split is an estimate, and days with few tags carry wide uncertainty; early-season days especially. Fish whose tags never resolve to a river are not shown here.
Season insight, updated on the data date
This year's early-returning "A-run" (one-salt) steelhead have largely not shown up. PIT-tagged smolts from the last outmigration are returning at roughly a fraction of last year's same-date pace (worth knowing: last summer was an unusually strong one-salt year, so against two summers ago this year sits at a fraction). The drop is across every origin we track, though not evenly: wild one-salts are at a fraction of last year and hatchery at a fraction, which points to ocean survival rather than a data artifact. Our own smolt-to-adult proxy says the same: few one-salt returns per 1,000 smolt tags so far, against more last year. One-salts are few% of aged returns so far against more% last year. It explains why the overall Bonneville count so far this year sits among the lowest of the last 17 years at this same date, a year-to-date standing, not a final result. The live standing is in the card titled What the data says, which updates with the count. Where the season finishes depends on the fall run still to come; the forecast card is our estimate of that, and it will move as September and October land. The two-salt fish returning now went to sea a year earlier and are at most of last year's pace. See Fish Biology → Ocean Age for the breakdown, and the run-timing forecast wedge for where the season may land.

This season, river by river

The run under way, sorted by projected finish: solid is the estimate so far at Bonneville, cross-hatched in the same colour is the projected rest of the season, from the same forecast each river page quotes. Rivers with no hatched part have no projection yet. Click a bar for its river page.
Loading chart...

Where the run is going, every year since 2012

The whole model in one picture: estimated destinations, river by river, every migration year since 2012; the current season builds at the right edge. The record starts at 2012 because that is where the PIT evidence gets thick enough to name rivers: MY2012 has about one tag per 50 fish, while 2008 has one per 6,600. Click a band to open its river page; sixteen rivers have one.
Reading the two views: the Bonneville and Granite views count the same fish at two dams. A river's Bonneville number is always larger than its Granite number because two or three in ten Snake-bound fish never complete the climb, a share measured from each river’s own tags. Snake river pages count at Bonneville all season and show beside the finish the share expected to reach Granite. And the current-season bar counts from June 1, while the season curve below counts from January 1 and projects to December 31, so its running total and projected finish will both read higher than this bar. Same run, different clocks.
Loading chart...
Pick your river →
Timing, travel speed and current status for 16 drainages

The season behind every river

This year's run against every year since 2010 at Bonneville. The shaded wedge is where the season lands if it keeps running like its three most similar years. Full detail on the Run Timing tab.
Loading chart...

Cumulative Run Timing: Bonneville

This year's pace against every year since 2010. The shaded wedge is where the season lands if it keeps running like its three most similar years.
Loading chart...
How this chart is estimated. The dam view is a pure census: every steelhead counted at the window, no modelling. The per-river views scale that census: each river's season total comes from the same estimate as the Destinations tab (PIT tags × published tagging rates, one shared source), and the census's daily shape spreads it across the year. The forecast wedge assumes this season keeps behaving like its three most similar past years, an assumption that works because the split of the run between rivers stays relatively stable from year to year at Bonneville; when it breaks (like this year's missing one-salts), the wedge widens or misses, and that miss is itself information.

Cumulative Run Timing: Lower Granite

Snake River cumulative timing. Fish arrive later here than at Bonneville. Same wedge logic, matched on Granite's own curve.
Loading chart...
How this chart is estimated. The dam view is a pure census: every steelhead counted at the window, no modelling. The per-river views scale that census: each river's season total comes from the same estimate as the Destinations tab (PIT tags × published tagging rates, one shared source), and the census's daily shape spreads it across the year. The forecast wedge assumes this season keeps behaving like its three most similar past years, an assumption that works because the split of the run between rivers stays relatively stable from year to year at Bonneville; when it breaks (like this year's missing one-salts), the wedge widens or misses, and that miss is itself information.

Run Timing by River New

How these fish numbers are built, in three steps: (1) DART counts every steelhead passing Bonneville each day, a census with no modelling. (2) PIT-tagged fish detected at each river's entry arrays give that river's share of the run. (3) The daily dam count is multiplied by that share, so the curve height is real fish and the split between rivers is the estimate. What this cannot tell you: rivers entered through tributary arrays rather than a mainstem site are detected less often, so their share is understated; the Clearwater is seen at its own gate only about 38% of the time. Rivers below 0.5% of the run are omitted unless they are major drainages. Use the dropdown to isolate one river.
Loading chart...

Basin Destination by Year New

Estimated adult steelhead by destination river. In completed years a Clearwater or Salmon hatchery fish is assigned the basin it was released into, Idaho's wild fish follow Idaho Fish and Game's published split, and every other river's fish are placed by where they were seen again upstream; the rivers then scale to the DART dam count, with the Snake block held to the share the Lower Granite count implies. The season in progress is split from this season's tags at Bonneville, each release group sent to the rivers its fish reached in past years; a river with too few tags so far holds its usual share for this date. For the Idaho basins, the season in progress is a PIT tag index with no representation correction, on Idaho Fish and Game's advice that a historic correction should not be applied to a run still under way; those numbers will be revised when the year closes. Hover a segment for the estimate, the tag-expanded fish behind it, and the raw tag-share number it was corrected from.
Other/Unknown is not a river: it is the part of the dam count we could not attribute. In the migration-year view it is near zero for completed years; the calendar-year view is not closed to the census and carries the unattributed share. MY2011 is not drawn: 63 tags cannot split 414,057 fish. Rivers entering the Columbia below Bonneville are excluded here: those fish never passed the dam being counted. Yakima uses the Prosser Dam census in completed years, because a count beats an estimate.
* Method note: totals scale to the dam census, matching how Idaho Fish and Game publish theirs, less a correction of about five percent at Bonneville for fish counted twice after falling back over the dam. Hatchery and wild are allocated separately and recombined using the fin-clip census at the dam. The current-season split is provisional: it rests on this season's tags, and it will move as the fall run and the next model run land.
Loading chart...

Sub-Basin Destinations New

Where fish go inside each drainage: Lochsa, Selway, Lemhi, Pahsimeroi and the rest. Only three drainages are split here: the Clearwater, the Salmon and the Grande Ronde. They are the ones with enough sub-basin arrays to divide. Together they are about two thirds of the run, so the bars here add to less than the Destinations chart above. That is coverage, not disagreement: for each of the three, the sub-basin bars sum to its Destinations bar exactly. Hatchery and wild are allocated separately, because they go to different places. Hatchery production concentrates at facilities like Dworshak; wild fish spread through the headwater tributaries. Pooling them (our PIT sample is 93–99% hatchery, the run is 52–72%) made every sub-basin number a hatchery number. Each river's hatchery and wild totals are the ones on the Destinations chart above; hatchery is split among the sub-basins by PIT tags, wild by Stark's published sub-basin returns, so the two charts agree by construction. Where the tags name a sub-basin Stark does not (Sawtooth's returns to the upper Salmon) it shows as hatchery with no wild, and the reverse for wild-only streams. Some years show one hatched grey block instead of a fork split. That is a year when a fork that normally carries a fifth or more of the drainage recorded almost no tags, usually because an array was down rather than because the fish were absent. Splitting the rest would push that fork's fish onto its neighbours, which is what this chart used to do: in MY2026 the South Fork was drawn at 20,550 of the Clearwater's 30,417 because the North Fork read zero. Hover the block to see which fork is missing.
Loading chart...

Ocean Age × Origin (IDFG Style) New

Stacked by ocean age (winters at sea) and origin, in IDFG's reporting format. Dark is hatchery, light is wild.
How ocean age is known: only for fish PIT-tagged as juveniles, where we know the year they went to sea. Ocean age = (return migration year − smolt migration year) − 1. A fish tagged as an adult has no smolt year, so its ocean age is unknowable and it is excluded. How origin is known: a juvenile tagged at a hatchery is hatchery; one tagged at a screw trap or in-river is wild. The bar heights come from the DART dam census; only the split between age and origin classes is estimated from tags.
Read the labels before trusting a bar. Each shows the PIT tags behind it. Every drawn year rests on 1,400 to 10,700 aged tags (2012–13: 8,944, about 26 fish per tag; the thinnest, 2021–22, 1,750); a dam-year under 500 is not drawn and the axis says which. Ages come from each tag's mark year, origin from its rear type. Only ladder detections count: array detections years later read as extra ocean winters and are excluded.
Loading chart...

Returning Adults by Drainage Beta

Estimated adult returns by drainage, by migration year (June 1 to May 31), the same numbers as Basin Destination, drawn as lines. The same season totals as the Destinations chart, drawn as lines. Includes 3yr/5yr/10yr average reference lines. Hover for expansion details.
Loading chart...

Hatchery vs Wild: Bonneville

How origin is determined: counted at the dam window, not from PIT tags. Wild fish have an intact adipose fin; hatchery fish are fin-clipped before release, so counters can tell them apart on sight. DART publishes Steelhead = the total run and Wild Steelhead = the wild subset of that total, so hatchery = total − wild. (Adding the two columns double-counts every wild fish and inflates the run 28–40%; that error reached this site once before.) This is a census of every fish that passed, not an estimate.
Loading chart...

Hatchery vs Wild: Lower Granite

Snake River hatchery vs wild origin split at Lower Granite Dam.
Loading chart...

Ocean Age × Origin (IDFG Style)

Winters at sea × hatchery/wild. Identical to the Destinations-tab copy: one number, two homes. Current season: see the one-salt collapse note.

Loading chart...

Adult Length Distribution

Size distribution of returning adults by river system. Bimodal peaks often correspond to 1-ocean vs 2-ocean fish.
Loading chart...

Adult Length vs Ocean Age New

Each point is one fish. Circles = paired juvenile+adult measurements, orange diamonds = adult measurement only (age estimated from length). Click any fish to open its full tag history on PTAGIS. Colored by ocean class. Use dropdown to filter by river.
Loading chart...

Columbia Basin Migration Flows New

Steelhead flow through the Columbia and Snake River dams to the rivers they end up in, and one level further for the largest rivers. DART dam counts set the total flow at each dam. The river split is the same allocation as the Destinations tab. Completed migration years only: the season in progress is on the Destinations tab, because dam counts to date cannot show where a run still in the river will end up. "Other tributaries" is what a dam counted that the model did not place in a named river: smaller tributaries, harvest and loss between dams. The forks to the right of the largest rivers (the Clearwater, Salmon, Grande Ronde and Imnaha in most years) are the Sub-Basin Destinations split; a "Rest of" node holds the smaller forks and the fish no sub-basin site placed, so every river sends on exactly what it receives. View dam map →
Loading Sankey data...

Entry-Gate Detections by River New

Daily PIT tag detections at river entry gates across all years. Average row at top shows typical timing; individual years below. Select a river to see its entry-gate detections over time. Toggle years on/off.
Years:
Loading heatmap...

Migration Timing by Year: Dams New

Daily DART passage counts across all years at major dams. Each row is a year, each column is a day of year. Shows how migration timing shifts year to year: earlier runs, later peaks, and unusual patterns.
Years:
Loading heatmap...

PTAGIS Detection Sites: Map

Official PTAGIS map of PIT tag interrogation and MRR sites across the Columbia Basin. Use the built-in search (magnifying glass icon) to find sites by code or name. Cross-reference site codes with the heatmap above.

How to Use This Dashboard

Every chart on this site is interactive. Here are the key things you can do:

Legend Controls:

  • Single click a year or river in the legend to hide/show it
  • Double-click a legend entry to isolate it; only that item will show. Double-click again to restore all.

Dropdowns & Buttons:

  • Use dropdown menus (top-left of charts) to switch between views: dam totals, individual rivers, smoothing modes, etc.
  • On the Run Timing chart, the dropdown lets you pick Bonneville (BON) or Lower Granite (LWG) scaling and filter to individual rivers. Single-river views color lines by year so you can compare across seasons.

Chart Interaction:

  • Hover over any line or bar to see detailed data: fish counts, percentages, PIT tag info, expansion factors
  • Click + drag to zoom into a region. Double-click to reset zoom.
  • Use the camera icon in the top-right toolbar to download a chart as a PNG image

What Can You Learn?

  • Dam Passage: Compare this year's daily fish counts to historical patterns. Is the run early, late, big, or small?
  • Run Timing: Track cumulative progress: what % of the run has passed? How does each river compare?
  • Destinations: Where are the fish going? Basin destination shows estimated returns per river system. The "expansion" number in the hover tells you how many real fish each PIT tag represents (e.g., 5x means each tagged fish represents ~5 total fish). It is the final estimate divided by the tag-weighted fish behind it, so it shows how far the census closure moved that river (1.0x means the weighted tags alone accounted for it). Each tag's own weight is one over its release group's tagging rate, from the release records. It is not the dam count divided by the tags.
  • Fish Biology: Size distributions and ocean age help understand the population mix (1-ocean vs 2-ocean fish).
  • Migration Flows: Sankey diagram traces fish from Bonneville through each dam to their final destination river. Width of each band = number of fish. Use the year dropdown to compare across years.
  • Fish Biology: Click any fish dot on the growth scatter to open its full tag history on PTAGIS. Orange diamond markers are fish with a single adult measurement only (age is estimated from length).

Dam & Site Abbreviations:

BON = Bonneville TDA = The Dalles JDA = John Day MCN = McNary IHR = Ice Harbor LMN = Lower Monumental LGS = Little Goose LWG = Lower Granite PRD = Priest Rapids WAN = Wanapum RIS = Rock Island RRH = Rocky Reach WEL = Wells

Where the run goes: three ways of asking

The most important open question on this site. Solid lines are fish tagged at the Bonneville trap and followed upstream; the dotted crosses are what this site currently publishes. The stars and diamonds are CRITFC's own reads of the same run by two different methods: stars are their PIT tracking (2021, 2022); the one genetics series left (2014, 2016, 2018) is the Upper Columbia, the others were removed on 29 August because they did not count the same fish. CRITFC's PIT read lands nearer the tracers than to what we publish. The Snake share we publish is set by the Lower Granite count, and its gap to the tracers, which count only fish that reached the Snake, is open. What this means →
Loading chart...

Scoreboard: our Idaho split vs IDFG, year by year

The check that matters most, shown rather than summarised. Bars are the per-year gap between our Clearwater share and IDFG's published one; lines are the two shares. An average across years would look far better, and would be hiding exactly what these bars show.
The genetics series was removed on 29 August 2026. It was built from CRITFC's upper-basin genetic groups only, which leave out the lower Clearwater and lower Salmon, while our series counts the whole basin. Different denominators, so the comparison was not well posed and should not have been published. It returns when we can match the sub-basins on both sides. The one genetics series that does match, CRITFC's Upper Columbia group, stays on the tracer chart on the How we know tab. What this means →
Loading chart...

About SteelheadTracker

SteelheadTracker is a passion project that tracks Columbia Basin steelhead migration using publicly available data from DART (Columbia Basin Research), PTAGIS (PIT Tag Information System), the Fish Passage Center (hatchery releases and smolt monitoring), USGS (water data), and NOAA (weather forecasts).

Why should you trust this?

Fair question. I'm a fisherman who wanted answers I couldn't get on the schedule I needed them. The data was all public: dam counts, PIT tag detections. But the answers were locked in reports that arrive years late. I've always appreciated the run-breakdown graphs Idaho Fish & Game publishes; they calibrated my expectations. But they came out sporadically, and were never up to date or the most current when I was trying to make decisions about a trip.

So it started small: watching detections at two antennas on the South Fork Clearwater and weeding out fish that pinged the same array twice in a day. It turns out, in an unpredictable twist, that scaling up from two detection sites to the entire Columbia system was longer and harder than I thought. Ten months, a lot of evenings, and a healthy number of documented mistakes later, it worked. It's finally at a version that's good enough, at least for me, and I'm more particular than most people about this kind of thing.

What started as a small script became, working side by side with state-of-the-art AI over many months, a roughly 40,000-line Python analysis pipeline: fifteen-plus years of detection histories for hundreds of thousands of individually PIT-tagged steelhead, merged with the daily counting-window census at every major dam, plus published tagging rates, hatchery release records, and run reconstructions from IDFG and Columbia Basin research programs.

And because "a big pile of code" is not by itself a reason to trust anything, the pipeline spends as much effort checking its numbers as producing them. Two numbers are scored against Idaho Fish and Game's run reconstruction: the split between the Clearwater and the Salmon, and the level of each. The current figures, and their worst years, are on the accuracy page rather than typed here, so they cannot go stale; and every dam total is checked against the census. Outside Idaho only the Klickitat has a published count to score against (the Yakama Nation's Lyle Falls estimate); the other rivers' pages say so. Where our numbers and the published ones disagree, the chart says so instead of hiding it. That testing has caught my own errors before they reached you more than once; the one time it didn't, the What's New section below tells that story honestly.

The goal is simple: the same public data that powers DART and PTAGIS, vetted, cross-referenced, ranked, and presented so you can actually read it.

Data Sources:

  • DART: Dam passage counts (daily & annual)
  • PTAGIS: PIT tag detection data (individual fish tracking)
  • PTAGIS Detection Sites: PIT tag monitoring site locations and metadata
  • Fish Passage Center: hatchery release totals by year and basin, the denominator behind every tagging rate, and the Smolt Monitoring Program daily collection counts at Lower Granite and Rock Island, the sampling frame for fish tagged at a dam
  • USGS: Streamflow and water temperature
  • NOAA: River flow forecasts
  • Columbia Basin Dam Map: Overview of dam locations in the basin

How It Works:

A build script fetches the latest DART dam passage data and combines it with precomputed PIT tag analysis (basin destinations, growth, origin classification). Charts are rendered client-side using Plotly.js, with no server computation needed.

Methodology Notes:

  • Destination and returning adult charts default to migration year (June 1 to May 31); the destination chart's dropdown also offers calendar-year views to line up with dam passage data
  • H/W classification from DART uses the "Wild Steelhead" column reported by dam operators
  • PIT-based H/W uses release site information to infer hatchery vs wild origin
  • Basin destinations: a Clearwater or Salmon hatchery fish is assigned the basin it was released into, every other hatchery fish is placed by where it was seen again upstream, Idaho wild fish follow Idaho Fish and Game's published wild split, wild fish elsewhere share one census-derived fraction, and the season in progress is split from this season's tags at Bonneville, sent to the rivers those release groups actually reached in past years
  • Charts marked "Beta" are under active development and may have known limitations

A Note on the Numbers:

Estimating how many steelhead are heading to each river is a genuinely hard problem. Only a fraction of the fish carry PIT tags, and those tags have to be expanded (multiplied by factors from 10× to 50× or more) to estimate basin destinations. Expansion factors vary by year and river, some rivers have very few tags to work with, and no antenna detects every fish. So instead of asking you to trust the method, this site publishes its error: every estimate is scored against independent published sources (Idaho Fish and Game's hatchery figures for the Clearwater and Salmon, their wild escapement by stock for the Snake, and the dam censuses; rivers outside Idaho have no published figure to score against), the misses are documented alongside the hits, and when something turns out wrong it gets said here, not buried. See How accurate is this? for exactly how far to trust each number. If you spot something that looks off, or you have expertise that could improve the methodology, I'd genuinely like to hear from you.

Contact & Support:

Built by Paul Van Valkenburg, paul.vanvalkenburg@gmail.com

If you find this project useful and want to support its development, whether that means buying me a beer, helping me take my wife out to dinner to repair the damage this site has done to my marriage, or just keeping the servers running, any contribution is appreciated. Donate via PayPal

Want to receive updates? Email me to join the mailing list.

What's New

October 5The forecasts through October 5, and one scale all season: the Salmon has passed the Clearwater

Counts through October 4 are in, and the chart from September 29 is redrawn below through October 5.

One change in how the Snake pages read. Until now they counted at Bonneville until October 1 and then switched to the Lower Granite scale, which put a 30 percent step in every number with no fish behind it. They now count at Bonneville all season, where their fish are counted first and the season is 95 percent complete by October, and show beside the finish the share expected to reach Lower Granite, measured from each river’s own tags over the last three seasons (about 0.78 for the Clearwater and Grande Ronde, 0.81 for the Salmon), with the Granite count so far as the running check. The grey line on the chart is that expectation.

Today: Clearwater 12,921 at Bonneville and 10,027 expected at Granite with 6,254 counted there so far; Salmon 13,053 and 10,534 (7,663 counted); Grande Ronde 7,680 and 5,960 (4,413 counted). The Clearwater keeps coming down and the Salmon has passed it. That is fish, not method: the Clearwater added 33 fish at Bonneville in the three days after October 1 while its own timing expects about a sixth of its run after that date, the late B-run, so every day those fish do not arrive lowers its finish. The Salmon is 91 percent in by October 1 and holds. In tagged fish the Clearwater has 155 past Bonneville where the last three seasons had 433, 899 and 399 by this date.

Projected finish by build date for the Clearwater, Salmon and Grande Ronde, 12 September to 5 October 2026, at Bonneville, with the share expected to reach Lower Granite

Also this week: the Granite expectation uses each river’s own measured share in place of one Snake-wide constant; checked against Idaho Fish and Game’s published per-basin numbers it halves the error. The method is on the accuracy page.

October 2New on the Snake river pages: fish on the way, and when they usually get there

Every river page except the Deschutes now has a card called Fish on the way. It counts the tagged fish bound for that river that are past Bonneville and past the next dam up this season, how many have reached each sub-basin’s antennas, how many to expect in the next two and four weeks and the rest of the season, and when they usually arrive. These are tag counts, not fish counts, so read them for pace and timing. The flow column carries the NOAA river forecast for the gauge nearest the antennas and names the days a rise is forecast; the counts are not flow-adjusted, because I tested that against 14 seasons and it did not help the two-week number, while the rise days do say which days fish move.

The measured part surprised me. South Fork Clearwater fish reach the South Fork around the first week of March whether they crossed Bonneville in July or October; they hold in the main river through the winter. Flow moves them: on days after a three-day rise of 25 percent or more at Stites, arrivals on the South Fork run two to nine times the other days’ rate, in every month from October to March. Last fall was the second-highest fall flow on record there, and 60 percent of last season’s South Fork fish were in before January 1, against 0 to 31 percent in every other season.

Before putting the forecast up I ran it on each of the last 14 seasons as if that season were under way, and scored it against the simplest alternative, assuming the same arrivals as the season before. It beats that in most seasons for every river except the Dworshak trap, which the card marks low confidence. Researchers say the Columbia has been through several steelhead eras in this record; I tested training the forecast within those eras and it did not help, so it uses the last three seasons. The method and every score are on a page of their own.

Also in this update: counts through October 1. Bonneville added 155 fish in two days. The Snake river pages switched to the Lower Granite scale on October 1, as they do every year when the run reaches Granite, so their season totals and finishes now read at Granite and are not comparable with the September figures.

September 30Since the last update: everything revised down, the Salmon and Clearwater most

Four more days of counts, September 25 to 28, and every forecast on the site came down. Bonneville added 652 steelhead in those four days; the three past seasons this one is being compared to added 1,300 to 2,800 in the same four days. The forecast assumes the season keeps pace with those years, so when it falls behind, the fish still to come are scaled down for every river.

The Salmon and the Clearwater took the biggest hits, 15,000 to 14,000 and 16,000 to 14,400. The Salmon's own tagged fish simply did not arrive: none crossed Bonneville in the four days, where the comparison years averaged five. The Clearwater's did arrive, eight of them, but a Clearwater forecast leans on the whole run's pace because most of its fish come late, so it fell with the run. The Grande Ronde and Imnaha, mostly in already, barely moved.

Nothing in the model changed between these two builds. This is the first revision this month that came only from fish.

September 29What a month of changes did to the forecasts, and what to make of it

This is the first season this site has run, and the honest question is how much the forecasts are worth. Between September 12 and 29 the fish barely moved and the forecasts moved a lot, and most of that movement was me changing the model, not fish.

I spent the month working with Idaho Fish and Game on how their numbers are built. Every change was an improvement against their run reconstruction: the level error on the Idaho hatchery counts went from 22 percent to 11, the Clearwater-to-Salmon split from 6 points to 3.5. But each change also moved the forecast for the season under way, and more than I wanted to see.

The Salmon and Grande Ronde forecasts held together through it, inside 13,900 to 17,500 and 7,000 to 8,700 fish all month, and they are converging. The Clearwater's did not: 14,800, 11,600, 20,400, 14,500 and 16,000 across five builds on nearly the same fish. It is the latest-running river and the one every method change lands on hardest, and its band of plus or minus 28 percent is the model saying exactly that. I am not yet sure the Clearwater lines are going to meet.

From here the method holds still and the forecasts move only with fish. The first such step is in: four more days of counts, September 24 to 28, moved the Clearwater finish from 16,000 to 14,400, the Salmon from 15,000 to 14,000 and the Grande Ronde from 7,960 to 7,780, all downward because the fish are arriving slower than the analog years did. That is what a few days of data is worth; the earlier swings were not that. The chart shows each build's projected finish with its band, one panel per river, and it will be extended as the season runs.

Projected finish by build date for the Clearwater, Salmon and Grande Ronde, September 2026

September 25Idaho Fish and Game explained the gap, and the Idaho hatchery numbers moved

I wrote to Idaho Fish and Game asking why my PIT tag count for Dworshak came out at about 60 percent of their run reconstruction every year. Their hatchery evaluation program answered. A PIT tag estimate under-counts the run because some tags are lost and tagged fish survive at a slightly lower rate than untagged ones. They call the shortfall PIT representation, measure it every year against their genetic count at Lower Granite, and it is not a constant: about 70 percent for the Clearwater and 90 percent for the Salmon and Snake over 2013 to 2019, but 82 to 92 percent and 89 to 101 percent over 2021 to 2025.

What changed on the site:

  • The Dworshak correction this site fitted to the 2013 to 2019 reports, and applied to every year, is gone. It assumed 62 percent representation forever and was too large by about a third for recent years. Completed years now use IDFG's own representation figures by basin and year. Against the site as last published, the Clearwater hatchery count at Bonneville for 2021 to 2026 is up 5 to 14 percent (MY2025: about 37,600 to about 42,100). Most of that is a change made on September 18, when unclipped hatchery fish that the dam count files as wild were moved to the hatchery layer of the basins that release them, using IDFG's own proportions. The representation change on its own moved the Clearwater down 2 to 6 points of share against the intermediate build it replaced, which was never published.
  • The current season is a PIT tag index with no correction, on their advice that a historic figure should not be applied to a run still under way. It will be revised when the year closes.
  • The accuracy page now scores the Idaho hatchery numbers against the run reconstruction, which IDFG describe as their most accurate estimate, and shows their two numbers and ours on one chart. Until today it scored against their fall PIT charts and called that deliberate. It was not the right reference: those charts are the same method as this site, and IDFG say they under-count.

They also confirmed that 2019-2020 is the newest run reconstruction, with later years in progress, and pointed me to where unclipped hatchery releases are published by program.

September 13Every river now gets its own run timing, and the forecasts say how sure they are

Until today every river's run timing was Bonneville's. The model scaled the dam's curve up or down for each river, which changes how big a season is but not when its fish move, so all twelve forecast rivers came out between 73% and 74% through their season on the same date. The Umatilla is largely finished by mid-September and the Clearwater has barely started; they cannot both be three quarters done.

Each river now carries its own timing, measured from 10,291 adult PIT crossings at Bonneville since 2012. The spread is 58 points, not 1:

  • Wenatchee, median 3 August, 92% past by 11 September
  • Salmon, median 31 August, 65% past
  • Clearwater, median 18 September, 34% past

Tested by hiding one year at a time and forecasting it from the others, this is right within 13.8% against 29.4% for the old shared curve. The Clearwater's projected finish roughly doubles as a result.

The forecast band is now the error we actually measure. Each river's band comes from how far that river's forecast has missed in the past, so the Wenatchee reads plus or minus 3% and the Clearwater plus or minus 28%. That difference is real and you were not being shown it.

Four rivers lost their projection. The Umatilla, Walla Walla, John Day and Asotin do not have enough tagged adults to measure their timing, and they were only ever showing Bonneville's curve. They now show no forecast rather than a borrowed one.

Also: the Asotin's 2015 hatchery number was zero because the reference table we anchor to has no Asotin row that year and the code read the gap as a count of nothing. And the hot and cold share chips had been frozen since 29 August because the script that writes them had been failing silently; run again, it says no river is running hot.

September 12The expansion weights were an average of the wrong things

Every hatchery tag stands for some number of untagged fish, and that number was being built badly. For a hatchery that releases into several rivers the model used one pooled rate, so Irrigon's Imnaha fish and its Wallowa fish were both counted at 31 fish per tag when the real rates are 15 and 48. The Imnaha came out more than twice too heavy and the Grande Ronde a third too light.

Worse, the pooled rate itself was a running average that gave the last release in the file half the say. Dworshak's 2024 rate was effectively set by one small, lightly tagged release, reading 87 fish per tag against a true 64.

Both are fixed, and the Grande Ronde's current season rises about 78% as a result. A separate check now refuses any weight below one fish per tag, which caught 41,617 tags standing for less than the single fish they were in.

The error bars were also mislabelled. They were captioned as a 95% confidence interval and are not one: the low end is the fish tags have already placed in a river, the high end assumes the unplaced tags go the same way. For most river-years nothing more is expected to resolve, so the bar sits on the estimate. It now says that.

September 6 to 8Charts that could not be right are gone, and the season finish is on the front page
  • The sub-basin chart used to split a drainage across its forks even when a fork's detectors recorded almost nothing, which pushed those fish onto neighbouring forks. Such a year now shows a single hatched block saying the forks could not be resolved.
  • The calendar-year views on the destinations chart published 41 river-years where a river's Lower Granite number exceeded its Bonneville number, which is impossible. They are withdrawn.
  • The projected season finish now appears on the front page and the phone, not only on the river pages.
  • The forecast band and the average miss are two different quantities and were being quoted as if they were one. They are now labelled separately.
EarlierAugust 2026 and before

August 24, 2026: the site learns to talk, and every river gets a page.

New today: dedicated river pages (browse all 16) with each river's run timing, forecast wedge, season totals, and real PIT-measured travel times ("Clearwater-bound adults take a median 20 days Bonneville→Granite"); a daily "What the data says today" plain-words briefing on the Run Timing tab; the timing wedge charts promoted to the landing view; and a River-shaped alternate layout on the Migration Flows diagram.

3 September 2026. Two audits acted on, and the physics enforced.

Two more independent reviews of the site, twelve readers in all, and the numbers they found were fixed the same day. Upper Columbia rivers no longer sum to fewer fish than the dams that counted them; the Grande Ronde no longer reads more fish at Granite than at Bonneville; the chart caps and the river pages read one file of projected finishes; Cottonwood Creek moved to the Grande Ronde, where it is; three transposed and duplicated rows left the tagging-rate table; and which rivers are held to a typical share is now decided on the model's raw output, not on a chart the decision had already smoothed. The phone page is built with the site from the same data. One rate that stocked five rivers from one hatchery, the Klickitat's, is being priced by the river its tags were released into rather than by the hatchery's total.

2 September 2026. The season in progress, the Washington tag rates, and an audit.

The current season is now split from this season's own PIT tags at Bonneville. Each release group is sent to the rivers its fish actually reached in past years, which matters because Lyons Ferry stock does not go home and barged smolts are filed under a Lower Columbia release site. A river with fewer than twenty tags so far holds its usual share for the date. Upstream dam counts are no longer used as caps on the current season, because they lag Bonneville by weeks and a count to date is a floor, not a ceiling. Before this the Snake read 86 percent of the run so far against tags saying 47 to 50.

  • Tag rates for Washington and Oregon. The Fish Passage Center's release table records zero PIT tags for Skamania, Lyons Ferry, Irrigon and Wells in most years; PTAGIS holds ten to forty thousand a year for each. The rate is now the PTAGIS count over the FPC release total, and where both sources counted tags they agree to within three percent. Fish tagged at the Lower Granite bypass are expanded by FPC's daily collection count there. The Fish Passage Center is now a named source.
  • The Methow's history comes down. The Methow and Okanogan had been allowed up to two times the Wells Dam count, which is the tolerance a check uses, not a measurement. Seventy percent of Methow and Okanogan fish tagged at Bonneville are later seen at Wells, so the cap is now that conversion.
  • An audit. Five independent reviews of this build, one per page, found about seventy items, from a Yakima count of zero caused by a missing map entry to sentences describing a method the site no longer uses. The numbers are fixed in this build, the copy is being corrected, and a second audit follows before anything is published.

1 September 2026. The level, and two rivers that were four times too big.

August fixed which river the run goes to. This update fixes how many fish are in it, which turned out to be a separate problem hiding behind the first one.

  • Ten thousand fish a year were being deleted. The pipeline checked that the rivers never added up to more than the dam counted, and never checked that they added up to it at all. Every year came out at 71 to 95 percent of the real run, with the remainder simply gone rather than marked unknown. The hatchery level now sits about 2 percent above Idaho's published figures instead of 17 percent low every single year.
  • The Methow and the Tucannon were roughly four times too large. Both for the same reason: the step that decides which river a fish is bound for was counting raw tags rather than expanded fish, so a river that tags heavily looked like it received more fish. The Methow read 13 percent of the Columbia hatchery run in 2012 and now reads under 3. Two mislabelled detector codes also sent Tucannon fish to the Tucannon that had never been there, including one that is a trawl in the Columbia estuary, 200 miles downstream.
  • Every river now fits through its own dam. A river's fish must pass the dams between the ocean and home, so its number cannot exceed those counts. That check now passes for every completed year; the season in progress is not capped, because upstream counts lag Bonneville by weeks. It did not pass before.
  • A new check the site cannot fake. Every PIT tag seen at Bonneville, multiplied by how many fish its release group stands for, reconstructs the season total to within about 10 percent of the physical dam count, without being told the answer. That is run by hand after every model rebuild. If the expansion ever breaks, this catches it, and nothing else could.
  • Three missing years of Idaho wild data recovered. Spawn years 2017 to 2019 had been marked unavailable for months. They were published all along, as a picture of a chart with no readable text behind it.
  • Forecasting Lower Granite from Bonneville. Snake fish pass Bonneville two to four weeks before Granite, so Bonneville's count is a real head start. By mid September it forecasts the Granite season to about 12 percent, against 34 percent for assuming last year. This site previously told you to assume last year. That was wrong, and the forecast page now says so.
  • Said plainly what the wild numbers are. Roughly a third of the run is wild, and our wild figures are weaker than our hatchery ones. Outside the Snake there is no river-specific wild estimate at all. The accuracy page now spells out exactly which rivers and years that affects.

August 2026: a big update, and an honest one.

This site ran without updates from late February to late August 2026. During that gap I found several real problems in my own numbers, and rather than patch quietly I rebuilt the validation from the ground up. Everything below is now checked against published sources before it ships: Idaho Fish and Game's own figures for the Idaho rivers, the Yakama Nation's counts for the Klickitat, and dam-by-dam censuses everywhere. Rivers with no published figure are checked only against the dam counts their fish must pass, and a hard gate blocks the site from deploying if the numbers fail.

Fixed in this update:

  • Eight charts restored: the live build had silently switched to an older script and dropped them (including the calendar/migration-year toggles).
  • Ocean age corrected: 1-salt fish were dramatically undercounted by a day-counting bug; ages now derive from migration years and are validated against length distributions.
  • One number per quantity: the cumulative run-timing chart and the destinations chart could disagree about the same river by 5x. Both now read from a single source. The Dam Passage tab's daily split by destination is a different quantity, the share of each day's tags seen later at each river's entry arrays, and it does not match these totals; it is being rescaled to them.
  • Hatchery and wild estimated separately: the PIT-tag sample is 93–99% hatchery while the actual run is 52–72% hatchery. Pooling them made every destination estimate quietly a hatchery estimate. Wild allocation now uses wild sources and the dam fin-clip census.
  • New: sub-basin destinations: Lochsa, Selway, Lemhi, Pahsimeroi and 18 more tributaries, from the separate hatchery/wild allocation.
  • Confidence intervals repaired: some intervals didn't contain their own estimate after a late rescaling step; whiskers now wrap every bar.
  • Impossible destinations removed: basins that enter the Columbia below Bonneville can't be destinations for fish counted at Bonneville.
  • 2011 shown as unresolved: only 63 usable tags exist for that migration year, which cannot support per-river estimates. The bar now says so instead of pretending.
  • Two data clocks: dam counts update daily (automated); PIT detection data runs through the date in the header: it refreshes with each model rebuild, not nightly, and this line states the real date rather than pretending otherwise.

Known limitations, plainly:

  • Returns to the Snake mainstem itself are not shown as their own river; they are folded into the Salmon group, as Idaho Fish and Game publish them. Mainstem estimates lean on a model prior, because very few tags resolve there, so treat them as indicative rather than measured.
  • The current migration year is always partial until the run completes in May.
  • Tag-expansion methodology is under active validation against IDFG's published numbers; expect refinements, and expect me to say so here when they land.

Build time and data date are in the header above