Skip to main content

In brief

The simulator stages 40 engineers over 156 weeks. They must finish a migration and, at the same time, keep the existing platform running. Five ideas are enough to read everything else.

  • An integration can run away through a chain of causes: departures reduce the team's capacity, the migration falls behind, uncertainty rises, and more people leave.
  • The model contains three chains of this type and three protections: a retention bonus for key people, a rolling budget that funds replacements, and a parallel run of the old and the new system.
  • At the attrition observed in the reference case (3 non-key departures over three years), the model produces no spiral, with or without the protections. The reference case therefore sat far from the tipping threshold.
  • This result does not prove that the protections were useless. Without protection, half of the simulations tip into a spiral at about three times the observed attrition. With all three protections, it takes about ten times that attrition.
  • All numerical values are synthetic. The model helps ask the right questions before signing an acquisition. It computes no forecast.

The problem: why an integration can run away

When a company buys another, two IT systems, two teams and two ways of working have to be brought together. Here, the engineering team of the acquired company must move its platform to a different technical infrastructure. That is the migration. Meanwhile, customers keep using the product, which means maintaining the existing service: fixing incidents, shipping small changes, keeping the service running. That is ongoing operations.

The weight of these operations depends on technical debt, meaning the accumulation of shortcuts taken in the past in code and infrastructure. The heavier the debt, the more engineers ongoing operations absorb. In the model, operations take 6% of engineering effort when debt is zero and 30% when debt is at its starting level. Less capacity remains for the migration and for paying down that same debt.

These mechanisms reinforce one another. Imagine a team that loses two people. The others take over their work, the migration slips, the announced schedule degrades, worry grows. Two more people leave in turn, and the cycle restarts faster. Specialists call this a reinforcing loop: the effect of each step feeds its own cause.

A spreadsheet represents this phenomenon poorly, because effects arrive with delays and depend on each individual. An agent-based simulator brings 40 individual engineers to life, each with a personal sensitivity to uncertainty, and lets the whole evolve week after week. One then observes whether the team holds or collapses, and what makes the difference.

The model at a glance

Causal map of the modelThree reinforcing loops link departures, capacity, delay, uncertainty, debt and revenue at risk. Three levers (rolling budget, retention bonus, parallel run) slow these loops down.Rolling budgetfunds arrivalsRun loadkeeping the existing service upTechnical debtaccumulated shortcutsDeparturespeople who leaveEngineering capacitywhat the team producesMigration delaygap to the planRetention bonusslows key departuresPerceived uncertaintyworry in the teamsRevenue at riskcustomers being migratedParallel runold and new together−−++++−+−++−−State variableIntermediate variableLever+ same direction, − opposite directionlink inactive in the reference case
Causal map: 7 variables, 3 levers, 13 links.

Each arrow links a cause to its effect. A plus means the two quantities move in the same direction, a minus that they move in opposite directions. The map merges migration progress and its delay into a single box. Dashed links exist in the model. The reference case showed no customer attrition: revenue exposure stayed theoretical there.

The model contains three reinforcing loops, chains of causes in which each effect feeds its own cause.

LoopChain of causesIn plain terms
R1, attrition spiralDepartures, capacity, delay, uncertainty, departuresDepartures slow the migration, which worries the teams and triggers more departures.
R2, debt and capacityDebt, run load, capacity, debtThe heavier the debt, the less capacity the team has to reduce it.
R3, revenue pressureDelay, revenue at risk, uncertainty, departures, capacity, delayA delay threatens revenue, which worries the teams and sustains the delay. This loop stayed inactive in the reference case.

The three levers slow these loops: the retention bonus acts on departures, the rolling budget on capacity, the parallel run on revenue at risk.

Variables and levers

The model tracks eight quantities that change every week, and three levers that can be switched on or off to measure their effect. All starting values are synthetic.

