CoCiP Benchmark

Running CoCiP periodically on a fixed scenario helps identify both intended and unintended changes. Early in its development, pycontrails was evaluated against existing implementations of CoCiP [Schumann, 2012]. Because bug fixes and model improvements have since changed its results, this page compares pycontrails releases against one another. Every release runs the identical CoCiP simulation, so changes in model output and runtime can be traced directly to the release that made them.

The simulation covers 19,326 flights over Europe on 30 January 2020, using the ADS-B flight trajectories of GAIA [Teoh et al., 2024] and ERA5 model-level meteorology. January 2020 predates the COVID-19 decline in air traffic, and according to ERA5, the 30th had the largest share of persistent contrail regions over Europe of any day that month (select_day.py). For each release, the benchmark records CoCiP’s output for every flight alongside the totals across all flights (run_benchmark.py).

The benchmark uses the CoCiP parameter choices of [Teoh et al., 2024]. Some parameters, such as max_age, have existed since the first pycontrails release, while others were only added later, such as unterstrasser_ice_survival_fraction in 0.50.1. Each release runs with the parameters available in it.

Every run uses a c3-highmem-4 Google Compute Engine instance (4 vCPUs, 32 GB of memory), with the latest Python version the release supports and the package dependencies available on its release date.

When a release fails on some flights, for example because it does not support their aircraft type, the benchmark excludes them. If the skipped flights cannot be identified in advance, the benchmark applies a patch from a later release instead. The table below lists the number of excluded flights, and benchmark_results.csv lists the patches applied. Releases 0.9.0 and 0.15.1 are omitted entirely, as they fail on all or nearly all flights.

Releases before 0.11.0 have no Fleet-mode and run CoCiP one flight at a time, which would take about 40 hours for all flights. Instead, these releases run on a fixed random sample of 2,000 flights, and their totals and runtime are scaled by 19,326 / 2,000. When 0.11.0 runs on the same sample, its scaled energy forcing is 5.5% above its result on all flights, which indicates the size of the sampling error.

Releases 0.19.1 to 0.28.2 use too much memory to run Fleet-mode on all flights at once, so they run it on 64 batches of flights, one after another. Their runtime is the sum of the batch runtimes.

In the plots below, the numbered markers link to a row in the table of changes.

Results

Flights excluded

Number of flights excluded because the release fails on them.

2026-11-13T14:40:44.534116 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/

Totals

Total energy forcing, contrail length times age, length of flight segments forming persistent contrails, and fuel burn over all flights evaluated with CoCiP.

2026-11-13T14:40:44.836883 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/

Energy forcing per flight

Distribution of the energy forcing per flight for selected releases. Each histogram shows the fraction of the flights run in each bin. Flights with energy forcing between -1010 and 1010 J, which include those with none, are left out.

2026-11-13T14:40:46.225388 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/

Runtime Performance

Time spent running CoCiP, not counting loading the flights and meteorology, and peak memory of the process. Runtimes of releases run on the sample are scaled to all flights.

2026-11-13T14:40:45.096391 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/

Changes

#

Release

Release date

Change

1

0.2.0

2021-11-16

  • CoCiP fails for 72 sample flights because of the misspelled parameter deafult_thrust, and the benchmark drops them.

  • Persistent contrail length is available.

2

0.3.0

2021-11-23

  • CoCiP attaches persistent_1 and the other initial contrail properties to the first waypoints of each flight instead of the waypoints that satisfy the SAC, so the persistent contrail length is wrong until 0.19.1.

  • A performance bug in the SAC flight model meteorology handling is fixed, improving memory footprint.

3

0.6.0

2021-12-03

  • CoCiP computes the solar direct radiation from the solar geometry instead of from the ERA5 TOA incident solar radiation, and shifts the radiation times to the middle of each accumulation hour.

4

0.7.1

2021-12-11

  • Fix of the deafult_thrust typo, so the 72 sample flights run again.

