When resources are abundant, bad assumptions can survive for a surprisingly long time.
You can waste money, people, energy, materials, computing power, or time—and still get the job done.
Scarcity is different.
When resources are limited, dependencies become visible.
A missing component can stop an entire system. A shortage of fuel can make a factory useless. A lack of skilled workers can make sophisticated technology irrelevant. A broken supply chain can turn abundant raw materials into unusable inventory.
This is why first-principles thinking becomes especially valuable under resource constraints.
But there is another powerful tool that is often overlooked:
History.
History gives us thousands of examples of humans solving problems with limited resources, incomplete information, technological constraints, political constraints, and unexpected failures.
The trick is not to copy historical solutions.
The trick is to understand why those solutions worked.
History as a database of experiments
A common mistake when studying history is asking:
"What did they do?"
A better question is:
"What constraint were they facing, what resources did they have, what dependencies existed, and what mechanism allowed them to succeed?"
Consider a society facing a shortage of a critical material.
There are several possible responses:
- find more of the material;
- substitute another material;
- redesign the product;
- reduce consumption;
- recycle the material;
- change the production process;
- eliminate the requirement entirely.
The interesting lesson is not necessarily which solution was selected.
The deeper lesson is that scarcity changes the design space.
History repeatedly shows people solving resource problems by changing the system rather than simply trying to obtain more of the scarce resource.
That is a first-principles insight.
First principles: strip the problem down
First-principles thinking means reducing a problem until we reach fundamental constraints.
Instead of saying:
"We need more servers."
Ask:
"What capability do the servers provide?"
Perhaps the actual requirement is:
"We need to process 10 million events per hour."
That immediately creates more options.
Maybe we can:
- reduce computation;
- cache results;
- process asynchronously;
- compress data;
- eliminate unnecessary events;
- distribute workloads;
- change the algorithm;
- use cheaper hardware;
- process only information that actually matters.
The original solution—"more servers"—was merely one implementation.
The underlying requirement was different.
This distinction is critical.
First principles separate needs from implementations.
Scarcity is a forcing function
Scarcity can be painful, but it has an intellectual advantage.
It forces us to ask:
What is actually necessary?
When resources are unlimited, systems accumulate unnecessary dependencies.
A product might depend on:
- five external APIs;
- three vendors;
- expensive infrastructure;
- specialized personnel;
- proprietary software;
- continuous internet access;
- a particular supply chain.
Everything works—until one dependency fails.
Then the hidden structure becomes obvious.
This is one of the most important lessons from scarcity:
A system's real complexity is often determined by its dependencies, not by its visible components.
The missing skill: dependency thinking
Most people naturally think in lists.
They see:
A, B, C, D, E.
But systems are rarely lists.
They are graphs.
For example:
┌── Supplier A
│
Raw Material ───────┤
│
└── Supplier B
│
▼
Component X
│
▼
Assembly Y
/ \
/ \
Software Energy
│ │
└────┬──────┘
▼
Product
The important question is not simply:
"What components do we have?"
It is:
"What depends on what?"
That is the beginning of dependency-graph thinking.
Why dependency graphs matter
Suppose a system has 100 components.
At first glance, losing one component sounds like a 1% problem.
It might not be.
If that component sits at the root of several critical dependencies, its failure could stop the entire system.
Conversely, another component might represent 20% of the physical material but be easily replaceable.
Therefore:
Importance is not proportional to quantity.
A tiny dependency can have enormous system-level importance.
This applies everywhere:
| Domain | Hidden dependency |
|---|---|
| Software | Library → application |
| AI | Model → GPU → electricity → cooling |
| Manufacturing | Product → component → supplier |
| Agriculture | Crop → fertilizer → minerals → energy |
| Healthcare | Drug → active ingredient → chemical precursor |
| Business | Revenue → customer → payment infrastructure |
| Government | Service → personnel → infrastructure → funding |
| Personal productivity | Goal → skill → tool → time |
Dependency analysis exposes the bottlenecks.
History becomes more useful when represented as a dependency graph
Imagine studying a historical technological achievement.
The superficial approach is:
"They invented X."
The deeper approach is:
Achievement
↓
Required capability
↓
Required technology
↓
Required materials
↓
Required energy
↓
Required infrastructure
↓
Required knowledge
↓
Required institutions
Now we can ask much better questions.
Which dependency was the hardest?
Which dependency was scarce?
Which dependency was substituted?
Which dependency was eliminated?
Which dependency was brought under local control?
Which dependency became a bottleneck?
Which dependency failed?
This transforms history from storytelling into systems analysis.
The most valuable historical lesson: solve constraints, not appearances
Suppose a historical society solved a transportation problem using technology that no longer exists.
Copying the technology may be useless.
But suppose we discover that the real constraints were:
- low energy availability;
- expensive materials;
- limited manufacturing precision;
- poor communication;
- difficult terrain.
Now we can transfer the principles.
A modern solution might look completely different while solving the same fundamental constraints.
This gives us an important rule:
Do not copy historical solutions. Extract historical constraints and mechanisms.
History provides the experiments.
First principles provide the abstraction.
The dependency graph provides the structure.
Together, they allow us to transfer knowledge into unfamiliar environments.
Hypothetical new challenges
This becomes especially powerful when facing problems that have no historical precedent.
Consider a hypothetical future problem:
A remote settlement must operate for ten years with extremely limited imports.
There may be no historical example that exactly matches this situation.
So copying history directly will fail.
Instead, construct the system from first principles.
Start with fundamental needs:
Survival
├── Food
├── Water
├── Energy
├── Shelter
├── Healthcare
├── Manufacturing
└── Knowledge
Then decompose each dependency.
For example:
Food
├── Water
├── Seeds
├── Nutrients
├── Energy
├── Labor
├── Tools
└── Knowledge
Then decompose again.
Energy
├── Generation
├── Storage
├── Conversion
├── Maintenance
└── Replacement parts
Now something interesting appears.
The problem is no longer:
"How do we survive for ten years?"
It becomes:
"Which dependencies must remain available continuously for ten years?"
That is a much more tractable question.
Dependency graphs reveal bottlenecks
A dependency graph lets us classify components.
1. Independent components
Failure has limited consequences.
2. Replaceable components
There are multiple ways to satisfy the requirement.
3. Critical components
Their failure disrupts important functions.
4. Root dependencies
Many parts of the system depend on them.
5. Single points of failure
There is no practical alternative.
These are the components we should worry about first.
A system with thousands of components may actually depend critically on only a handful.
That is where limited resources should be concentrated.
Resource allocation should follow dependency importance
This changes how we think about scarce resources.
The naive approach is:
"Spend resources where there is the most demand."
The better approach is:
"Spend resources where failure propagates the most."
Imagine two components:
Component A
- consumes 50% of the budget;
- easy to replace;
- failure affects one subsystem.
Component B
- consumes 2% of the budget;
- impossible to replace;
- failure disables five major subsystems.
Component B deserves disproportionate attention.
This is why dependency graphs are useful for:
- redundancy;
- inventory;
- emergency planning;
- infrastructure;
- software architecture;
- supply chains;
- military logistics;
- business continuity;
- energy systems;
- AI infrastructure.
Scarcity should encourage dependency reduction
There are three broad ways to deal with a critical dependency:
Acquire more
Increase supply.
Create redundancy
Find multiple ways to satisfy the requirement.
Eliminate the dependency
Redesign the system so the requirement disappears.
The third option is often the most powerful.
For example:
Original system
Product
↓
External API
↓
Internet
Possible redesign:
Product
↓
Local computation
The goal is not merely to find a backup API.
The deeper solution is to remove the dependency altogether.
The historical pattern of substitution
One of the most transferable lessons from history is substitution.
When a critical resource becomes scarce, successful systems often change one of four things:
Material → substitute material
Process → substitute process
Technology → substitute technology
Requirement → eliminate requirement
The last one is frequently overlooked.
Instead of asking:
"How can we obtain more of X?"
ask:
"Why does the system require X in the first place?"
That question can produce radically different solutions.
Dependency graphs also expose false complexity
Sometimes a problem looks extremely complicated because we are looking at its implementation rather than its structure.
Suppose a system contains 500 modules.
That sounds terrifying.
But perhaps the dependency graph looks like:
Core capability
/ | \
A B C
/ | \ | / \
D E F G H I
The real question is not:
"How do we understand all 500 modules?"
It is:
"Which nodes control the largest portions of the graph?"
This is where graph analysis becomes a thinking tool rather than merely a technical tool.
A practical framework
When facing an unfamiliar challenge, use this sequence.
Step 1 — Define the objective
What must actually be achieved?
Not the conventional solution.
The actual outcome.
Step 2 — Identify fundamental constraints
What cannot be changed?
Examples:
- energy;
- time;
- materials;
- physics;
- geography;
- human attention;
- money;
- computation;
- knowledge.
Step 3 — Decompose the objective
Break the objective into capabilities.
Step 4 — Build the dependency graph
For every capability, ask:
"What does this require?"
Then repeat until reaching fundamental resources or assumptions.
Step 5 — Find bottlenecks
Identify:
- single points of failure;
- scarce resources;
- highly connected nodes;
- long dependency chains;
- difficult-to-replace components.
Step 6 — Search history
Look for historical situations with similar constraints, not necessarily similar technologies.
Step 7 — Extract mechanisms
Ask:
What principle allowed that solution to work?
Step 8 — Generate alternatives
For every critical dependency:
- acquire it;
- substitute it;
- stockpile it;
- create redundancy;
- reduce consumption;
- eliminate it.
Step 9 — Stress-test the graph
Remove important nodes mentally.
Ask:
"What happens if this disappears?"
This is where resilience becomes visible.
The deeper idea
First-principles thinking and historical thinking are often treated as separate intellectual tools.
They are actually complementary.
History gives us evidence.
It shows what humans attempted under real constraints.
First principles give us abstraction.
They allow us to separate fundamental mechanisms from historical circumstances.
Dependency graphs give us structure.
They show how resources, capabilities, technologies, and assumptions interact.
Together:
Historical evidence
↓
Identify constraints
↓
First-principles abstraction
↓
Dependency graph
↓
Find bottlenecks
↓
Generate alternatives
↓
Test against new challenge
This is particularly powerful for problems that have never existed before.
We cannot search history for an exact answer to a genuinely new problem.
But we can search history for similar constraints.
That is the difference.
The ultimate question
When resources are scarce, the most useful question is not:
"What should we build?"
It is:
"What must remain true for the system to work?"
Once we know that, we can work backward.
What does that condition depend on?
And what does that depend on?
Continue until the dependency graph reaches fundamental constraints.
Then attack the graph.
Remove unnecessary dependencies.
Create substitutes.
Build redundancy around critical nodes.
Reduce consumption.
Localize fragile dependencies.
And, whenever possible, redesign the system so that the scarce resource is no longer required.
That is the real power of first-principles thinking under scarcity.
History tells us what has already been tested.
First principles tell us what is fundamental.
Dependency graphs tell us where the system can break.
And when those three are combined, even a completely new challenge becomes something we can reason about systematically.
Top comments (0)