QuantityWhat it representsStarting value
Engineering capacitySum of the productivities of the engineers present. A key person counts 1.5 times an ordinary person. A new hire climbs from 30% to 100% productivity over 16 weeks.40 people, including 8 key people
Run loadShare of capacity devoted to maintaining the existing service. It equals 6% plus 30% of the debt.30%
Technical debtLevel of accumulated shortcuts, from 0 to 1. It falls when the team pays it down and rises when delay pushes toward shortcuts.0.80
Migration progressShare of the total work already done, from 0 to 1.0
Migration delayGap between the progress a linear plan over 156 weeks would have reached and the actual progress.0
Revenue at riskCustomer revenue under threat as long as the migration is not finished: 15% of total revenue. Tracked revenue starts at 1 and can only fall.1
Perceived uncertaintyWorry in the teams, from 0 to 1. It starts at the announcement of the integration, then evolves with delay, revenue pressure and recent departures.0.50
DeparturesWeekly probability of leaving the team, specific to each engineer: a base rate plus a reaction to uncertainty, weighted by personal sensitivity.Value recalibrated on the observed case

The three levers are the protections tested in the scenarios.

LeverWhat it does in the model
Retention bonusCuts the probability of departure of key people by 85% during the first 104 weeks.
Rolling budgetEach week, a three in ten chance of replacing a person who has left, as long as headcount is below 40.
Parallel runRuns the old and the new system together. Costs 8% of capacity and protects 95% of revenue at risk against customer attrition.

One week in the simulation

The program advances week by week. Each week, it performs the same eight calculations in the same order, then moves on to the next.

Weekly cycleEach week, eight calculations follow one another in the same order: free capacity, split, progress, debt, revenue, uncertainty, departures, arrivals. Uncertainty links delay, revenue and departures.next week1. Free capacityeffort of those presentminus upkeep2. Split75% to the migration25% to the debt3. Progresswork donedelay recomputed4. Debtfalls with effortrises with delay5. Revenuecustomer attritionif the delay grows6. Uncertaintydelay and revenuerecent departures7. Departuresrandom drawfor each person8. Arrivalsreplacement possibleif rolling budgetUncertainty links delay, revenue and departures: this is where the loops close.
Weekly cycle: 8 calculations in a loop.
  1. Free capacity. The program adds up the productivity of the engineers present, then subtracts the run load and, if the parallel run is active, 8% of the starting capacity.
  2. Split. While the migration is unfinished, 25% of free capacity reduces the debt and 75% moves the migration forward. Once the migration is finished, all free capacity reduces the debt.
  3. Progress. Completed work is added to the total. Delay is the positive gap between the progress of a linear plan over 156 weeks and actual progress. In version 2, each departure adds rework to the total work.
  4. Debt. It falls with paydown effort and rises with delay, because a team that is behind takes shortcuts.
  5. Revenue. While the migration is unfinished, part of revenue is at risk. Without a parallel run, a delay loses customers. With it, 95% of that loss is avoided.
  6. Uncertainty. Each week it moves toward a target that adds up worry caused by the announcement (which fades with time), delay, revenue pressure and the departures of the last twelve weeks.
  7. Departures. Each engineer draws a random lot for leaving. The probability depends on the base rate, on uncertainty and on personal sensitivity. The retention bonus divides that probability by nearly seven for key people during 104 weeks. In version 2, a freelancer can only leave at the end of a contract.
  8. Arrivals. With the rolling budget, a person who has left is replaced with a three in ten chance each week, as long as headcount is below 40. The new hire reaches full productivity in 16 weeks.

A simulation repeats this cycle 156 times. The program then launches others, with different random draws, to see the spread of results.

The team: employees, freelancers and distance

The first version of the model treats all engineers as employees working in the same place, who can leave in any week. The reference case did not look like that: the team had a majority of freelancers, spread across locations. The second version adds these two traits and a third notion, knowledge loss, then compares three team structures.

CharacteristicCo-located employeesCo-located freelancersDistributed freelancers
Share of freelancers0%65% (assumption)65% (assumption)
When a departure is possibleAny weekAt contract end, every 26 weeks for a freelancerSame
Contracts with a common end dateNot applicable50% (assumption)50% (assumption)
Effort lost to coordination0%0%10% (assumption)
Ramp-up of a new hire16 weeks16 weeks24 weeks (assumption)
Contagion of departures between colleaguesNormalNormalHalved (assumption)