5

0.8.1

2022-01-11

  • CoCiP fails with ValueError for flights whose waypoints do not intersect the meteorology: 255 sample flights, 229 that previously failed with IndexError and 26 more.

6

0.11.0

2022-01-31

  • First release with Fleet-mode. The benchmark runs CoCiP on all flights at once.

  • The benchmark drops 971 flights that fail in this release.

  • The results have no persistent contrail length.

7

0.12.3

2022-02-16

  • Fix of CoCiP running with Fleet-mode: the contrail waypoints are sorted by flight and time after new waypoints are added. Before, the segment joining the older and newer contrail waypoints of each flight was discontinuous, so it had no energy forcing.

8

0.16.0

2022-03-10

  • BADA3 fuel flow is clipped at every waypoint to the nominal range of its flight phase. Earlier releases corrected only fuel flows above the maximum climb fuel flow or below 0.

9

0.17.1

2022-03-10

  • 36 more flights now run (earlier releases failed for engines whose EDB fuel flows repeat a value).

10

0.18.0

2022-03-21

  • The wind shear of a partially initialized segment no longer contributes to the plume geometry.

11

0.19.1

2022-04-06

  • Persistent contrail length is available again.

  • CoCiP builds a dense (flight * time step * waypoint) array of the contrail output that does not fit in memory, so the benchmark runs CoCiP on 64 batches of flights, one after another. Runtime is the sum over batches.

12

0.20.2

2022-04-25

  • 565 more flights now run. From 0.11.0 to 0.20.1, CoCiP failed for flights whose waypoints are all outside the meteorology but whose engine has an nvPM profile, and the benchmark dropped those flights.

13

0.22.0

2022-05-27

  • CoCiP copies the full meteorology in eval instead of when created, which increases the runtime.

14

0.25.9

2022-08-12

  • New engine thrust setting methodology, based on ECLIF II nvPM measurements, which changes the nvPM number emissions index.

  • 370 more flights now run. Earlier releases failed for piston aircraft, and the benchmark dropped them.

15

0.26.0

2022-09-15

  • CoCiP selects the meteorology around the flights for initialization and around the contrails at each evolution step, without copying it. This improves runtime.

16

0.27.0

2022-09-27

  • Humidity scaling becomes a separate model. Before, CoCiP scaled only RHi, with rhi_adj = 0.97 set by the benchmark; now the benchmark passes ExponentialBoostLatitudeCorrectionHumidityScaling with its defaults, which also scales specific humidity.

17

0.28.3

2022-10-13

  • CoCiP no longer builds the dense array, so the benchmark now runs all flights in one batch again.

18

0.28.9

2022-11-14

  • The benchmark sets radiative_heating_effects=True, a CoCiP parameter added in this release.

19

0.29.0

2022-11-18

  • The EDB is indexed by engine, with 557 engines for gaseous emissions and 178 for nvPM instead of 117 and 47.

  • This release fails for flights whose engine is missing from its EDB, and the benchmark drops those 2,862 flights.

20

0.29.1

2022-11-25

  • 2,748 of the 2,862 flights dropped in 0.29.0 run again.

  • BADA3 has new default aircraft and engine pairs.

  • Staged combustors get a step change in nvPM emissions.

  • BADA3 looks up each aircraft type’s engine in a static table of 250 BADA types, which lacks the types of 114 flights (mostly light and piston aircraft, plus CL35, LJ75 and DHC6). BADA3 fails for them and the benchmark drops them.

21

0.31.4

2022-12-08

  • With radiative heating effects, the contrail plume temperature includes the cumulative heating, up to 1.5 K, instead of the ambient temperature. Until 0.60.4, the heating is mistakenly added to the stored air temperature in place more than once per time step.

22

0.33.0

2023-01-25

  • Fix of the BADA3 fuel flow in slow climb and descent.

23

0.36.0

