RF Link Budget Calculator (LoRa, Wi-Fi, Microwave, Satellite) avatar

RF Link Budget Calculator (LoRa, Wi-Fi, Microwave, Satellite)

Pricing

Pay per event

Go to Apify Store
RF Link Budget Calculator (LoRa, Wi-Fi, Microwave, Satellite)

RF Link Budget Calculator (LoRa, Wi-Fi, Microwave, Satellite)

Radio link budgets from plain text: path loss (free space, two-ray, Hata, satellite), ITU-R rain and gas loss, received power, SNR, Eb/N0, fade margin, max range and Fresnel clearance. For AI agents.

Pricing

Pay per event

Rating

0.0

(0)

Developer

Jumble Mog

Jumble Mog

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Security

Limited permissions

Share

Will this radio link work? Describe it in one line and find out. Type LoRa SF12 at 868 MHz, 14 dBm, 2 dBi antennas, 15 km, rural or 5.8 GHz, 10 km, 23 dBm, 30 dBi dishes both ends, sensitivity -80 dBm, 99.99% at 40.4, -3.7. You get back:

  • The whole budget, step by step: transmit power, antenna gains, cable losses, EIRP, path loss, the weather losses, and the received power in dBm and watts.
  • The receiver side: the noise floor, SNR, C/N0, Eb/N0 and Shannon capacity. You can give a sensitivity or let the tool work it out from the noise figure, bandwidth and required SNR.
  • The verdict: the link margin, whether it keeps the fade margin you want (10 dB unless you say otherwise), and the transmit power that margin needs.
  • The range: how far the link reaches with that margin, and at bare sensitivity.
  • The clearance: the first Fresnel zone, the earth bulge, the height the path needs above obstacles, and the radio horizon for your antenna heights.
  • A chart: the budget as a waterfall, and the received power against distance with the sensitivity and margin lines.

Propagation models:

  • Free space (Friis, ITU-R P.525), the default.
  • Two-ray ground reflection, for low antennas over flat ground.
  • Log-distance with an exponent, for indoor and cluttered paths.
  • Okumura-Hata (150-1500 MHz) and COST-231 Hata (1500-2000 MHz) for urban, suburban and rural cells. These are picked by themselves when you name the environment.
  • Satellite slant paths for GEO, MEO and LEO: the slant range from the elevation and orbit, plus gases, clouds, rain and scintillation by ITU-R P.618.

Weather comes from the ITU-R models when it matters:

  • Atmospheric gases (ITU-R P.676) from 10 GHz, so 24, 60 and 80 GHz links carry their oxygen and water-vapour loss.
  • Rain for an availability such as 99.99%. On terrestrial paths it uses ITU-R P.530 with P.838, and the rain rate comes from the ITU-R P.837 world maps for your coordinates (or a rate you give).

It's made for:

  • IoT and LoRa/LoRaWAN/Meshtastic builders planning gateway coverage.
  • WISPs and network engineers sizing point-to-point microwave hops.
  • Ham radio operators, drone and RC pilots, and students.
  • Satellite ground-station planners.
  • AI agents that need a real dB answer instead of a guess.

A LoRa SF12 link at 868 MHz over 15 km rural, computed by this Actor: the budget waterfall from 14 dBm to -119.8 dBm received, and the received power by distance crossing the -137 dBm sensitivity at 46 km and the 10 dB margin line at 24 km

How to use it

  1. Write Links, one per line, such as 2.4 GHz, 3 km, 20 dBm, 12 dBi antennas, sensitivity -85 dBm. The form has examples.
  2. Optionally set a Default fade margin, Default propagation model or Default noise figure.
  3. Click Start. Each link is a row in the results, with its summary, chart and report.