Knowledge loss applies to all three structures. Each engineer accumulates knowledge of the migration during their first 52 weeks of presence, then nothing more is added. A key person carries three times as much. When someone leaves before the migration ends, the remaining work grows by a volume proportional to that knowledge: 20 person-weeks of rework per unit of knowledge.

The word “assumption” in the table flags unmeasured values. They influence the result and are listed with the others in the section on limits.

Calibrating: anchoring the model on the observed case

Calibrating means adjusting a model parameter until it reproduces an observed fact. The fact retained is the attrition of the reference case: about 3 non-key departures over the three years, in a team of around forty people. That statement allowed two readings. Reading A counts 3 departures in total over three years. Reading B counts 3 departures per year, 9 in total. The person who led the case confirmed reading A, which is the one used throughout this guide.

The method is a bisection search. One factor multiplies the base probability of departure and the reaction to uncertainty together, preserving their ratio. The program runs 50 to 60 simulations with a given factor, counts non-key departures, then narrows the factor until the average reaches 3. This gives the following values.

Team structureFactorBase probability of departure per weekReaction to uncertainty
Version 1, co-located employees0.16950.000340.00203
Version 2, co-located employees0.17430.000350.00209
Version 2, co-located freelancers0.18170.000360.00218
Version 2, distributed freelancers0.16230.000320.00195

Two limits deserve attention before going further. First, the model has a single setting and a single observation: the agreement between the two holds by construction and tests nothing. Second, the split between the base rate and the reaction to uncertainty is an assumption that calibration cannot settle.

Results

Each scenario is simulated 40 to 60 times with different random draws. A simulation is classified as a “spiral” when engineering headcount falls below 60% of the initial headcount at any point. The tables give averages over these runs.

What a spiral looks like

The first figure shows the model with its default attrition, about 25 non-key departures over three years. This value was not recalibrated on the reference case: the figure shows the phenomenon without measuring it.

Engineering headcount and migration progress across four scenarios
Figure 1. Headcount and progress in four scenarios, default attrition not recalibrated. Median and 10 to 90% interval over 40 runs.

With all three levers, headcount stays close to its starting level (average minimum of 89%) and the migration finishes. Without the rolling budget, headcount falls on average to 40% and the migration stops at 60%. Without any lever, headcount reaches 21% and the migration plateaus at 50%. In this regime, 92% of the simulations without the rolling budget and 100% of the simulations without any lever tip into a spiral.

At the observed attrition

The following table uses version 2, the majority-freelance distributed team, recalibrated to 3 non-key departures over three years.

ScenarioSpiralMinimum headcountMigration completed at 156 weeksFinal debtRevenue lostKey-person departures
Baseline, three levers0%97%94%0.250.7%0.3
Without retention bonus0%97%92%0.260.7%0.8
Without rolling budget0%91%88%0.300.8%0.5
Without parallel run0%97%100%0.018.4%0.4
Without any lever0%87%97%0.1610.0%1.1

No scenario tips into a spiral. Each lever acts at a different point. The parallel run protects revenue: without it, 8.4% of revenue is lost against 0.7%. In return it costs capacity, hence a slower migration with it (94%) than without it (100%). The retention bonus retains key people: 0.3 departures on average with it, 0.8 without it.

Had the starting statement meant 3 departures per year, or 9 over three years (reading B), the result would differ. On the first version of the model, 35% of simulations without any lever would tip into a spiral, 8% without the rolling budget and none with all three levers.

What distance costs

Team structure, baseline scenarioMigration completed at 156 weeksFinal debtRevenue lost
Co-located employees100%0.000.4%
Co-located freelancers100%0.000.4%
Distributed freelancers94%0.250.7%

Distance weighs on the schedule and on debt more than on the stability of the team. The 10% of effort lost to coordination and the 24 weeks of ramp-up are assumptions: this table describes their effect on the model and says nothing about the reality of the reference case.

Distance to the tipping threshold

The second figure answers the useful question: by how much would attrition have to rise for the system to tip? The horizontal axis multiplies the attrition calibrated on the observed case.

Share of simulations ending in a spiral by attrition, for three team structures, with and without levers
Figure 2. Share of simulations in a spiral according to non-key attrition, as multiples of the observed case. Sixty runs per point, synthetic parameters.

