5 min read
On this page

Stocks, Flows & Delays

Donella Meadows spent decades studying how complex systems behave. Her framework — stocks, flows, and delays — is the most practical lens for understanding why systems produce surprising, counterintuitive results. Engineers who internalize this framework stop being surprised by the consequences of their decisions and start anticipating them.

Stocks

A stock is anything that accumulates. It is a quantity you can measure at a point in time. Stocks change slowly because they are the result of accumulated flows. You cannot change a stock instantly — you can only change the flows that feed it.

Engineering stocks:

Technical debt          Accumulates with every shortcut,
                         decreases with every refactor.
Team knowledge          Accumulates with experience and learning,
                         decreases with attrition.
User base               Accumulates with acquisition,
                         decreases with churn.
Code quality            Accumulates with good practices,
                         erodes with pressure and shortcuts.
Trust (with users)      Accumulates with reliability,
                         erodes with outages and broken promises.
Bug backlog             Accumulates with new bugs filed,
                         decreases with bugs fixed.

The key insight about stocks is that they have inertia. You cannot turn a large codebase from low quality to high quality overnight, no matter how many engineers you assign. You cannot rebuild team knowledge after a mass departure in a week. The stock was built by years of accumulated flow, and it can only be changed by sustained flow in the other direction.

You cannot drain a bathtub instantly.
You can only open the drain wider and close the faucet.
The water level (stock) changes at the rate the flows allow.

Flows

A flow is a rate of change — the speed at which a stock increases or decreases. Flows are what you can actually control. Stocks are the consequences of flows over time.

Stock                   Inflow                      Outflow
---                     ---                          ---
Technical debt          Taking shortcuts,            Refactoring, rewrites,
                         skipping tests               paying down debt

Team knowledge          Hiring, training,            Attrition, layoffs,
                         documentation                knowledge silos breaking

User base               Marketing, referrals,        Churn, competitor
                         organic growth               switches, abandonment

Production incidents    New bugs, config errors,     Fixes, rollbacks,
                         deploys                      preventive measures

Backlog size            New feature requests,        Shipping features,
                         bug reports                  closing as won't-fix

The distinction between stocks and flows is practical. When someone says "we have too much technical debt," they are describing a stock. The question is not "how do we eliminate the debt?" (you cannot change the stock directly) but "how do we change the flows?" — reduce the inflow of new debt and increase the outflow of debt repayment.

Bad framing:  "We need to eliminate our tech debt."
              (Trying to change the stock directly.)

Good framing: "We need to stop adding tech debt at the current rate
               (reduce inflow) and allocate 20% of sprint capacity
               to paying it down (increase outflow)."

Delays

A delay is the gap between when you take an action and when you see the result. Delays are the single most important concept in systems thinking for engineers, because they cause most of the counterintuitive behavior in complex systems.

Action                              Visible result         Typical delay
---                                 ---                    ---
Hire a new engineer                 Increased productivity 3-6 months
Ship a new feature                  Revenue impact         1-3 months
Introduce a code review process     Fewer production bugs  2-4 months
Start writing documentation         Faster onboarding      6-12 months
Accumulate technical debt           Slowdown in shipping   6-18 months
Skip testing                        Production outage      Weeks to months
Invest in developer tooling         Faster development     3-6 months

Delays are dangerous because humans are bad at connecting causes to effects when there is a gap between them. When a team starts cutting corners in January and the outage happens in July, nobody connects the two. When an investment in tooling starts in Q1 and the productivity gain appears in Q3, the temptation is to cancel the investment in Q2 because "it's not working."

Why You Cannot Fix a Slow Team by Hiring

The most common example of delay blindness in engineering management is the belief that hiring solves velocity problems. The reasoning seems sound: more engineers equals more output. But it ignores the delay.

Month 1: You hire 3 engineers to speed up the team of 5.
Month 2: The 5 existing engineers spend 30% of their time
          onboarding the new hires. Velocity drops.
Month 3: New hires are starting to contribute but still
          asking questions. Net velocity is roughly flat.
Month 4: New hires are at ~50% productivity. The team is
          starting to recover.
Month 6: New hires are at ~80% productivity. The team is
          finally faster than before the hiring.

For six months, hiring made the team slower. If the deadline was in three months, hiring was the wrong intervention. This is Brooks's Law — "adding manpower to a late software project makes it later" — and it is a direct consequence of the delay between hiring and productivity.

The stocks-and-flows view makes this clear:

Stock: Team productivity
Inflow: New hires ramping up (delayed by 3-6 months)
Outflow: Existing engineers' time diverted to onboarding (immediate)

The outflow hits immediately. The inflow takes months.
The stock (productivity) drops before it rises.

The Bathtub Analogy

