Run the EDR signals demo

The signals demo is the fastest way to see EDR’s store-and-forward, multi-tier relay, and at-least-once delivery in one topology: two edges replicating up through a regional relay to a central hub, entirely in Docker.

The demo is a self-contained bundle that you unzip and run with Docker Compose—see Run it.

  1. How EDR sources data
  2. The topology
  3. The three config shapes
  4. Run it
  5. What this demonstrates
  6. Next

If you haven’t set up EDR yet, start with Get started with EDR, which walks through a simpler two-node case on one host.

How EDR sources data

EDR reads the files that InfluxDB 3 Enterprise’s storage engine writes. For what WAL, PT, gen0, cv2, and .ptsnap mean, see Storage engine terms.

Primary source: WAL files

InfluxDB 3 Enterprise, on the upgraded storage engine (the default for new clusters on 3.11+; on 3.10.x enable it with --upgrade-pacha-tree), flushes incoming data to write-ahead log (WAL) files on the object store roughly every second—the flush interval, sooner under heavy ingest as the buffer fills. Snapshots later roll these already-persisted WAL files up into compacted files. EDR’s WAL replicator discovers new files as they appear and ships them downstream.

Secondary source: compacted PT files

The upgraded storage engine promotes WAL data through compaction levels:

  1. A write arrives.
  2. The storage engine creates a WAL file.
  3. A snapshot creates a gen0 PT file from the WAL data and records it in a .ptsnap manifest.
  4. Compaction progressively promotes gen0 data to cv2 files at level L1 and higher.
  5. Retention expiry eventually deletes the data.

After a WAL file is snapshotted, it becomes eligible for deletion. If EDR was down or disconnected when that happened, the WAL file might be gone, but the data still exists in gen0 or a higher compaction level (cv2 files). Historic fill and gap fill recover data from these files. For more information, see Historic fill and gap fill and Size WAL retention, which covers sizing the InfluxDB flag that governs this recovery window and the trade-offs of raising it.

The topology

Two edges replicate up through a regional relay to a central hub, entirely in Docker.

flowchart LR Mumbai["Mumbai\nupstream · source\nInfluxDB 3 + EDR"] -- EDR --> Singapore Chennai["Chennai\nupstream · source\nInfluxDB 3 + EDR"] -- EDR --> Singapore Singapore["Singapore\nregional · relay\nreceives + forwards"] -- EDR --> London["London\ndownstream · sink\nInfluxDB 3 + EDR"]

Four nodes, each a pair of containers—an InfluxDB 3 Enterprise instance and an EDR agent beside it. The three roles are the only three an EDR agent ever takes:

NodeRoleWhat its config has
mumbai, chennaiupstream-only—a pure sourcea downstream: block (where it sends)
singaporeregional relay—receives and forwardsboth upstreams: and downstream:
londondownstream-only—a pure sinkan upstreams: list (who sends to it)

A fifth container, the dashboard, generates the test signals, queries every tier, serves the UI, and runs the channel relay. It is demo scaffolding, not part of EDR.

The three config shapes

Every EDR agent uses one of these three shapes. The auth_token on each sender’s downstream matches an upstreams entry on the receiver—that pairing is how a receiver knows who connected.

Edge (upstream-only)—mumbai (Chennai is identical with its own name and token):

name: mumbai
downstream:
  name: singapore
  address: http://singapore-edr:9090    # the next hop's EDR --listen
  auth_token: mumbai-auth               # token-store key
  historic_fill: { mode: none }         # live-only for the demo

Regional relay—singapore receives from both edges, forwards to the hub:

name: singapore
upstreams:
  - { name: mumbai,  auth_token: mumbai-auth,  write_token: singapore-token }
  - { name: chennai, auth_token: chennai-auth, write_token: singapore-token }
downstream:
  name: london
  address: http://london-edr:9090
  auth_token: singapore-auth
  historic_fill: { mode: none }

Hub (downstream-only)—london, the sink:

name: london
upstreams:
  - { name: singapore, auth_token: singapore-auth, write_token: london-token }

Every EDR deployment composes these three shapes into a tree, however large. For a two-node version, see Get started with EDR.

The dashboard relay is demo-only

Above, each sender’s downstream.address is the next hop’s EDR directly—the production shape. The demo instead points each downstream.address at the dashboard’s relay, which transparently forwards to the same receiver, only so the dashboard can cut and restore a channel. It changes nothing about how EDR works; in production you point straight at the next hop.

Run it

The demo ships as its own zip, separate from the agent binaries and container image—see EDR for how to obtain it if you don’t have it yet. Unzip it; the archive extracts to a signals-demo/ directory. cd into that directory and follow its README.md—that’s the canonical guide, covering prerequisites, licensing (trial or file-based), driving the dashboard (start and stop signals, cut and restore channels), the edr-inspect triage tooling, ports, and layout. In brief, from inside signals-demo/:

cp .env.example .env        # set the Enterprise image + the four license emails
docker compose up --build   # then open http://localhost:8090

You’ll watch three signals propagate across the tiers—and, by cutting a channel, watch a downstream node freeze and then catch up with no loss when the link is restored.

What this demonstrates

  • Store-and-forward across intermittent links—data written while a hop is down is queued and delivered when it returns.
  • Multi-tier relay—a regional node that both receives and forwards (and forwards its own locally-written data too).
  • At-least-once delivery with automatic catch-up; no data lost on disconnection.

The demo runs on defaults with no tuning. Before you size a production deployment, see Size WAL retention for the two settings worth setting deliberately.

Next


Was this page helpful?

Thank you for your feedback!