A line can hold any of these, in any order:

  • Frequency: 868 MHz, 5.8 GHz.
  • Distance: 15 km, 300 m, 2 mi. Satellite links can give the elevation instead.
  • Power: 14 dBm, 30 W, 500 mW, or EIRP 52 dBW.
  • Antennas:
    • Gains: 2 dBi antennas (both ends), tx antenna 12 dBi, rx 3 dBi.
    • Dishes: 0.6 m dish, 30 dBi dishes both ends.
  • Losses: 1 dB cable loss each end, 3 dB body loss, 10 dB foliage loss.
  • Heights: gateway height 30 m, node height 2 m, base station 50 m, mobile 1.5 m.
  • Model: urban, suburban, rural, indoor, two-ray, path loss exponent 3, free space.
  • Receiver:
    • sensitivity -110 dBm.
    • Or NF 6 dB, 125 kHz bandwidth and SNR 10 dB.
    • Or Eb/N0 6 dB at 40 Mbps.
    • Or a LoRa spreading factor: SF7 to SF12 (125 kHz and the Semtech SNR limits).
  • Margin: 15 dB fade margin.
  • Weather and place: 99.99% availability, at 40.4, -3.7, 42 mm/h, vertical polarization.
  • Satellite: GEO, LEO 550 km, elevation 30°, downlink, G/T 12 dB/K.

Objects work too, with the same fields named; see Input.

Examples

All of these ran on this Actor; the numbers are from the results.

LinkResult
LoRa SF12 at 868 MHz, 14 dBm, 2 dBi antennas, 15 km, rural, gateway height 30 m, node height 2 mHata rural path loss 137.8 dB, received -119.8 dBm against a -137 dBm sensitivity: 17.2 dB margin. 24 km range with a 10 dB margin, 46 km at bare sensitivity
5.8 GHz point-to-point, 10 km, 23 dBm, 30 dBi dishes both ends, 1 dB cable loss each end, sensitivity -80 dBm, tower height 25 m, 99.99% availability at 40.4, -3.7EIRP 52 dBm, 0.58 dB of rain at 99.99% in Madrid, received -47.3 dBm, 32.7 dB margin. Line of sight ends at 41 km for 25 m towers
12 GHz GEO downlink, EIRP 52 dBW, 0.6 m dish, elevation 30°, at 51.5, -0.1, 99.9%, 27 MHz bandwidth, noise figure 1 dB, Eb/N0 6 dB at 40 Mbps38,600 km slant range, 205.8 dB free-space loss plus 2.3 dB of gases, clouds, rain and scintillation in London. Eb/N0 10.8 dB, 4.8 dB margin
900 MHz, 30 W, base station 50 m, mobile 1.5 m, 8 km, urban, 15 dBi tx antenna, 0 dBi rx antenna, sensitivity -104 dBmOkumura-Hata urban loss 153.8 dB, 9.9 dB margin, 7.96 km range with a 10 dB margin
60 GHz, 1 km, 10 dBm, 38 dBi, sensitivity -65 dBm14.8 dB of oxygen absorption on top of 128 dB free-space loss, 8.2 dB margin
433 MHz, 10 mW, 2 km, two-ray, tx height 3 m, rx height 1 m, NF 6 dB, 25 kHz bandwidth, SNR 10 dBTwo-ray loss 122.5 dB (31 dB over free space), noise floor -124 dBm, SNR 11.5 dB, 1.5 dB margin

The tests check that:

  • Free-space loss matches 32.45 + 20 log f(MHz) + 20 log d(km).
  • Okumura-Hata matches the hand calculation, and two-ray matches the plane-earth formula past the crossover.
  • The noise floor is -174 dBm/Hz at 290 K, and LoRa sensitivities match Semtech's (-137 dBm at SF12, -124.5 dBm at SF7).
  • Dish gain, the Fresnel radius (17.32 √(d/4f)), the 4/3-earth radio horizon and the slant range match their formulas.
  • Rain and oxygen losses fall in their known ranges.
  • Range and required power follow from the margin.

How-to examples

Each example is a complete input; the results are from runs of the Actor (also listed under Examples).

{"links": ["LoRa SF12 at 868 MHz, 14 dBm, 2 dBi antennas, 15 km, rural, gateway height 30 m, node height 2 m"]}

Result: Hata rural path loss 137.8 dB, received -119.8 dBm against a -137 dBm sensitivity: a 17.2 dB margin. The range is 24 km with a 10 dB margin, 46 km at bare sensitivity.

{"links": ["5.8 GHz point-to-point, 10 km, 23 dBm, 30 dBi dishes both ends, 1 dB cable loss each end, sensitivity -80 dBm, tower height 25 m, 99.99% availability at 40.4, -3.7"]}

Result: EIRP 52 dBm, 0.58 dB of rain at 99.99% in Madrid, received -47.3 dBm and a 32.7 dB margin. Line of sight ends at 41 km for 25 m towers.