2023-02-24

  • The benchmark runs this release with pycontrails-bada 0.2.1, which reverts the flight phase handling of 0.33.0.

24

0.40.0

2023-04-14

  • Linear interpolation is cythonized and the interpolation module overhauled for speed.

25

0.43.0

2023-06-23

  • The benchmark passes HistogramMatching, new in this release, with its defaults, instead of ExponentialBoostLatitudeCorrectionHumidityScaling.

26

0.44.0

2023-06-23

  • The benchmark runs the PS model, new in this release, with BADA3 for aircraft types the PS model does not cover. Earlier releases ran BADA3 only.

  • In pycontrails-bada 0.4.0, BADA3 assumes a load factor of 70% instead of the BADA reference mass.

27

0.46.0

2023-08-16

  • Fix of a unit error in wake_vortex.turbulent_kinetic_energy_dissipation_rate, which increases the dissipation rate.

28

0.47.3

2023-10-20

  • Fix of radiative_forcing.effective_tau_contrail, which changes the shortwave radiative forcing only.

29

0.49.0

2023-11-21

  • PS model version 2.0, with new aircraft and engine parameters.

30

0.50.1

2024-04-08

  • The benchmark sets unterstrasser_ice_survival_fraction=True, a CoCiP parameter added in this release.

31

0.50.2

2024-04-17

  • The ICAO EDB is updated from v28c to v29b.

  • New PS model coefficients.

  • The EDB adds engine 1ZM001 with no idle fuel flow, for which the FFM2 emissions profiles fail, so the benchmark drops the one flight with it.

32

0.51.0

2024-05-23

  • The benchmark sets level_type="model" in HistogramMatching, new in this release, which uses quantiles calibrated for ERA5 model-level data.

33

0.51.1

2024-05-31

  • The PS model’s engine_deterioration_factor increases average fuel burn by 2.5%.

  • PS model aircraft type synonyms move more flights from BADA3 to the PS model.

34

0.52.2

2024-08-01

  • The benchmark sets fill_low_altitude_with_isa_temperature and fill_low_altitude_with_zero_wind, aircraft performance parameters added in this release. Waypoints below the lowest meteorology level had no fuel flow before, so the climb and descent fuel is now counted.

  • Peak memory falls with an improved Cocip._bundle_results.

  • The EDB fills in the idle fuel flow of 1ZM001, so its one flight runs again. No release from here on fails for EDB fuel flows.

35

0.54.3

2024-11-21

  • The default load factor rises from 70% to 83% in the PS model and in BADA3.

  • The benchmark uses pycontrails-bada 0.7.0, whose aircraft-engine table adds the BADA 3.16 aircraft types, so 113 of the 114 flights dropped since 0.29.1 now run.

36

0.54.7

2025-02-19

  • The ice crystal survival fraction is updated to Lottermoser and Unterstrasser (2025).

37

0.55.0

2025-09-02

  • The benchmark sets vpm_activation=False, a CoCiP parameter added in this release, because the extended K15 model runs out of memory on the benchmark VM.

38

0.59.1

2025-11-19

  • The benchmark passes the MEEM2 nvPM emissions model, new to the emissions CoCiP parameter in this release.

  • MEEM2 fails for engines with DAC, TAPS or TAPS II combustors, and the benchmark drops those 770 flights.

  • The ICAO EDB is updated from v29b to v31.

39

0.60.1

2025-12-15

  • MEEM2 no longer fails for DAC, TAPS and TAPS II combustors; the 770 flights run again.

40

0.60.2

2026-01-15

  • The benchmark sets vpm_activation=True, which increases runtime.

  • The benchmark sets max_horizontal_diffusivity and max_vertical_diffusivity, CoCiP parameters added in this release.

41

0.60.5

