Technical Guide

Technical guide

This page will document how the app calculates wave data, filters surf spots, and combines buoy, wind, and tide information.

Sections will be added here over time as the forecast logic is documented.

Swell Timing

How swell travel time is estimated from a buoy

The app estimates swell timing by treating the swell as a moving line of energy in deep water. It uses the buoy location, the destination shoreline target, and the swell period reported by the buoy.

First, the swell period is converted into an approximate deep-water group speed:

group speed (knots) ≈ 1.515 × swell period (seconds)

Next, the app converts the swell “from” direction into a travel direction by adding 180 degrees. That travel vector is compared against the line from the buoy to the coastline target.

Instead of only using straight-line distance, the app projects the buoy-to-target vector onto the swell travel axis. That produces a signed distance:

signed distance = dot(target - buoy, unitVector(travelDirection))

Travel time is then estimated by dividing that signed distance by the swell group speed:

arrival hours = signed distance / group speed

A positive result means the swell line has not reached the target yet. A negative result means that the swell line has already passed the target. That is why an east or southeast swell can show as “past Hanalei Bay” when viewed from a northwest buoy.

Pseudocode

travelDirection = swellFromDirection + 180
groupSpeedKnots = 1.515 * swellPeriodSeconds
signedDistance = dot(targetVectorFromBuoy, unitVector(travelDirection))
arrivalHours = signedDistance / groupSpeedKnots

Swell speed by period

These are the approximate deep-water group speeds used by the app when estimating travel time from a buoy.

Swell periodGroup speedApprox mph
8s12.1 kt13.9 mph
10s15.1 kt17.4 mph
12s18.2 kt20.9 mph
14s21.2 kt24.4 mph
16s24.2 kt27.9 mph
18s27.3 kt31.4 mph

Buoy Power

How buoy power and wave height are estimated

Forecast power in the app is a custom energy-style score based on swell height and swell period. It replaces Surfline's row power as the source of truth for filters and forecast displays.

The calculation starts with the idea that swell energy rises faster than height alone, so height is squared and then weighted by period:

swell power = swell height² × swell period

In the formula above:

  • swell height is in feet
  • swell period is in seconds

This means the power score is not a direct physics unit like watts or kilowatts. It is a surf-forecast scoring metric that increases strongly with both size and period.

Forecast row power is then calculated from the matching swells for a spot: the biggest eligible swell power plus half of the second biggest eligible swell power.

Estimated surf height uses a different idea. Instead of reusing period directly, the app maps combined power into coarse whole-foot surf bands.

row power = biggest matching swell power + 0.5 × second biggest matching swell power

The power-to-height conversion is intentionally coarse. It is a surf-facing heuristic for filtering and display, not a spot-specific breaking-wave model.

Pseudocode

if swellHeightFeet == null or swellPeriodSeconds == null:
  return null

swellPower = swellHeightFeet * swellHeightFeet * swellPeriodSeconds
rowPower = strongestMatchingSwellPower + 0.5 * secondStrongestMatchingSwellPower

Power To Height Bands

power < 40 => 0 ft
40-59 => 1 ft
60-79 => 1.5 ft
80-119 => 2 ft
120-159 => 2.5 ft
160-199 => 3 ft
200-239 => 3.5 ft
240-299 => 4 ft
300-359 => 4.5 ft
360-479 => 5 ft
480-585 => 6 ft
... then grow by about 1.22x across:
7, 8, 9, 10, 12, 14, 16, 18, 20, 25, 30, 35, 40 ft
Estimated surfPower band
1 ft40-59
1.5 ft60-79
2 ft80-119
2.5 ft120-159
3 ft160-199
3.5 ft200-239
4 ft240-299
4.5 ft300-359
5 ft360-479
6 ft480-585
7 ft586-714
8 ft715-871
9 ft872-1062
10 ft1063-1295
12 ft1296-1580
14 ft1581-1927
16 ft1928-2351
18 ft2352-2868
20 ft2869-3499
25 ft3500-4269
30 ft4270-5208
35 ft5209-6353
40 ft6354-7750

Example buoy power and wave-height values

These examples use the same formulas documented in this section so you can compare how power and estimated face height scale differently.

Buoy swellCalculationPowerEst. wave face height
2.0 ft @ 8s2.0² × 832.018.0 ft
2.5 ft @ 12s2.5² × 1275.01.5 ft
3.5 ft @ 8s3.5² × 898.02.0 ft
4.0 ft @ 10s4.0² × 10160.03.0 ft
4.9 ft @ 14.8s4.9² × 14.8355.34.5 ft
5.4 ft @ 8s5.4² × 8233.33.5 ft
6.0 ft @ 12s6.0² × 12432.05.0 ft
6.5 ft @ 8s6.5² × 8338.04.5 ft
8.0 ft @ 18s8.0² × 181152.010.0 ft
7.8 ft @ 9s7.8² × 9547.66.0 ft
10.0 ft @ 16s10.0² × 161600.014.0 ft
12.0 ft @ 18s12.0² × 182592.018.0 ft
18.0 ft @ 20s18.0² × 206480.040.0 ft

This power score is best used as a relative measure of swell energy. Higher numbers mean more potential surf energy offshore, but they do not directly guarantee a specific breaking wave height at the beach.

The estimated wave-height value is intended to be a more intuitive surf-facing number than power. It is still a coarse heuristic and should be treated as a generic offshore-to-surf estimate, not a spot-specific breaking-wave model.

Direction, refraction, island shadowing, and local bathymetry still determine how much of that energy actually turns into surf at a given spot and how big the final breaking waves appear.