Why not just use a weather API's fog field?
Most weather APIs expose a visibility field or a fog boolean in their current-conditions endpoint. The problem is that these fields describe fog at a specific point — usually an airport ASOS station — and coastal fog is highly localized. Fog that's sitting over the water half a mile offshore may not register at the nearest airport, which is typically inland enough to miss it.
What I wanted was something that answered: "Is there fog at this specific coastal coordinate right now, and when will the sun burn it off?" The closest existing tool I found was the NOAA Marine Point Forecast, but it's text-only, covers only U.S. waters, and updates every 12 hours. Not usable for a morning-of decision.
So I built a scoring function from ingredients I could assemble from two freely available APIs: Open-Meteo Marine for atmospheric data, and NOAA NDBC buoy feeds for sea-surface temperature near the coast.
The four factors
1. Dew-point spread (T − Td)
This is the most important single predictor. Fog forms when air reaches saturation, which happens when the dew point equals the air temperature. A spread of less than 2°C means you're within reach of fog; a spread of 0°C means it's already foggy or raining.
I get the 2m air temperature and dew point from Open-Meteo's hourly marine variables. The spread contributes up to 4 points to the fog score.
2. Marine boundary layer height
The marine boundary layer (MBL) is the lowest part of the atmosphere directly influenced by the ocean surface. When the MBL is shallow — say, below 300m — any moisture in it has nowhere to go, so it tends to saturate and form low cloud or fog.
Open-Meteo's boundary_layer_height variable is a decent proxy for MBL height at coastal points. I normalize it against a 400m threshold: heights below 400m contribute up to 3 points.
3. Coastal upwelling
This one surprised me when I added it. Along the California coast (and other eastern-boundary upwelling zones), northerly winds push warm surface water offshore and allow cold water from depth to rise. This cold surface layer chills the air above it, accelerating saturation.
I use SST from NDBC buoys as a proxy for upwelling intensity. When the buoy SST at the nearest NDBC station is more than 3°C cooler than the modeled surface temperature in Open-Meteo (which doesn't fully capture upwelling), I add up to 2 bonus points to the fog score.
This is the least robust part of the model. NDBC coverage is sparse — there are only a few dozen active buoys on the U.S. West Coast — so this factor only applies within about 80km of a buoy. If you're in an area with no nearby buoy, the upwelling term is skipped and the maximum score is 7 rather than 10.
4. Wind speed and direction
Light onshore flow at night is a fog factory on west-facing coasts. Wind speed under 8 kn from the ocean quadrant (roughly 180°–360° on the U.S. West Coast) combined with low dew-point spread is one of the strongest fog signatures. I add 1 point for favorable wind direction and another for speed under 8 kn.
Strong onshore wind actually disperses fog by mixing the boundary layer. So there's a nonlinear penalty for speeds above 18 kn even when other factors look favorable.
Calibration
I calibrated the weights against three months (November 2025 – January 2026) of hourly METAR observations from SFO, OAK, HMB, and MRY. Fog was defined as visibility below 5/8 statute miles with low cloud or obscuration. I scored each hour with the model and compared against the METAR binary.
At a threshold of score ≥ 5 = fog predicted, the model achieves roughly 71% precision and 68% recall on the test set. That's not great by machine learning standards, but it's reasonable for a four-factor heuristic that doesn't look at numerical weather model output. The main failure mode is fog that forms quickly due to cold ocean advection — the model under-scores these events because the dew-point spread looks fine at the hourly mark before the fog arrives.
Burn-off time
The burn-off estimate works differently: it doesn't use the scoring function. Instead, it looks for the first hour where solar zenith angle drops below 55° (i.e., the sun is high enough to start dissipating the inversion) while the dew-point spread is rising at a rate of at least 0.3°C/hour. In practice this tends to be an hour or two after solar noon at coastal sites — or never if the marine layer is thick enough.
I'm not confident enough in this estimate to mark it as anything other than approximate. The displayed time always shows "~" in front of it for that reason. If you know of a better open-data approach for burn-off prediction, I'd be genuinely interested — open an issue.
Limitations
The model is calibrated for the U.S. West Coast. It probably works reasonably well for similar upwelling coasts (Oregon, Washington, Baja, parts of Chile), but I haven't tested it there. It almost certainly gives poor results for:
- East Coast and Gulf Coast sites, where fog dynamics are different (advection fog from warm ocean over colder land in spring, rather than MBL fog from cold ocean)
- Inland sites more than a few kilometers from the shore
- High-latitude sites where the boundary layer physics differ substantially
I'd rather the tool be honest about its scope than silently give bad answers. If you're outside the model's calibration range, Zeemist will show a warning in the fog output header.