2026-03-31

  • The extended K15 model is updated to align with pyrcel, and splits waypoints into rich burn and lean burn by nvPM number emissions index.

  • The engine deterioration factor of the PS model, and of BADA3 in pycontrails-bada 0.8.3, comes from each flight’s aircraft_age_yrs instead of a fixed 2.5%. For narrow-body aircraft it rises to 6% at 10 years, so fuel burn rises by 1.8%.

42

0.61.0

2026-04-15

  • The vertical diffusivity with radiative_heating_effects uses the square of the turbulent vertical velocity, but squares its minimum too, by mistake.

  • Take-off mass comes from an estimated payload instead of a load factor.

  • The cargo load factor table has no rows between Africa and Asia Pacific, so this release fails for the 7 flights between those regions, and the benchmark drops them.

  • The payload estimate calls jet.cargo_load_factor once per flight, and each call runs a pandas query and re-indexes the airport table. This increases runtime significantly.

43

0.63.0

2026-04-30

  • The cargo load factor table falls back to global values, so the 7 flights between Africa and Asia Pacific run again.

44

0.63.1

2026-05-28

  • Fix of the minimum turbulent vertical velocity squared in 0.61.0.

All results

Consecutive releases with equal results share a row, with the range of their runtimes and peak memory. benchmark_results.csv has every field of every release’s summary, including the Python and dependency versions, the machine, and the sample details.

Releases

Flights dropped

Energy forcing (J)

Persistent length (km)

Fuel burn (kg)

Runtime (s)

Peak memory (GB)

0.1.0

2,474

9.853e+17

—

4.029e+07

29,789

18.8

0.2.0

3,169

9.826e+17

5.314e+06

3.996e+07

29,878

19.0

0.3.0

3,169

9.746e+17

4.951e+06

3.996e+07

21,095

15.8

0.5.0

3,169

9.747e+17

4.951e+06

3.996e+07

21,709

15.8

0.6.0

3,169

9.634e+17

4.951e+06

3.996e+07

21,308

15.5

0.7.1 – 0.8.0

2,474

9.661e+17

5.011e+06

4.029e+07

21,915–23,929

15.5

0.8.1

2,725

9.661e+17

5.011e+06

4.025e+07

24,958

15.5

0.11.0 – 0.12.0

971

7.495e+17

—

3.792e+07

316–322

26.8

0.12.3 – 0.14.0

971

9.400e+17

—

3.792e+07

326–337

26.7–26.9

0.15.0 – 0.15.3

971

9.396e+17

—

3.790e+07

313–338

26.9

0.16.0 – 0.17.0

971

1.013e+18

—

4.349e+07

337–342

28.3

0.17.1

935

1.013e+18

—

4.354e+07

336

28.3

0.18.0 – 0.19.0

935

1.017e+18

—

4.354e+07

323–327

28.1

0.19.1 – 0.20.1

935

1.017e+18

5.506e+06

4.354e+07

1,038–1,052

21.4

0.20.2 – 0.20.3

370

1.017e+18

5.506e+06

4.362e+07

1,022–1,048

22.0

0.21.0 – 0.22.4

370

1.024e+18

5.506e+06

4.362e+07

964–1,342

21.9–22.0

0.23.0 – 0.25.2

370

1.024e+18

5.506e+06

4.362e+07

977–1,229

21.3–22.0

0.25.3 – 0.25.8

370

1.020e+18

5.506e+06

4.362e+07

969–988

21.3

0.25.9 – 0.26.0

0

1.001e+18

5.507e+06

4.363e+07

526–1,007

21.4–24.0

0.27.0 – 0.28.2

0

1.536e+18

5.648e+06

4.363e+07

528–553

21.9–22.0

0.28.3 – 0.28.7

0

1.534e+18

5.648e+06

4.363e+07

192–195

27.9–28.1

0.28.8

0

1.534e+18

5.648e+06

4.363e+07

188

28.0

0.28.9

0

2.418e+18

5.648e+06

4.363e+07

181

25.6

0.29.0

2,862