Meadows used the bathtub as the simplest illustration of stocks, flows, and delays. The water level (stock) is determined by the faucet (inflow) and the drain (outflow). You cannot change the water level by looking at it. You can only change it by adjusting the faucet and the drain.

This maps directly to engineering situations:

Situation: "Our bug backlog is growing."

Stock: Bug count
Inflow: New bugs discovered (from shipping code, from users reporting)
Outflow: Bugs fixed

Options:
  1. Increase outflow: Dedicate more engineers to bug fixing.
  2. Decrease inflow: Improve code quality so fewer bugs ship.
  3. Both.

Option 2 has a delay (better code quality takes months to show results)
but is more sustainable. Option 1 is immediate but does not solve the
root cause — bugs will keep flowing in.
Situation: "Our deploy pipeline is getting slower."

Stock: Pipeline duration
Inflow: New tests, new build steps, new checks
Outflow: Optimization, parallelization, pruning

If inflow exceeds outflow, the pipeline will keep getting slower.
You cannot fix it once — you need a sustained outflow that matches
or exceeds the inflow.

Delays in Feedback Loops

Delays interact with feedback loops (covered in the next subtopic) to produce oscillation — the system overshoots in one direction, then overcorrects in the other.

Example: Scaling a service

Minute 0:  Traffic spikes. CPU at 90%.
Minute 1:  Auto-scaler detects high CPU. Requests new instances.
Minute 5:  New instances are provisioning. CPU still at 90%.
            Requests are queuing.
Minute 8:  New instances come online. CPU drops to 30%.
Minute 10: Auto-scaler detects low CPU. Terminates instances.
Minute 12: CPU back to 90%. Auto-scaler requests instances again.

The delay between "request instance" and "instance is serving traffic"
causes oscillation. The fix: longer cooldown periods, predictive
scaling, or pre-warming.

This same pattern appears in hiring (over-hire, then freeze, then over-hire again), in incident response (over-rotate on prevention, then relax, then over-rotate again), and in process adoption (add too many rules, then rebel against rules, then add them back).

Practical Applications

Capacity Planning

Stocks:  Server capacity, database connections, storage
Flows:   Traffic growth (inflow), optimization efforts (outflow)
Delays:  Procurement (weeks), provisioning (hours), optimization
          impact (days to weeks)

Key insight: If traffic is growing at 10% per month and provisioning
takes 4 weeks, you need to start provisioning when you have 4 weeks
of headroom, not when you run out.

Team Building

Stocks:  Team capability, institutional knowledge, morale
Flows:   Hiring, training, attrition, burnout
Delays:  Onboarding (months), training ROI (months), burnout
          (slow accumulation over months, sudden departure)

Key insight: By the time someone quits from burnout, the damage
was done months ago. The stock (morale) was draining slowly.
The delay between the cause (overwork) and the visible effect
(resignation) makes it hard to intervene in time.

Technical Debt

Stocks:  Total debt burden, developer velocity
Flows:   New debt added per sprint, debt paid down per sprint
Delays:  Debt's impact on velocity (months to years — the codebase
          gets subtly harder to work with over time)

Key insight: Technical debt has an unusually long delay. The
shortcuts you take today slow you down in 6-18 months. By then,
nobody remembers the shortcuts. They just know the codebase is
"slow to work in." The cause is invisible because the delay
hides it.

Common Pitfalls

  • Ignoring delays — assuming that actions produce immediate results. Hiring does not immediately increase velocity. Process changes do not immediately improve quality. Budget for the delay.
  • Confusing stocks with flows — "We fixed 50 bugs this month" (flow) does not tell you whether the bug backlog (stock) grew or shrank. You also need to know how many new bugs were filed.
  • Optimizing flows without checking stocks — improving the deployment flow without checking whether the stock of deployable code is keeping up. Or improving hiring flow without checking whether the stock of team knowledge is growing.
  • Intervening during the delay — starting an initiative, seeing no results during the expected delay period, and canceling it before it has time to work. Tooling investments and culture changes are especially vulnerable to this.
  • Linear thinking about non-linear stocks — assuming that doubling the inflow doubles the stock. It does not when there are capacity limits, feedback loops, or diminishing returns.

Key Takeaways

  • Stocks are things that accumulate (tech debt, knowledge, user base). Flows are rates of change (hiring rate, churn rate, deploy frequency). Delays are the gaps between actions and results.
  • You cannot change stocks directly. You can only change the flows that feed them. Frame problems in terms of flows, not stocks.
  • Delays cause most of the counterintuitive behavior in engineering systems. Hiring has a delay. Quality investments have a delay. Technical debt has a very long delay.
  • Brooks's Law is a delay problem: the outflow of mentoring effort is immediate, but the inflow of new productivity is delayed by months.
  • When you take an action and do not see immediate results, ask whether you are in a delay period before changing course.
  • The bathtub model applies to most engineering situations: identify the stock, the inflows, the outflows, and the delays.