Forecast Accuracy Report
The surf forecast that grades itself. Every 6 hours we snapshot our own forecasts at NOAA buoy locations, then score them against what the buoys actually measured. No cherry-picking — every scored forecast is counted, and every scored pair is published as an open dataset.
Check our work: summary JSON · per-station CSV · every scored pair · the scoring code
Rolling 30-day window · updated 2026-09-01 22:50 UTC
Great Lakes
| Buoy | Pairs | Bias | MAE 0–24h | MAE 24–48h | MAE 48–72h |
|---|---|---|---|---|---|
| East Lake Ontario #45012 | 2428 | -0.05 m | 0.119 m | 0.142 m | 0.173 m |
| North Lake Michigan #45002 | 2419 | -0.05 m | 0.114 m | 0.121 m | 0.162 m |
Gulf
| Buoy | Pairs | Bias | MAE 0–24h | MAE 24–48h | MAE 48–72h |
|---|---|---|---|---|---|
| Galveston, TX #42035 | 2692 | -0.06 m | 0.095 m | 0.107 m | 0.122 m |
Hawaii
| Buoy | Pairs | Bias | MAE 0–24h | MAE 24–48h | MAE 48–72h |
|---|---|---|---|---|---|
| Mokapu Point, HI #51202 | 2716 | -0.13 m | 0.192 m | 0.205 m | 0.209 m |
| Waimea Bay, HI #51201 | 2692 | +0.23 m | 0.243 m | 0.243 m | 0.253 m |
Mid-Atlantic
| Buoy | Pairs | Bias | MAE 0–24h | MAE 24–48h | MAE 48–72h |
|---|---|---|---|---|---|
| Barnegat, NJ #44091 | 2692 | -0.10 m | 0.143 m | 0.16 m | 0.171 m |
| Long Island (30nm S of Islip), NY #44025 | 2648 | +0.02 m | 0.126 m | 0.162 m | 0.194 m |
| New York Harbor Entrance, NY #44065 | 2704 | +0.02 m | 0.104 m | 0.133 m | 0.17 m |
New England
| Buoy | Pairs | Bias | MAE 0–24h | MAE 24–48h | MAE 48–72h |
|---|---|---|---|---|---|
| Block Island, RI #44097 | 2681 | +0.07 m | 0.125 m | 0.164 m | 0.205 m |
Northern California
| Buoy | Pairs | Bias | MAE 0–24h | MAE 24–48h | MAE 48–72h |
|---|---|---|---|---|---|
| Monterey, CA #46042 | 2716 | +0.06 m | 0.152 m | 0.167 m | 0.197 m |
| San Francisco Bar, CA #46026 | 2692 | +0.16 m | 0.16 m | 0.196 m | 0.237 m |
Pacific Northwest
| Buoy | Pairs | Bias | MAE 0–24h | MAE 24–48h | MAE 48–72h |
|---|---|---|---|---|---|
| Columbia River Bar, OR/WA #46029 | 2692 | +0.05 m | 0.118 m | 0.135 m | 0.168 m |
| Grays Harbor (Westport), WA #46211 | 2692 | +0.00 m | 0.128 m | 0.14 m | 0.169 m |
Puerto Rico
| Buoy | Pairs | Bias | MAE 0–24h | MAE 24–48h | MAE 48–72h |
|---|---|---|---|---|---|
| San Juan, PR #41053 | 2631 | -0.12 m | 0.154 m | 0.167 m | 0.179 m |
Southeast
| Buoy | Pairs | Bias | MAE 0–24h | MAE 24–48h | MAE 48–72h |
|---|---|---|---|---|---|
| Cape Canaveral Nearshore, FL #41113 | 2692 | -0.14 m | 0.141 m | 0.144 m | 0.151 m |
| Grays Reef, GA #41008 | 2681 | -0.03 m | 0.106 m | 0.119 m | 0.129 m |
| Masonboro Inlet, NC #41110 | 2692 | -0.00 m | 0.112 m | 0.114 m | 0.116 m |
| Oregon Inlet, NC #44095 | 2692 | -0.02 m | 0.097 m | 0.108 m | 0.112 m |
| St. Augustine, FL #41117 | 2692 | -0.07 m | 0.114 m | 0.121 m | 0.131 m |
Southern California
| Buoy | Pairs | Bias | MAE 0–24h | MAE 24–48h | MAE 48–72h |
|---|---|---|---|---|---|
| San Pedro, CA #46222 | 2716 | -0.06 m | 0.112 m | 0.12 m | 0.118 m |
| Torrey Pines Outer, CA #46225 | 2716 | -0.04 m | 0.1 m | 0.103 m | 0.1 m |
Methodology
Every 6 hours (about 2h45m after each NOAA wave-model cycle) we request our own public forecast at the exact coordinates of 21 NDBC wave buoys spanning every region we serve. Each snapshot stores the predicted significant wave height (and wave period, though the period figures aren't shown here — see below) out to 72 hours ahead.
Once a forecast's valid time passes, it is paired with the buoy observation nearest in time (within 45 minutes) and the error is recorded. Bias is the mean of forecast − observed (positive = we over-forecast), MAE is the mean absolute error, both over a rolling 30-day window. Wave heights are significant wave height in meters, compared like-for-like in open water — this measures the wave model, not breaking-wave face height at the beach.
We don't publish a headline period-bias number. Our own forecast sources define "wave period" differently (a mean period from one, a peak period from another) and neither matches NDBC's peak-period observation cleanly, so a pooled figure would mostly measure that definitional gap rather than forecast skill. The per-source period error is still computed and available in the raw JSON for anyone who wants to dig into it.
We use these numbers, not just publish them: where a buoy shows a persistent, well-sampled bias, the forecast served for nearby spots is automatically nudged by the measured amount (capped, and only with 30+ scored pairs behind it). The verification always scores the raw model output, so the correction can't hide the model's true error. Pipeline code is open source.