Every abstraction is a loan
You borrow simplicity today and repay it in understanding later.
An abstraction lets you stop thinking about something. That is its entire value. An ORM lets you stop thinking about SQL. A framework lets you stop thinking about routing. A cloud service lets you stop thinking about machines. Each one hands you time you would otherwise have spent on detail.
But the detail did not disappear. It was deferred. Somewhere, the thing you stopped thinking about is still happening, and one day it will behave in a way your abstraction did not predict. On that day, you pay back the loan, usually at the worst possible moment and with interest.
Interest compounds in layers
One abstraction is cheap to see through. Five stacked abstractions are a different problem. When a query is slow in a system with an ORM on top of a connection pool on top of a proxy on top of a managed database, the debugging session begins with archaeology. Each layer was a reasonable decision. Together they form a debt nobody remembers signing.
This is not an argument against abstraction. Software without abstraction is just a longer way of writing assembly. It is an argument for borrowing deliberately. Before adopting a layer, ask what it will cost to understand the layer beneath it when things go wrong, and whether anyone on the team can actually pay that cost.
Good abstractions have escape hatches
The abstractions worth borrowing are the ones that let you step outside them without tearing everything down. A query builder that lets you drop to raw SQL. A component library that lets you override a style without forking. These are loans with flexible terms.
The bad ones are total: they own the whole stack and offer no way down. They feel wonderful in the first month. They feel like a mortgage in the second year.
Who holds the debt
The cruel part of abstraction debt is that the person who borrows is rarely the person who repays. The engineer who adopted the clever framework has often moved on by the time its edge cases surface. The repayment falls to whoever is on call, usually someone who never chose the layer and has no context for why it exists.
This changes how a team should think about adoption. A new dependency is not a personal productivity tool. It is a liability shared with every future maintainer. The question is not whether you can understand it today, but whether a tired person at two in the morning, a year from now, can understand it well enough to fix a production incident.
The healthiest teams I have seen treat this explicitly. They keep a short list of the layers they depend on and who understands each one. When nobody understands a layer anymore, that is treated as a risk, not a curiosity. Either someone learns it properly, or the team plans its removal before the debt is called in.
Borrowing is how anything ambitious gets built. Just know the terms, and write them down where the next person will find them.