# readsb: the ADS-B decoder behind a lot of global flight maps

> readsb is a C program that decodes ADS-B transmissions from an RTL-SDR dongle and pushes the results out in the beast format. This fork of the dump1090 family is the decoder half of several large aircraft tracking sites, and its distinguishing work is in the network connectors, the optional receiver identifier tracking, and writing flight traces to disk for a global map.

**wiedehopf/readsb** — ADS-B decoder swiss knife

- Repository: https://github.com/wiedehopf/readsb
- Stars: 696 · Forks: 140
- Language: C
- License: NOASSERTION
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/wiedehopf-readsb

## Five generations of a decoder

readsb is a detached fork of the Mictronics project of the same name, and the credits section at the top of the readme is a genealogy of the whole thing.

The original dump1090 was written by antirez. Malcom Robb worked on his fork of it. Mutability forked that into dump1090-mutability and then into dump1090-fa. Mictronics took dump1090-fa and produced readsb. And this project is a further fork of the Mictronics readsb.

That chain matters more than a list of names, because it explains the shape of the code. The repository is a large flat set of C files at the top level, one per subsystem, with names that carry the history: the aircraft table, the message converters, the CPR position decoding, the CRC checks, the network input and output, the JSON output, the mode A and mode C decoders, the 2400 MHz demodulator, the ICAO filter, the magnetic and geometric helpers, the globe index, and the interactive mode.

The readme is equally direct about expectations. It is continually under development, and it says to expect bugs, segfaults, and all the good stuff. There is a no warranty notice, with the software provided by the copyright holders and contributors as is.

The default branch is dev rather than master, the last push was on 2026-10-10, and there are no tagged releases, which fits a project whose build produces its own version string from the version file and the git description at compile time.

The two extra readme files matter for anyone integrating with it. One documents the JSON format used for the aircraft database, and one documents the API. The JSON file is what a map server consumes, and the API is what a web interface calls.

## The network connectors, in both directions

The push server support is the part of readsb that turns it from a radio program into a network service, and the mechanism is a network connector.

A connector is a host, a port, and a mode. The two basic modes are sending beast data to a listening server and receiving beast data from one.

```
--net-connector 192.168.2.22,30004,beast_out
```

```
--net-connector 192.168.2.28,30005,beast_in
```

The first pushes the decoded traffic to a server that is listening, which is how a receiver with an internet connection feeds a map. The second pulls from a server instead of from a local radio, which is how a receiver that has no antenna of its own gets its data from a site that does.

The beast format is the wire format, and the readme makes a point that matters for compatibility: the output of the reducing mode is normal beast messages, compatible with every program able to receive beast messages. That is the property that lets a small receiver join a large aggregator without either side needing to know anything about the other.

Building the network layer into the program rather than into a wrapper script is what makes the fork interesting. The beast data carries the raw frames, and the program that reduces them can do so without losing the original, which is why the same binary can both serve a map and feed another decoder.

## BeastReduce, and the receiver identifier problem

The BeastReduce output exists for a specific reason, and the readme explains it in one paragraph.

It selectively forwards beast messages if the received data has not been forwarded in the last 125 milliseconds, or the interval set with the net beast reduce interval option. Data that is not related to the physical state of an aircraft is only forwarded every 500 milliseconds, which is four times that interval. And the messages it produces are ordinary beast messages, so they work with any program that understands them.

The effect is a flood reduction at the source rather than at the receiver. A receiver in a busy area sees the same aircraft many times, and forwarding every frame is what fills a feed with duplicates. Reducing at the sender means the aggregator receives less and every receiver can use the same mode.

The connection to a large aggregator is made with the reduce plus variant, which adds a receiver identifier.

```
--net-connector=feed.airplanes.live,30004,beast_reduce_plus_out,uuid=0033062d-e17e-4389-91a9-79ebb967fb4c
```

