How SwellSlots AI Predicts Local Wave Heights

Jacques du Rand · April 10, 2026 · 14 min read

The Problem: One Ocean, One Grid, Many Different Waves

Here's something most surfers don't think about: the offshore swell data that powers surf forecasts comes from numerical wave models with a fixed grid resolution. SwellSlots pulls data from the Open-Meteo Marine API, which uses the MeteoFrance MFWAM model at roughly 8km resolution (0.08 degrees).

What does that mean in practice? It means that spots within the same ~8km grid cell receive identical raw swell data. Take Cape Town's Atlantic coast: Sunset Beach, Big Bay, Doodles, Kite Beach, Haakgat, and Pans all share the same offshore swell reading — something like 1.46m at 8.8 seconds from 209 degrees.

But any surfer who's been to these spots knows they produce very different waves. Dungeons (a heavy big-wave reef break outside Hout Bay) and Llandudno (a punchy beach break in a scenic cove) are only about 7km apart — but the waves they produce on the same swell couldn't be more different.

That's the problem we set out to solve.

Where the Data Comes From

SwellSlots fetches two parallel API calls from Open-Meteo for every spot:

Marine API (swell, ocean, sea temperature):

  • swell_wave_height — significant wave height in metres
  • swell_wave_period — average swell period in seconds
  • swell_wave_peak_period — peak energy period in seconds (more accurate for surf)
  • swell_wave_direction — compass bearing the swell travels from (0-360 degrees)
  • secondary_swell_wave_height and secondary_swell_wave_period — the secondary swell train
  • wind_wave_height — locally generated chop (metres)
  • sea_surface_temperature — water temp in Celsius
  • ocean_current_velocity and ocean_current_direction — currents

Weather API (wind, atmosphere):

  • wind_speed_10m — wind speed at 10 metres above sea level (km/h)
  • wind_direction_10m — where the wind blows from (degrees)
  • temperature_2m, uv_index, visibility, cloud_cover, precipitation_probability

Open-Meteo's marine data is powered by global wave models including MeteoFrance MFWAM (8km resolution, 10-day forecast range) and ECMWF WAM (9km, 15-day range). These are the same class of spectral wave models used by national meteorological agencies worldwide — descendants of the WAM (Wave Modelling) family that's been the backbone of operational wave forecasting since the 1980s.

The data is solid. The problem isn't the quality of the offshore forecast — it's that offshore and local are two very different things.

Two Layers: Universal Ratings + Spot-Specific AI

SwellSlots uses a two-layer approach to turn raw data into something useful.

The SwellSlots forecast grid for Dungeons — each cell is a time slot showing swell height, period, wind, and tide at a glance.

Layer 1: Base Forecast Rating

Every time slot on the forecast grid gets a universal rating based on simple thresholds. This is what you see at a glance on the main grid:

Swell Rating Height Period
Epic 1.0-2.5m 10s+
Good 0.8-3.0m 8s+
OK 0.5-3.5m 6s+
Bad anything else -

Wind gets rated too — glassy conditions (8 km/h or less, any direction) are Epic, offshore winds up to 18 km/h are Epic, and so on. Tide state contributes as well: rising tide is rated highest, falling and high are good, low tide is just OK.

These three are combined into a composite score using weights: swell 40% + wind 40% + tide 20%. The weights reflect reality — swell and wind matter equally and most, tide is secondary but still important.

One key piece of per-spot data does feed into Layer 1: the beach facing direction. Each spot stores the compass bearing it faces toward the ocean (e.g. Llandudno faces 270 degrees — due west). This lets us convert raw wind degrees into meaningful surf terms: offshore, onshore, cross-shore, or cross-offshore. An easterly wind at a west-facing beach is offshore (great!), but the same wind at an east-facing beach is onshore (not great). Without the beach facing direction, we couldn't distinguish these.

Layer 2: The AI Prediction

When you tap into a time slot's detail view, SwellSlots applies the spot-specific AI correction. This is where things get interesting.

