Abstractions are the backbone of modern software engineering. Layers, interfaces, ORMs, frameworks, SDKs — they help us build complex systems faster. But every abstraction hides part of the underlying reality. And eventually, that reality leaks.
That’s exactly what Joel Spolsky wrote about in his classic article "The Law of Leaky Abstractions":
All non-trivial abstractions, to some degree, are leaky.
This principle is more than a pragmatic observation — it’s a warning. And it reminded me how my background in physics helped me understand not only the power of abstractions, but also their limits.
In physics, we build mathematical models to represent real-world systems. These models are abstractions — simplifications that hold true under specific conditions. Like any abstraction, they have boundaries. The key difference is that in physics, models are constantly tested, and when they fail, we refine or discard them. And we can only do that because we deeply understand the foundations beneath the abstraction.
That’s the parallel I want to draw: abstractions make us move faster. But it’s a deep understanding of fundamentals that allows us to go further — in science, and in software.
Drawing the Parallel with Physics
In physics, there’s a fundamental principle: the laws of nature should behave the same in all inertial reference frames — meaning they must remain consistent whether you're at rest or moving at a constant speed. That consistency gives us the confidence that our models are “portable” across different conditions — up to a point.
Einstein took this idea further with the Theory of Relativity, showing that even light and electromagnetism must obey this invariance. The result? A more robust model of space and time capable of explaining extreme phenomena.
In software engineering, we create abstractions expecting them to be equally “portable” — to work across business contexts, deployment environments, and traffic loads. But just like in physics, that portability breaks down under certain conditions. An abstraction that works well in a monolith might completely fail in a distributed system. A solution that behaves perfectly in development might crumble in production under load. That’s like moving from Newtonian physics into the relativistic realm.
And this is where fundamentals matter most: understanding what lies beneath the abstraction allows us to know when it will fail — and how to fix it.
Context Shifts: When Abstractions Break
In software, abstractions take the form of layers, interfaces, APIs, and frameworks. These are our models — tools we use to tame complexity. But, just like in physics, these abstractions aren’t universal. They work well within certain "frames of reference" — but when the context shifts, they often fall apart.
A clear example is ORMs (Object-Relational Mapping). These frameworks abstract database access, letting developers work with objects instead of writing SQL. That abstraction boosts productivity and removes boilerplate. But once performance issues arise — a slow query, a deadlock, or an N+1 problem — the abstraction leaks. And suddenly, the only way out is knowing SQL and how relational databases work under the hood. Worse yet, some abstractions lock you into their internal models, making it harder to optimize or even change technologies.
Another classic case is HTTP. It abstracts over TCP/IP beautifully and works well for most web applications. But for real-time scenarios — online games or live chat systems — traditional HTTP’s stateless, synchronous nature becomes a bottleneck. In those cases, you need to turn to WebSockets or gRPC. The abstraction, once reliable, becomes insufficient outside its intended context.
These examples show that just like with physical models, software abstractions hold — until you switch context. And then, only the fundamentals will guide you forward.
Abstractions Make You Faster. Fundamentals Take You Further.
Abstractions help you fly faster. But when the storm hits, it’s fundamentals that keep the plane from falling.
Abstractions are indispensable. They let us build faster and iterate quickly — especially in today’s hyper-competitive, delivery-driven market. But they’re tools, not magic. They don’t remove complexity — they hide it.
And when that complexity resurfaces (it always does), your grasp of the fundamentals is what makes the difference.
Knowing how the file system works, how an HTTP request is routed through your app stack, or how a query is actually executed in the database might seem distant from your daily routine — until something breaks. And once it breaks, the shortcut provided by the abstraction is no longer enough.
That knowledge isn’t just for firefighting — it’s what enables you to design better systems, anticipate failures, and make smarter architectural decisions.
Real-World Examples?
- An engineer who understands TCP can build systems that are resilient to packet loss, even when using HTTP or gRPC.
- Someone who understands index structures and search algorithms can optimize queries beyond what any ORM can offer.
- Deep knowledge of memory management in Go can help avoid GC-induced latency spikes in real-time systems.
The point is not to reject abstractions. Quite the opposite — use them intentionally. Understand that the speed they offer is only sustainable if you know what lies beneath.
Abstractions build the race car. Fundamentals pave the track.
Conclusion
Mastering fundamentals isn’t just about writing bug-free or optimized code. It’s about adopting a different mindset. Just like in physics — where concepts like time or mass behave counterintuitively in different reference frames — software fundamentals train you to question assumptions.
Abstractions matter — but they shouldn’t be shields against understanding. They should be bridges. Tools to accelerate, not crutches to hide behind.
So here’s my final invitation: cultivate technical curiosity. When an abstraction breaks down, don’t see it as a failure — see it as an opportunity to learn what most people never explore. When everyone’s looking at the framework, look underneath. That’s where the lasting insights are.
When in doubt, ask: what is this abstraction hiding from me?
And be willing to find out.