Visibility Distance Fields Are Deceptive: What vis_km Actually Measures and How to Use It Correctly

Most developers who pull vis_km from a weather API assume it’s a continuous, real-time sensor reading at their exact coordinates. It isn’t — and the gap between what the field implies and what it actually represents will bite you in specific, predictable ways depending on what you’re building.

Where vis_km Comes From

Visibility observations don’t come from a dense sensor grid. They come primarily from METAR reports at airports and a small number of manual surface observation stations. ICAO stations report prevailing visibility — defined as the greatest visibility value that encompasses at least half of the horizon circle, not the minimum in any single direction. So if three-quarters of the horizon is clear at 10km but there’s a fog bank to the northwest with 200m visibility, the reported figure is 10km. That fog bank doesn’t disappear from reality just because it didn’t make it into the number.

The WMO defines prevailing visibility this way deliberately. It’s designed to represent the dominant condition at an aerodrome, not the worst case — which makes sense for aviation operations and makes considerably less sense when you’re trying to flag dangerous driving conditions in that fog bank to the northwest.

The field in our API response is sourced from these METAR observations and the nearest-station logic we apply, including the composite scoring that accounts for elevation difference and station representativeness. But no amount of station-selection cleverness fixes the fundamental issue: a single observation point is being used to represent conditions at your requested coordinate, which may be several kilometers away and at a different elevation.

The Ceiling on the Number

Most METAR stations cap reported visibility at 10km (or sometimes 9,999 meters, depending on how the originating country encodes it). You’ll see vis_km: 10 even when actual visibility is 50km on a crystal-clear day. This matters if you’re distinguishing between merely-acceptable and exceptional visibility — photography timing apps, drone operations, certain outdoor activity recommenders. A value of 10 doesn’t tell you whether it’s a hazy 10 or a perfectly clear afternoon that just hit the reporting ceiling.

There’s no clean fix from the API side. One proxy: cross-reference with cloud cover, humidity, and aerosol-sensitive fields. High humidity plus low wind plus a clear condition code usually means you’re at the ceiling because conditions are genuinely good, not because a haze layer happens to sit exactly 10km out. That’s a heuristic, not a measurement.

Fog Detection Is Not What vis_km Was Built For

There’s a temptation to use low vis_km values as a fog detector. It works some of the time. But the field routinely misses radiation fog — the kind that forms overnight in a valley and burns off by mid-morning — because it typically forms after the last scheduled observation and dissipates before the next one. METAR reports are periodic, not continuous, and the observation you’re working with might be up to an hour old.

Better fog detection logic uses the dew point spread: when temp_c minus dewpoint_c drops below roughly 2°C, the air is close to saturation and fog becomes likely, especially overnight with light winds. Low vis_km combined with a condition code in the fog/mist range (our codes 248 and 260) confirms it. But either signal alone is unreliable. We covered this in more depth in the fog detection post — the short version is that vis_km should be a corroborating field, not the primary detector.

Sector Visibility and Runway Visual Range: What’s Missing

Aviation developers in particular should know that vis_km in an API response is not runway visual range (RVR). RVR is measured specifically along a runway centreline with transmissometers, reported in meters, and not present in standard METAR-derived JSON APIs — including ours. For Category I/II/III ILS approach minimums, you need RVR directly from ATIS or a dedicated aviation data source.

Sector visibility — visibility in specific quadrants of the compass — is encoded in some METAR strings when conditions vary significantly around the horizon, but it doesn’t propagate into a single vis_km field cleanly. If directional visibility matters to your use case (marine operations heading into a coastal fog bank, for example), a single scalar value won’t give you what you need.

vis_miles vs. vis_km: One Is Derived

The API returns both vis_km and vis_miles. Don’t treat these as independent observations — vis_miles is converted from vis_km. If you’re storing both and using consistency between them as a data-quality signal, you’ll always pass that check, because they’re the same number in two units. Not a gotcha most people hit, but it happens.

When vis_km Is Actually Reliable

It’s most reliable at well-instrumented airport locations in flat terrain with dense station networks — major airports in the Netherlands, the UK Midlands, or the US Midwest, for example. There, the nearest station is likely within a few kilometers of your requested coordinate, at a similar elevation, and the observation is automated and recent.

It’s least reliable in mountainous terrain (valley fog that doesn’t match ridgeline conditions), coastal areas where sea fog can be extremely local, and anywhere with sparse station networks where the nearest station might be 30–40km away. We apply elevation correction via lapse rate to temperature readings in those cases, but there’s no analogous physical model that translates visibility at a valley station to visibility at an elevated coordinate — fog and haze don’t scale with altitude the way temperature does. So we don’t pretend otherwise.

A Practical Rule

Use vis_km as a rough categorical signal — clear, reduced, poor — rather than a precise measurement. Bucket it: above 8km is effectively clear for most consumer use cases, 2–8km warrants a note, below 2km is operationally significant. Trying to distinguish 6.4km from 7.1km in application logic is treating the field as more precise than the underlying observation method supports.

If your use case genuinely requires high-precision or directional visibility — RVR for aviation, sector visibility for marine routing, real-time fog boundary mapping — you need dedicated sources beyond what a general-purpose weather API field provides. That’s not a limitation of any particular API; it’s a limitation of what the METAR network was designed to do.

A useful first check: pull the station metadata from the API response and look at the distance and elevation delta between that station and your target coordinate. If it’s more than 10km laterally or 200m vertically, treat vis_km as illustrative. At that point you’re not reading local conditions — you’re reading the nearest available approximation of them, which is a different thing.

Scroll to Top