The SlotDetail modal showing the SwellSlots AI Prediction — corrected local height, swell match, and all the correction factor badges (exposure, refraction, period, tide).

The core formula:

correctedHeight = offshoreHeight x exposure x direction x refraction x period x tide

Six multiplicative factors, each grounded in surf physics. Let me walk through each one using two real Cape Town spots as examples:

  • Dungeons — reef break, exposure 1.35, optimal swell direction 225 degrees, best tide low, faces 210 degrees toward the ocean
  • Llandudno — beach break, exposure 0.75, optimal swell direction 220 degrees, best tide mid, faces 270 degrees toward the ocean

The Six Factors

1. Exposure Factor (0.35 - 1.40)

This is the big one — a static multiplier assigned to each of our 2,050+ spots based on local geography. It encodes whether a spot amplifies or attenuates the offshore swell.

The physics: When ocean swell approaches the coast, the underwater terrain (bathymetry) does remarkable things. A shallow reef shelf can focus wave energy and amplify swell height — this is why reef breaks like Dungeons produce waves much bigger than the offshore reading. Conversely, a sheltered bay with headlands blocking the main swell window attenuates the swell — waves lose energy wrapping around obstacles.

This is related to the principle of wave shoaling: as waves enter shallower water, group velocity decreases and wave height must increase to conserve energy flux. Reef breaks exploit this dramatically.

Range Meaning Example
0.35-0.49 Very sheltered bay Protected harbours
0.50-0.79 Sheltered / attenuated Llandudno (0.75) — cove setting reduces swell
0.80-0.99 Slightly reduced Melkbosstrand, Sunset Beach
1.00 Neutral Open beach, swell passes through unchanged
1.01-1.20 Amplified Haakgat (1.10) — reef focus
1.21-1.40 Strong amplification Dungeons (1.35) — shallow reef concentrates energy

So on a 1.46m offshore swell, Dungeons starts at 1.46 x 1.35 = 1.97m, while Llandudno starts at 1.46 x 0.75 = 1.10m. Already very different — and we've only applied one factor.

2. Swell Direction Quality (0.30 - 1.0)

Every spot has a sweet spot for swell direction — the compass bearing from which incoming swell produces the best waves. Dungeons loves swell from 225 degrees (southwest). Llandudno prefers 220 degrees.

We measure the angle between the actual swell direction and the spot's optimal direction:

Angle Difference Factor Meaning
0-15 degrees 1.00 Perfect angle
16-30 degrees 0.90 Slightly off
31-45 degrees 0.75 Noticeably off
46-60 degrees 0.60 Poor angle
61-90 degrees 0.45 Very poor
90+ degrees 0.30 Wrong direction entirely

Example: With swell from 209 degrees, Dungeons (optimal 225 degrees) has a 16-degree difference — factor 0.90. Llandudno (optimal 220 degrees) has an 11-degree difference — factor 1.00. The swell angle slightly favours Llandudno here.

3. Soft Refraction (0.65 - 1.0)

This is different from direction quality, and the distinction matters.

Direction quality asks: "Is the swell coming from the best direction for this spot?"

Refraction asks: "At what angle does the swell physically hit the beach face?"

A spot can have its optimal swell from the southwest but face due west — these are different measurements serving different purposes.

The physics: When waves approach a beach at an angle rather than head-on, they refract (bend) as they enter shallower water. The classic formula from coastal engineering is Snell's law adapted for water waves, giving a refraction coefficient:

Kr = sqrt(cos(approach_angle))

But here's the catch — that formula assumes you have detailed bathymetry data (the full underwater terrain map). We don't. Without bathymetry, pure Snell's law over-penalises oblique swells because it can't account for wave wrapping and diffraction around headlands and underwater features.

Our solution is a blended approach — 50% physics, 50% neutral, with a floor of 0.65:

Kr_soft = max(0.5 x sqrt(cos(approach_angle)) + 0.5, 0.65)
Approach Angle Pure Physics (Kr) Our Soft Kr
0 degrees (head-on) 1.00 1.00
30 degrees 0.93 0.97
45 degrees 0.84 0.92
60 degrees 0.71 0.85
75 degrees 0.51 0.75
85 degrees 0.30 0.65 (floor)