The identifier is optional, and the readme explains the fallback chain: if none is given on the command line, the one from the uuid file option is used, and if that file is not present then no identifier is sent at all. The reduce variant without the plus never sends one.

On the other side, the aggregator switches on the receiver identifier and ingest options, and the readme says the pair is made to work with the reduce plus output.

That is the piece that makes a global map possible. When a map draws an aircraft, it wants to know which receivers contributed the position, and with a receiver identifier per connection the server can attribute each fix to a station and show how many stations agree. The build options in the make file exist for exactly this: an option to keep the last receivers seen with each aircraft, which increases memory use but allows the API to be filtered by identifier, and an option that implies the first and prints all identifiers an aircraft was heard from into the JSON output.

There is a cost to the third option, and it is documented: tracking identifiers per position invalidates the persistent state, so changing it means losing up to 24 hours of historic traces.

## Building it, and the options that cost CPU

There are three ways to get the program, and the readme recommends a script for the automatic route, with a separate wiki page for building from source and another for a Raspberry Pi lite install, plus a section for macOS.

The Debian package route is spelled out in full, because it is the one most people take.

```
sudo apt update
sudo apt install --no-install-recommends --no-install-suggests -y \
    git build-essential debhelper libusb-1.0-0-dev pkg-config fakeroot \
    libncurses-dev zlib1g-dev libzstd-dev librtlsdr-dev help2man
git clone --depth 20 https://github.com/wiedehopf/readsb.git
cd readsb
export DEB_BUILD_OPTIONS=noddebs
rm -f ../readsb_*.deb
dpkg-buildpackage -b -ui -uc -us --build-profiles=rtlsdr
sudo dpkg -i ../readsb_*.deb
```

The build profiles are the interesting part. Without a profile the package has no receiver library dependencies at all, the profile for rtl-sdr adds that support, and a third profile builds with all of the supported receivers.

Building by hand is a single make, which by default produces a binary with no specific library support, and the readme is clear that the binaries land in the source directory and that installing them and starting them is up to you.

The compile flags are the ones that matter on a small computer. The RTLSDR variable switches on rtl-sdr support and the dependency on the library, and the OPTIMIZE variable sets the compiler flags. On a 32 bit Raspberry Pi, the readme suggests a specific pair of flags for the older processor cores, and in general it suggests reducing the hash table size and letting the compiler target the host.

```
make AIRCRAFT_HASH_BITS=11 RTLSDR=yes OPTIMIZE="-O3 -march=native"
```

The readme is honest about how much this buys. The difference between the fastest optimisation level and the default is likely very minimal, and letting the compiler target the native architecture usually makes little difference, though it might, so it is worth a try.

After installation, the service options, the device type, and the network ports are set by editing one file in the system default directory.

## Autogain, and the bias tee

Gain control is the part of an RTL-SDR setup that most often goes wrong, and readsb handles it in software.

For rtl-sdr devices a software gain algorithm is the default, and it is optimized for ADS-B. On the command line it is activated with the auto gain option, and it is silent by default, so a receiver that is working says nothing about it. A verbose variant turns on log messages for the gain changes, which is what you want when a station is dropping frames.

The internals can be reached with a longer form of the option, taking the lowest gain and three thresholds.

```
--gain=auto-verbose,<lowestGain>,<noiseLowThreshold>,<noiseHighThreshold>,<loudThreshold>
```

And the defaults are given explicitly, so you can see the shape of the numbers before changing them.

```
--gain=auto-verbose,0,34,36,243
```

The thresholds are in a range from 0 to 256, and the readme is candid that adjusting them requires some understanding of how the algorithm works, and that one option is to move the noise thresholds and watch the log. It also says there should be no need to tweak the parameters.

Separately, there is a utility for the rtl-sdr bias tee, and the readme notes that it can be used independently of readsb, with a link to its own wiki page. The bias tee is the piece of hardware that powers the antenna amplifier, and on a dongle without it the amplifier never turns on and the receiver hears nothing.