Without any lever, half of the simulations tip at about three times the observed attrition (57% for distributed freelancers, 52% for co-located freelancers, 70% for co-located employees). With all three levers, tipping occurs between eight and twelve times the observed attrition. The levers therefore push the threshold back by a factor of about three to four. The reference case sat at the far left of the figure, well away from the tipping zone.

How to read these results

Three readings are legitimate. Three others seem natural and are not.

What the results support.

  • The spiral mechanism exists in the model: it appears as soon as attrition exceeds a threshold, and the levers push that threshold back.
  • Each lever acts at a distinct point. The parallel run protects revenue, the rolling budget protects headcount, the retention bonus protects key people.
  • The reference case, with 3 departures over three years, sits far from the threshold.

What the results do not support.

  • That the protections were useless. Far from the threshold, they change nothing about stability. They keep their value as insurance against stronger attrition.
  • That a distributed team of freelancers is more robust. This result follows from two assumptions: a departure possible only at contract end, and a contagion of departures halved by distance.
  • That the model predicts a future integration. It compares scenarios on synthetic values and computes no real probability.

One last point of method: the reference case is a success. A model calibrated on a single success can display the right outcome without its mechanisms being exact. A failed integration case, even anonymised, would bring the missing information: it would allow the model to be tested on the other side of the threshold.

Limits and assumptions to verify

The table lists what is guessed or chosen without measurement. Each row gives the effect on the results and the check that would settle it.

AssumptionValue usedEffect on the resultsCheck to perform
Share of freelancers65%Sets the frequency of possible departuresActual composition of the team
A freelancer leaves only at contract endEvery 26 weeksIf notice is short, departures become possible all year and the apparent robustness of the team dropsNotice periods and contract lengths
Contracts with a common end date50%Concentrates possible departures on a few datesShare of contracts renewed together
Effects of distance10% coordination loss, 24 weeks of ramp-up, contagion halvedExplain the remaining debt and the better resistance of the distributed teamCompare with the actual migration schedule
Split of capacity between migration and debt75% and 25%Sets the speed of debt paydownTrade-off actually made in practice
Key people20% of the team, productivity of 1.5, knowledge × 3Determines the value of the retention bonusWho held the knowledge of the migration
Spiral thresholdHeadcount below 60% of the startVery strong ordinary attrition crosses the threshold with no loop at all: it measures attrition as much as the spiralA definition based on the acceleration of departures
Split between base rate and reaction to uncertaintyRatio preserved during calibrationChanges the relative weight of chance and contagionA second set of observed departures
A single observed caseA successCalibration tests nothing; a second lived case has not yet served as a testA failed case, even anonymised

Three scope notes complete the table. The simulated team has 40 people, like the reference case, and the model covers a single type of integration: the acquisition of a company by a group, with infrastructure migration and ongoing operations running in parallel. No internal company data is used, and the reference case is anonymised. The agents are explicit rules, deliberately: their behavior can be checked line by line.

Using the code

The code is written in Python with the Mesa library, designed for agent-based simulation. It was run with Python 3.13 and Mesa 3.5.1. The files go in a single folder, because some import others.

Source code and results: repository thierrysays/integration-attrition-simulator or archive integration-attrition-simulator-v1.1.zip (450 KB, Python scripts, results, figures, README in French and English). Code under the Apache License 2.0; results, figures and README under Creative Commons Attribution 4.0.

Installation

pip install mesa==3.5.1 matplotlib

The files

FileRole
pmi_model.pyVersion 1 model: team of co-located employees
run_scenarios.pyLever-removal scenarios, sensitivity sweep, figure 1
calibrer_attrition.pyCalibration on 3 departures (readings A and B), distance to the threshold
tracer_seuil.pyTipping curve of version 1
pmi_model_v2.pyVersion 2 model: freelancers, knowledge loss, distance
run_v2.pyCalibration, scenarios and tipping curve of version 2, figure 2
redessiner_courbe_v2.pyRedraws figure 2 from the results file, without rerunning the simulations
resultats_*.csvResults tables, readable in a spreadsheet

The commands

python3 run_scenarios.py
python3 calibrer_attrition.py
python3 run_v2.py