{"links": ["12 GHz GEO downlink, EIRP 52 dBW, 0.6 m dish, elevation 30°, at 51.5, -0.1, 99.9%, 27 MHz bandwidth, noise figure 1 dB, Eb/N0 6 dB at 40 Mbps"]}

Result: 38,600 km slant range, 205.8 dB free-space loss plus 2.3 dB of gases, clouds, rain and scintillation in London; Eb/N0 10.8 dB, a 4.8 dB margin.

Add this Actor to the Apify MCP server with https://mcp.apify.com/?tools=jumblemog/rf-link-budget-calculator. The agent describes the link in one line and answers with the path loss, received power, margin and range.

FAQ

Which propagation models does it use? Free space, two-ray, log-distance, Okumura-Hata, COST 231 and satellite paths, picked from the line or set with model; the Hata models never go below free space.

Does it include rain and atmospheric loss? Yes, by ITU-R: gases by P.676, terrestrial rain by P.530 with the P.837 rain rate at your coordinates, and satellite paths by P.618.

Does it know LoRa sensitivities? Yes. Give SF7 to SF12 and it uses 125 kHz and Semtech's SNR limits (-137 dBm at SF12, -124.5 dBm at SF7).

Does it check Fresnel clearance? Yes: the first Fresnel zone and earth bulge mid-path with k = 4/3, and the radio horizon from both antenna heights.

Input

FieldWhat it is
linksLinks, as text lines or objects.
fadeMargin, model, noiseFigureDefaults for links that don't give them.
chartsDraw charts (default on).

A link as an object takes:

  • Radio: frequency; distance (a number is km); txPower or eirp.
  • Antennas: txGain, rxGain or antennaGain (both ends); txDish, rxDish or dish (diameter, 60% efficiency unless you give dishEfficiency).
  • Losses: txLoss, rxLoss or cableLoss (each end); otherLosses.
  • Path: model (free-space, two-ray, log-distance, hata, cost231, satellite); environment (urban, dense urban, suburban, rural, indoor); pathLossExponent; txHeight, rxHeight (m); kFactor (default 4/3).
  • Receiver:
    • sensitivity;
    • or noiseFigure, bandwidth and requiredSnr;
    • or requiredEbN0 and dataRate;
    • or loraSf.
    • Also antennaTemperature and gOverT.
  • Margin: fadeMargin (default 10 dB).
  • Weather: availability or timePercentage; latitude, longitude; rainRate (mm/h at 0.01%); polarization; gases, humidity, temperature, pressure.
  • Satellite: elevation; orbit (GEO, MEO, LEO or an altitude); direction (downlink uses a 50 K sky temperature).
  • Other: title, and text (a line to start from, which the other fields override).

Output

One dataset item per link, also saved together in the run's OUTPUT record:

{
"request": 1, "status": "ok", "type": "link",
"title": "LoRa SF12 868 MHz link over 15 km",
"summary": "LoRa SF12 868 MHz link over 15 km: EIRP 16 dBm, path loss 137.8 dB, received -119.8 dBm, SNR -2.8 dB; margin 17.2 dB, which closes with 7.2 dB to spare over the 10 dB fade margin wanted. Range with that margin: 24 km.",
"link": {"frequencyMHz": 868.0, "wavelength": 0.3454, "distanceKm": 15.0, "model": "hata", "environment": "rural",
"txHeight": 30.0, "rxHeight": 2.0},
"budget": {"txPower": 14.0, "txAntennaGain": 2.0, "eirp": 16.0, "pathLoss": 137.8, "freeSpaceLoss": 114.74,
"gases": 0.0, "rain": 0.0, "rxAntennaGain": 2.0, "totalPathLoss": 137.8, "receivedPower": -119.8},
"receiver": {"sensitivity": -137.01, "sensitivityBasis": "noise floor + required SNR", "noiseFloor": -117.01,
"bandwidth": 125000.0, "snr": -2.8, "requiredSnr": -20.0, "cn0": 48.17, "loraSpreadingFactor": 12},
"margin": {"linkMargin": 17.2, "fadeMarginTarget": 10.0, "closes": true, "requiredTxPower": 6.8,
"maxRangeKm": 24.02, "rangeAtSensitivityKm": 46.18, "lineOfSightLimitKm": 28.41},
"geometry": {"fresnelRadius": 35.99, "clearance60": 21.59, "earthBulge": 3.31, "clearanceAboveObstacles": 24.9,
"radioHorizonKm": 28.41, "beyondHorizon": false},
"imageUrl": "https://api.apify.com/v2/key-value-stores/.../records/001-....png"
}