Example: With swell from 209 degrees hitting Dungeons (faces 210 degrees), the approach angle is essentially 1 degree — nearly head-on. Refraction factor: ~1.0. But Llandudno faces 270 degrees — the same 209-degree swell hits at about a 61-degree angle. Refraction factor: ~0.85.

This is where physics makes a real difference in separating nearby spots.

4. Period Quality (0.70 - 1.0)

Not all swell periods are created equal — and different break types care about this differently.

The science: Wave power is proportional to both height squared and period: P = (rho x g^2 / 64 x pi) x H^2 x T. This is a well-established result in physical oceanography. It means a 1.5m swell at 14 seconds carries nearly twice the energy of the same 1.5m swell at 8 seconds.

But the practical surf implications go further. Long-period groundswell (10s+) originates from distant storms — it's been sorted and cleaned by thousands of kilometres of ocean travel, with shorter-period components dissipating along the way. Waves with periods above 13 seconds show very little energy dissipation over distance. This is why a 14-second swell from the Southern Ocean arrives at Cape Town as clean, powerful, well-organised lines — while an 8-second wind swell from a local storm arrives as messy, disorganised chop.

Reef breaks need those long, powerful swells to properly refract onto the shallow shelf and produce quality waves. Beach breaks, with their gradual sandy bottoms, are far more forgiving:

Break Type Minimum Period Sweet Spot Why
Reef 10s 12s+ Needs long-period groundswell to properly wrap onto shallow reef
Beach 6s 8s+ Gradual bottom works with shorter periods
Point 8s 10s+ Longer periods wrap more predictably around headlands
Rivermouth 7s 9s+ Moderate periods interact best with sandbar geometry

Example: On an 8.8-second swell, Dungeons (reef break, sweet spot 12s) gets a period quality of 0.70 — below the minimum threshold. The swell just doesn't have the energy to properly work the reef. Llandudno (beach break, sweet spot 8s) gets 1.0 — that 8.8-second period is above its sweet spot.

But flip the script: on a 14-second winter groundswell, Dungeons jumps to period quality 1.0 while Llandudno stays at 1.0. Now the reef's high exposure factor (1.35) makes it the clear winner. This matches real-world behaviour — reef breaks are the go-to spots on big groundswell days.

5. Tide Factor (0.85 - 1.05)

The tide matters, and how much it matters depends on the break type.

Each spot has a bestTide — the tide phase that produces the best waves. Reef breaks are the most sensitive: surf Dungeons (best tide: low) on a high tide and the wave reforms over the deep reef, losing its power. Beach breaks are the most forgiving — many work well on any tide.

Condition Factor
Best tide = "all" (any tide works) 1.00
Current tide matches best tide 1.05 (small bonus)
Mismatch — reef break 0.85 (significant penalty)
Mismatch — rivermouth 0.88
Mismatch — point break 0.90
Mismatch — beach break 0.95 (mild penalty)

The penalties are deliberately moderate — a mismatched tide doesn't mean zero waves, it means suboptimal waves.

Putting It All Together: A Real Example

Let's walk through a concrete scenario using real data. Conditions: 1.46m offshore swell, 8.8-second period, from 209 degrees, rising tide.

Both Dungeons and Llandudno receive identical raw data from Open-Meteo (same grid cell).

Dungeons (reef break)

Factor Value Calculation
Offshore height 1.46m Raw from API
Exposure 1.35 Reef amplification
Direction quality 0.90 16 degrees off optimal (225 vs 209)
Refraction ~1.00 Swell nearly head-on (faces 210)
Period quality 0.70 8.8s below reef minimum of 10s
Tide factor 0.85 Rising tide ("mid") vs best tide "low" = mismatch on reef

Result: 1.46 x 1.35 x 0.90 x 1.00 x 0.70 x 0.85 = 1.1m (rated OK)