1.851e+18

5.487e+06

4.147e+07

166

24.0

0.29.1 – 0.31.3

114

1.886e+18

5.639e+06

4.362e+07

182–190

24.9–25.1

0.31.4 – 0.32.2

114

1.472e+18

5.639e+06

4.362e+07

178–192

24.5–24.7

0.33.0 – 0.35.2

114

1.526e+18

5.801e+06

4.192e+07

174–183

24.2–25.5

0.36.0 – 0.41.0

114

1.481e+18

5.653e+06

4.071e+07

123–202

22.3–25.5

0.42.0 – 0.42.2

114

1.482e+18

5.655e+06

4.073e+07

131–132

22.3–22.4

0.43.0

114

9.799e+17

5.249e+06

4.073e+07

116

19.0

0.44.0

114

9.648e+17

5.304e+06

3.971e+07

91

19.4

0.44.1 – 0.45.0

114

9.648e+17

5.304e+06

3.971e+07

97–100

20.0–20.2

0.46.0 – 0.47.2

114

9.736e+17

5.852e+06

3.971e+07

97–99

19.2–19.8

0.47.3

114

9.425e+17

5.852e+06

3.971e+07

101

19.2

0.48.0 – 0.48.1

114

9.425e+17

5.852e+06

3.971e+07

98–104

18.4–18.5

0.49.0 – 0.49.3

114

9.717e+17

5.936e+06

4.141e+07

99–109

18.5–18.6

0.49.4 – 0.50.0

114

9.714e+17

5.934e+06

4.132e+07

104–107

18.6

0.50.1

114

7.659e+17

5.934e+06

4.132e+07

104

18.4

0.50.2

115

7.583e+17

5.916e+06

4.090e+07

107

18.4

0.51.0

115

1.026e+18

5.908e+06

4.090e+07

106

18.8

0.51.1 – 0.52.0

115

1.048e+18

5.964e+06

4.183e+07

108–110

18.8

0.52.1

115

1.048e+18

5.964e+06

4.183e+07

103

18.8

0.52.2 – 0.54.2

114

1.053e+18

5.967e+06

6.479e+07

90–114

15.7–15.8

0.54.3 – 0.54.6

1

1.085e+18

5.991e+06

6.708e+07

110–116

15.5–16.1

0.54.7

1

1.098e+18

5.991e+06

6.708e+07

110

15.4

0.54.8 – 0.54.11

1

1.100e+18

5.991e+06

6.711e+07

110–113

15.6–16.3

0.54.12 – 0.58.0

1

1.101e+18

5.998e+06

6.711e+07

113–128

15.7–16.3

0.59.0

1

1.101e+18

5.998e+06

6.711e+07

114

15.5

0.59.1 – 0.60.0

771

8.331e+17

5.734e+06

6.375e+07

110

14.7–14.8

0.60.1

1

8.373e+17

5.998e+06

6.711e+07

113

15.2

0.60.2

1

1.154e+18

5.998e+06

6.711e+07

141

16.3

0.60.3

1

1.155e+18

5.998e+06

6.711e+07

144

15.4

0.60.4

1

1.148e+18

5.998e+06

6.711e+07

145

15.4

0.60.5

1

1.253e+18

6.039e+06

6.829e+07

148

15.1

0.61.0 – 0.62.0

8

5.141e+17

6.025e+06

6.684e+07

239–244

15.0

0.63.0

1

5.131e+17

6.012e+06

6.654e+07

256

15.3

0.63.1 – 0.63.3

1

8.336e+17

6.012e+06

6.654e+07

248–252

15.1–15.2

0.63.4 – 0.64.0

1

8.395e+17

6.012e+06

6.654e+07

240–248

15.2–15.3

0.65.0

1

8.396e+17

6.012e+06

6.654e+07

238

15.3

0.66.0

1

8.396e+17

6.012e+06

6.654e+07

242

15.2