Powers are in dBm, gains in dBi, losses in dB, distances in km and heights in m (see unitLabels). For satellite links geometry holds the elevation, slant range and orbit altitude. A link that can't be computed has "status": "failed" and the reason in error, and isn't billed.

How it works

  1. Reading the link: the line is split into its parts, and units are converted (W to dBm, miles to meters, dish diameter to gain).
  2. Path loss by the model, never below free space for the Hata models.
  3. Weather:
    • Gases by ITU-R P.676 from 10 GHz.
    • Terrestrial rain by ITU-R P.530 for the time percentage, with P.838 specific attenuation and the P.837 rain rate at your coordinates.
    • Satellite paths by ITU-R P.618: gases, clouds (P.840), rain and scintillation. All of these use the itur library.
  4. Received power = EIRP − losses + receive gain − receive cable loss.
  5. Noise floor = k·T·B, where T is the antenna temperature plus 290 K × (F − 1). The sensitivity is that floor plus the required SNR, or the value you give.
  6. Range: the distance where the received power meets sensitivity plus the fade margin, found by root-finding on the same model with the weather recomputed at each distance.
  7. Clearance: the first Fresnel zone and earth bulge mid-path (k = 4/3), and the radio horizon from both antenna heights.
  8. Charts are drawn with Vega-Lite and rendered with vl-convert.

Pricing

You pay one low price per link, at the price shown on this page. It includes the chart and the report. Links that can't be computed are never charged. If you set a maximum cost per run, the Actor stops before a link that wouldn't fit.

Speed

Each link takes a few milliseconds plus its chart. A link with ITU-R weather takes up to about a second more, the first time the maps load. A run through the API answers in about 10 to 15 seconds, including the cloud container starting.

Tips and limits

  • These are planning numbers. Models give median losses. They don't see your terrain, buildings or trees, so leave margin. Hata in particular is only fitted for 1-20 km and 30-200 m base stations, and the result warns when you're outside that range.
  • Line of sight: give antenna heights to have the radio horizon and Fresnel clearance checked. Without them, the horizon assumes 10 m at both ends and no clearance warning is raised.
  • Not included: terrain profiles and diffraction over real obstacles, multipath fading statistics, interference, and the satellite's own transponder noise (C/N here is the single hop you describe).
  • Rain needs coordinates or a rain rate; availability is 95% to 99.999%.
  • Limits: 500 links per run.

For AI agents and developers

This Actor works with the Apify MCP server, so AI agents can call it as a tool. Pass links as plain text and read summary, margin.linkMargin, margin.closes, margin.maxRangeKm and budget.receivedPower. A direct API call that waits for the answer:

curl -X POST "https://api.apify.com/v2/acts/jumblemog~rf-link-budget-calculator/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"links": ["LoRa SF10 at 915 MHz, 20 dBm, 3 dBi antennas, 8 km, suburban, gateway height 40 m"]}'

run-sync instead returns the run's OUTPUT: the status, the counts and every result as JSON.

In Python, with the apify-client package:

from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("jumblemog/rf-link-budget-calculator").call(run_input={
"links": [{"frequency": "24 GHz", "distance": 3, "txPower": "10 dBm", "antennaGain": "34 dBi",
"sensitivity": "-70 dBm", "availability": "99.99%", "latitude": 1.35, "longitude": 103.8}],
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["summary"])

Credits

  • Weather models: ITU-Rpy (MIT) by Iñigo del Portillo, implementing ITU-R P.453, P.530, P.618, P.676, P.836, P.837, P.838, P.839 and P.840.
  • Root-finding: SciPy (BSD-3-Clause).
  • Charts: Vega-Lite and vl-convert (BSD-3-Clause), with the Inter font (SIL Open Font License).
  • Models: Friis (1946); Hata, Empirical formula for propagation loss in land mobile radio services (1980); COST 231 final report (1999); ITU-R P.525; LoRa SNR limits from the Semtech SX1276 datasheet.