Documentation

Everything you need to go from GPX file to a validated permit packet.

Getting started

Installation

Download the appropriate build from the Download page. RaceFlows is a self-contained desktop app — no runtime dependencies, no account required.

macOS: Open the DMG, drag RaceFlows to Applications. On first launch, right-click the icon and choose Open to bypass the unsigned-app warning.

Windows: Run the installer. If SmartScreen appears, click More info → Run anyway. The installer does not require admin rights.

Create a project

RaceFlows stores each event in a .race file — a SQLite database that holds courses, segments, features, pace bands, and simulation metadata. Trajectory data is written to a sidecar .race-data/ folder next to the file.

From the welcome screen, click New project and enter a project name, then choose a save location. You can also open a recent project from the list.

Import a GPX file

Click + Import GPX in the subheader. RaceFlows parses the track, resamples the centerline at 10 m intervals, computes cumulative distance, and tiles it into segments (default ~75 m each). If the GPX contains elevation data, an elevation profile is shown in the course sidebar.

Draw a course

Click + Draw course to enter drawing mode. Click the map to place waypoints; use Undo to remove the last point. When finished, click Finish and name the course. Drawn courses go through the same resample/segment pipeline as GPX imports (no elevation data).

Course setup

Segments & width zones

The course is divided into segments of configurable length. Each segment has a width zone (Narrow, Medium, Wide) that scales the density calculation — a narrow segment at the same runner count reads as higher density than a wide one. Assign zones in the Setup → Segments accordion.

Pace bands

A pace band set defines what fraction of the field runs within each pace range. Bands must sum to 100%. You can maintain multiple sets per project and assign a different one to each course.

To derive bands from real entrant data, click Import from registration CSV in the Pace Bands accordion. RaceFlows accepts columns named finish_time, expected_pace, pace_per_km, or pace_per_mile and fits five percentile-based bands automatically.

Start protocols

Each course has its own start protocol, set in Setup → Start Protocol:

  • Mass start — all runners released at a single time.
  • Wave start — runners distributed across named waves, each with its own start time and proportional share of the field.
  • Rolling start — runners released at a steady rate between an open and close window.

When multiple courses have different start times, the time slider uses a shared clock anchored to the earliest gun time. Courses show empty density until their gun fires.

Elevation & grade adjustment

If your GPX contains elevation, RaceFlows interpolates it onto the resampled centerline and displays it as a compact area chart. Enable Elevation-adjusted pace in the simulation panel to apply the Minetti (2002) grade multiplier — runners slow on uphills and speed slightly on gentle downhills.

Running a simulation

Running a simulation

Click Run in the map toolbar to open the simulation panel. Enable each course you want to include, set field size and optional cutoff time per course, then click Run simulation.

A fixed random seed controls all stochastic draws — same seed and same inputs always produce identical results. Use the button to generate a new seed.

Cohort adjustments

Two global multipliers slow the entire field before sampling:

  • Temperature — 0.3% pace penalty per °F above 60°F (no effect below 60°F).
  • Terrain — 1.0× road (no adjustment), 1.1× mixed, 1.25× trail.

Both multiply together. The resulting global pace multiplier is displayed when it differs from 1.0.

Reading the heatmap

After a successful run, the map colors each segment by runner density (runners per meter of segment length, normalized by width zone). The color scale runs green → yellow → red. Use the time slider to scrub through the race, or press to play it back.

When multiple courses are loaded, all are rendered in a single layer. Segments with higher density always appear on top regardless of which course they belong to.

Bottlenecks

A bottleneck is any segment where density exceeds the threshold (default 1.5 runners/m², configurable in Settings) for a sustained window (default 30 s). The bottleneck table lists each incident with its segment, time window, and peak density.

Comparing runs

Every simulation is saved automatically. In the simulation panel, select any two saved runs using the A/B radio buttons and click Compare A vs B. The comparison view shows both heatmaps at the same clock time, an overlaid finish-line chart, and a diffed bottleneck table highlighting new, resolved, and worsened incidents.

Permit maps

Placing features

Click a course in the subheader, then open the Features tab. Select a feature type from the palette and click the map to place it. Drag any placed feature to reposition it; click to select it and edit its properties (label, notes, and type-specific fields such as aid station dwell time).

Feature types: Aid station, Medical, Vendor, Packet pickup, Photo zone, Point of interest, Road closure.

Road closures

Open the Closures tab to place and edit road closure features. Each closure has a street name and optional open/close times. After running a simulation, RaceFlows computes recommended closure windows from the first and last runner pass times, with a configurable safety buffer, and displays them in the closure table.

PDF export

Click Export PDF in the Features tab. The export includes a cover page with a map snapshot and event metadata, a per-course feature inventory grouped by type, and a road closure schedule table. Fill in organizer name, contact, and permit notes in Settings → Export settings before exporting.

Staffing plan

Open the Volunteers tab for a recommended headcount breakdown by feature. Default rules: one marshal per intersection, two volunteers per aid station per 1,000 runners. The plan is read-only in this version — assigning specific people is out of scope.