So the hardware path has two failure modes and the project documents both: the software gain, which the decoder handles for you, and the bias tee, which is a separate utility because it is a property of the dongle rather than of the decoder.

## The global map use case, and what the traces cost you

The readme names the main use of this fork, which is being the backend of a global map of aircraft, used together with the tar1090 project and some extra options to cope with the number of aircraft, and to record a history of flight paths.

Several public sites run on it, including a dot lol address and three globe addresses for airplanes live, a Finnish site, and the ADS-B Exchange globe. Other projects use the software, one of them a container image for a reader and one of them a site that uses it indirectly through such a container, and a short list of projects consume the data it generates.

The trace history is the feature that makes those maps possible, and it is the one with a cost. The readme warns that saving traces will generate several thousand files a day and can use significant amounts of disk space depending on the data source.

The options that turn it on are in the decoder options, and they take a directory and an interval.

```
--write-globe-history /var/globe_history --heatmap 30
```

The heatmap interval is 30 seconds by default, and it can be reduced for finer time resolution, though the readme says it would not recommend going below 5 seconds. Separately, a JSON trace interval of 0.1 adds every position received to the traces, which is the maximum resolution setting.

Aggregators will generally also use the option that writes a JSON globe index, and the readme notes that this is not necessary if you do not have more than 500 concurrent planes.

The directory has to exist and be writable by the user the service runs as, and the readme gives the two commands that take care of it, creating the directory and giving it to the readsb user. That is the last piece of setup, and it is the one that produces a permission error if it is skipped.

## Conclusion

readsb fits a radio hobbyist running a small ADS-B receiver that feeds a personal map, or an aggregator operator who needs the receiver identifier tracked per aircraft so that contributions from many stations can be attributed. It does not fit a project that wants a supported product, because the readme says plainly that it is under continual development and comes with no warranty, and it does not fit a machine with a small disk, because the trace history writes thousands of files a day. Verify first that your dongle is supported and that the bias tee is fitted if the dongle needs one, that the network connector you want is available in your build, and that the receiver identifier options are switched on in the build you install, since the default build does not include them.

## FAQ

### What is readsb and where does it come from?

It is a C program that decodes ADS-B transmissions, and this project is a detached fork of the Mictronics readsb, which was itself a fork of dump1090-fa, which came from dump1090-mutability, from Malcom Robb's fork of antirez's original dump1090. The readme states that it is under continual development and comes with no warranty.

### How do I send decoded aircraft data to a server with readsb?

With a network connector that names the host, the port, and the mode. Sending beast data out uses the beast_out mode, and receiving it uses beast_in, so a receiver with no antenna of its own can take its data from a site that has one.

### What does the BeastReduce output do?

It selectively forwards beast messages when the received data has not been forwarded in the last 125 milliseconds, and it forwards data that is not about the physical state of an aircraft only every 500 milliseconds. The output is ordinary beast messages, so it works with any program that receives that format, and the reduce plus variant adds a receiver identifier for aggregators.

### How do I build readsb on Debian?

Install the build dependencies, clone the repository, and run the package build command with the rtlsdr build profile, then install the resulting package. Without a profile the package has no receiver library dependencies, and a third profile builds with all of the supported receivers. Building by hand is a single make, which by default produces a binary with no specific library support.

### How do I make readsb record flight paths for a map?

Add the globe history option with a directory and a heatmap interval to the decoder options, and create that directory owned by the readsb user. The readme warns that this generates several thousand files a day and can use significant disk space, and that the heatmap interval should not go below 5 seconds.

## Sources

- [Issues](https://github.com/wiedehopf/readsb/issues)
- [README](https://github.com/wiedehopf/readsb/blob/dev/README.md)
- [wiedehopf/readsb on GitHub](https://github.com/wiedehopf/readsb)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/wiedehopf-readsb