Llandudno (beach break)

Factor Value Calculation
Offshore height 1.46m Raw from API
Exposure 0.75 Sheltered cove
Direction quality 1.00 11 degrees off optimal (220 vs 209) — within 15 degrees
Refraction ~0.85 61-degree approach angle (faces 270)
Period quality 1.00 8.8s above beach sweet spot of 8s
Tide factor 1.05 Rising tide ("mid") matches best tide "mid" — bonus!

Result: 1.46 x 0.75 x 1.00 x 0.85 x 1.00 x 1.05 = 1.0m (rated Good)

Same raw swell, different local predictions. Llandudno actually rates better than Dungeons on this particular swell — which makes sense: 8.8 seconds is too short for a heavy reef break, but works nicely for a beach break.

Now Flip It: Big Winter Groundswell Day

Conditions: 2.5m offshore swell, 14-second period, from 225 degrees (classic Cape winter), high tide.

Dungeons: 2.5 x 1.35 x 1.00 x 1.00 x 1.00 x 0.85 = 2.9m (rated Epic)

  • Perfect swell direction (225 = optimal), period quality 1.0 (14s >> 12s sweet spot), but tide mismatch (high vs best=low)

Llandudno: 2.5 x 0.75 x 1.00 x 0.92 x 1.00 x 1.00 = 1.7m (rated Good)

  • Perfect direction, but sheltered exposure and refraction penalty (225 degrees hits 270-facing beach at 45 degrees)

Now the reef break dominates — exactly what you'd expect on a big groundswell day. Dungeons is where Cape Town's big-wave crew heads when the Southern Ocean sends its heavy artillery.

The Science Behind the Numbers

For anyone who wants the deeper physics:

Wave energy flux (power per metre of wave crest) follows:

P = (rho x g^2) / (64 x pi) x H^2 x T

Where rho is water density (~1025 kg/m^3), g is gravity (9.81 m/s^2), H is significant wave height, and T is wave energy period. A 3m swell at 8 seconds delivers about 36 kilowatts per metre of wavefront. A 3m swell at 15 seconds delivers roughly 68 kW/m — nearly double the power at the same height, purely from the longer period.

This is why our period quality factor exists. A short-period swell might show the same height on a forecast, but it carries significantly less energy and produces less powerful, less organised waves — especially at spots that need that extra energy to properly break (like reefs).

Refraction follows from the same principle: as waves enter shallower water, their speed decreases. The nearshore portion of an obliquely-approaching wave slows before the offshore portion, causing the wave crest to bend toward the shore. The standard refraction coefficient from coastal engineering literature is Kr = sqrt(cos(theta)), where theta is the angle between the wave crest and the depth contours.

We use a softened version because the pure formula assumes parallel, uniform depth contours — which real coastlines don't have. Headlands, reefs, submarine canyons, and irregular bathymetry all cause wave diffraction, reflection, and focusing that the simple formula can't capture. Our 50/50 blend (half physics, half neutral) with a floor of 0.65 is a practical approximation that avoids over-penalising oblique swells while still capturing the real effect.

What's Next

This is version 2 of the algorithm. It's not perfect — no model is without detailed bathymetry data and real-time observations. But it does a solid job of differentiating nearby spots that would otherwise show identical forecasts.

Things we're exploring for future versions:

  • Buoy calibration — using NDBC and local buoy observations to compute rolling forecast bias and auto-correct predictions
  • Secondary swell — the secondary swell train is currently ignored in the AI layer; incorporating it would give a more complete picture of the sea state
  • Ocean current interaction — opposing currents steepen waves (increasing height), following currents flatten them; the data is already there, the model just doesn't use it yet
  • Machine learning correction — once we've accumulated enough forecast-vs-observation data, training a per-spot ML model is the ultimate goal

For now, the six-factor multiplicative model gives surfers something they didn't have before: a quick, glanceable answer to "what will the waves actually be like at my spot?"

And that's really all I wanted when I started this project — to know when to grab my board and go.

Surf more!


← All Articles