Each command prints its tables on screen and writes its results files to the folder. Duration was not measured precisely: allow a few minutes for the calibrations, which launch several hundred simulations.

Changing a value and rerunning

All model values are fields of a Params class. An example that rebuilds the distributed-freelancer team of version 2, with calibrated attrition, then runs one simulation without the retention bonus:

from dataclasses import replace
from pmi_model_v2 import IntegrationModel, Params

s = 0.1623  # facteur de calibrage, freelances distribués
p = replace(
    Params(),
    freelance_share=0.65, coordination_penalty=0.10,
    onboarding_weeks=24, w_dep=1.5,
    base_quit=0.002 * s, quit_gain=0.012 * s,
    retention_bonus=False,
)
resultat = IntegrationModel(p, seed=1).run().summary()
print(resultat)

The seed parameter fixes the random draws: the same value gives exactly the same result. The scripts use values from 1000 upward for scenarios, from 5000 upward for calibration.

Reading the results columns

ColumnMeaning
spiraleShare of simulations whose headcount fell below 60% of the initial headcount
eff_minLowest headcount reached, as a share of the initial headcount
avancementShare of the migration completed at 156 weeks
detteFinal level of technical debt
revenu_perduShare of revenue lost to customer attrition
departs_cles, departs_autresAverage number of key-person departures and of other departures
repriseShare of migration work redone after departures (version 2)

Glossary

TermDefinition
AgentA simulated element that decides according to rules. Here, an engineer.
AttritionPeople leaving a team over a period.
Reinforcing loopA chain of causes in which the final effect feeds the initial cause and amplifies the phenomenon.
Rolling budgetContinuously renewed funding that allows people who have left to be replaced.
CalibrateAdjust a parameter so that the model reproduces an observed fact.
Technical debtShortcuts accumulated in code and infrastructure, which make every intervention heavier.
Full-time equivalentUnit for measuring headcount: one full-time person equals one. Three full-time equivalents equal three people.
Ongoing operationsWork to keep the existing service running: incidents, fixes, small changes.
Parallel runRunning the old and the new system at the same time, to avoid any interruption for customers.
FreelancerIndependent engineer bound by a fixed-term contract.
Random seedA number that fixes the random draws. The same seed gives the same result.
LeverA protection that can be switched on or off in a scenario.
MigrationMoving the platform to a different technical infrastructure.
Knowledge lossKnowledge of the migration that leaves with a person and is paid for in rework.
Key personAn engineer who is more productive and carries more knowledge. 20% of the team in the model.
Retention bonusA bonus paid to key people to keep them until the end of a period.
ReworkWork already done that must be redone or relearned after a departure.
Revenue at riskShare of customer revenue under threat as long as the migration is not finished.
Sensitivity to uncertaintyEach engineer's own propensity to leave when worry rises.
Tipping thresholdLevel of attrition beyond which simulations go into a spiral.
Agent-based simulationA method that brings simulated individuals to life and observes what emerges from their interactions.
SpiralIn this guide, a simulation whose headcount falls below 60% of the initial headcount.
SyntheticA value invented to illustrate a mechanism, not measured on a real case.
RunOne execution of the simulation with its own random draws. Each scenario has 40 to 60.

Open questions and next steps

Four pieces of information remain to be gathered. Each settles one assumption of the limits table.

  • What notice period and contract length did the freelancers have?
  • Did the migration meet the three-year schedule? The answer sets the effort lost to coordination.
  • What share of freelance contracts had a common end date?
  • Is there a failed integration case, even anonymised, to test the model on the other side of the threshold?

The next steps, in order:

  1. Replace the contract-end constraint for freelancers with a departure possible at any time after notice, then rerun the tipping curve.
  2. Define the spiral by the acceleration of departures rather than by the final level of headcount.
  3. Test a second integration case without readjusting the parameters, then confront the model with a failed case.
  4. Submit the causal map and the assumptions to two people who have lived through an integration.
  5. Build a set of anonymised cases: this is the lasting asset of the project, far more than the code.

The values in this guide are synthetic and the reference case is anonymised. To discuss the model or submit an anonymised integration case, write to thierry@glossolalie.pro · linkedin.com/in/thierrys.