
WM Talks: A business approach to technical debt
Topics covered:
What are the causes of technical debt in projects, what are its technical aspects, and can it be beneficial?
This is what was discussed in the latest episode of the WM Talks podcast by Paweł Kaźmierczak - Project Manager, Damian Maślanka - CTO, and Szymon Kania - CEO.
Paweł: Hi, this is Paweł Kaźmierczak. Today, I have the pleasure of hosting another episode of the WM Talks podcast series. My guests are Damian Maślanka and Szymon Kania. Today, we will have the opportunity to talk a bit about technical debt - what it actually is and how it affects running a business in the IT industry. Maybe first, let's explain to our listeners what technical debt actually is, because from my experience, this is not an obvious concept for everyone. How can we explain this term in the simplest way so that everyone understands it?
Damian: As the name suggests, debt - if we take financial debt as an example - means an obligation, something that was taken on earlier for the sake of the future. When it comes to technical debt, the analogy is similar. At some point, we take on an obligation while building a project, assuming that we will fix it in the future. This happens when, during a certain project stage, some simplifications are made, certain procedures are skipped, just to, for example, push the project forward more quickly or save resources for other functionalities. Over time, this debt is either repaid, or it keeps growing, which eventually leads to a situation where - just like in real life - financial obligations can overwhelm some entities. The same happens with technology. If technical debt grows too much, it may reach a point where the project itself becomes unstable and stops fulfilling its purpose.
Paweł: So, putting it in financial terms, the similarity is that when we take on financial debt, we must take into account that every feature has a cost in terms of developer time. Poorly written code will generate additional costs in the future because a developer will have to spend time refactoring, improving, and fixing issues, which all lead to additional financial expenses.
Damian: Yes, earlier, I simplified it a bit, comparing debt to development needs, but it's not always that simple. Often, and perhaps even more often, technical debt arises naturally because of team competence levels - it forms by itself, sometimes without people even realizing it. You can compare it to owning a house and neglecting regular renovations. The house still functions at a basic level, but as we know, after 20–30 years, a neglected, unrenovated house starts showing signs of wear. The same happens with software projects. If we ignore regular refactoring, code optimization, and updating libraries with new versions, after a few years, the project reaches a stage where it resembles an old, neglected house.
Paweł: Okay, so summing it up - if we don't take care of a project regularly, and just like with house renovations, we don’t update or optimize certain parts of the code, we may reach a point where we have to redo something entirely from scratch. This leads me to a question - when facing such a situation, does it make sense to continue developing old code, or is it better to write a new application from scratch?
Damian: Again, referring to the house analogy, this can go either way. From a technical perspective, sometimes it's still possible to save a structure, even if it requires significant costs, but there's a reason to do so. Similarly, with projects - sometimes, despite a huge technical debt, there’s still a way to bring the code to an acceptable state. However, in the tech world, things change rapidly. Unlike in the real world, where a house deteriorates over decades, technology evolves so fast that a few years of neglect can be equivalent to decades in another industry. More often than not, the process ends with the decision to "tear down the building" and rebuild the project from scratch.
Szymon: You can compare this to financial debt spiraling out of control. If there are too many neglected areas in a system, the debt grows at an accelerating rate. As Damian mentioned, this leads to a point where the only solution is to demolish everything and rebuild the system from the ground up. However, this is not a one-size-fits-all answer - each situation requires thorough analysis. The decision must be made based on a business evaluation: is it more profitable to refactor and gradually repay the technical debt, or is it ultimately cheaper and more forward-thinking to rewrite the system from scratch? For example, if an application is based on outdated technology and even updating a framework or libraries is impossible, then starting fresh is often the best business choice.
Paweł: Now, I would like us to talk about the causes of technical debt. What directly or indirectly influences its creation in code?
Damian: From my experience, it is mostly about simplifications. Often, developers working on a project, in order to speed up their work, skip certain procedures. They don’t ensure that a given function is written according to standards. However, this is not entirely their fault, as this can stem directly from the client, who puts strong time pressure on the team, expecting fast progress while not allocating a budget that would allow for a larger development team. A developer then finds themselves in a situation where they have to simplify certain things, meaning they don’t implement them according to best practices. And this is like stacking bricks - one on top of another - until we end up with a structure that is far from how it should look from a technological standpoint. Another factor is working with the wrong people in a project or even the wrong companies. Due to cost-cutting measures or miscalculations in their own competencies, they may not create high-quality code. They think the code is fine, but in reality, it’s not, and as time goes on and more code accumulates, it becomes what we call "spaghetti code" - a tangled mess that is hard to manage. As long as there are no experienced people on the team or a competent company to take care of it, there may be no awareness that technical debt exists at all. Of course, there are signals - such as excessive time required to develop new modules or a drastic decrease in application performance - but these are indirect indicators that are not always associated with technical debt. It often takes an external perspective to pinpoint that the root cause is technical debt.
Szymon: It’s also worth mentioning that sometimes technical debt is taken on intentionally, and that’s not always a bad thing. There are cases where work on a project is so dynamic and the timeline so tight due to business factors that some technical debt is consciously accepted, with the plan to repay it later. For example, after launching a phase of a project, when it starts gaining users, there may be a quieter phase where it becomes possible to address and pay down the technical debt. This is similar to the financial market - taking on debt is not always bad. Taking out consumer loans can be risky, but an investment loan can be a smart business move. Similarly, consciously taking on technical debt can be a good strategic decision, as long as there is a plan for managing and repaying it.

Damian: Continuing with the financial analogy, the key is to be mindful of the debt you’re taking on. The critical part is having a plan for repaying it. If there is no plan, and debt keeps piling up with the thought that "we’ll clean it up later," but that never happens, you enter a spiral of increasing debt. Just like in finance, this can reach a point where there’s no turning back, and the only way out is a drastic restructuring - or in the case of software, a complete rewrite of the system.
Paweł: That is, pay off there one loan, another and so on and get so wrapped up?
Szymon: Yes, you could compare it to patching one hole by creating another - just layering band-aids on top of an existing band-aid. That never ends well. Eventually, it leads to a point where a decision must be made to build a new system entirely. We’ve seen these cases firsthand. It’s difficult to tell a client that after investing so much time and money into a system, the best option is to throw it away and start over. But unfortunately, sometimes that’s the reality. If technical debt has reached a point where maintaining and extending the system is no longer feasible, rewriting it from scratch is the only reasonable path forward.
Paweł: Exactly. To sum up what we’ve discussed so far, it’s crucial to focus on code quality and continuous optimization.
Damian: You could call it "supporting" the code - keeping it in good shape.
Paweł: Yes, making sure that what we’ve built remains maintainable and scalable. From a technical perspective, that means continuously organizing and improving the code, much like regularly renovating a house. It’s also crucial to consider project planning before development even starts. The competence of the team plays a big role, as Damian mentioned. If a developer lacks the necessary skills, they might write inefficient code, leading to accumulating debt. And as we discussed, sometimes taking on technical debt is a conscious decision - especially when launching an MVP (Minimum Viable Product), to test a product’s viability. But in that case, it’s a good idea to document the parts that will require future refactoring.
Szymon: This isn’t just relevant for MVPs. Even in full-scale projects, accelerating development sometimes requires making trade-offs. But, as Damian pointed out earlier, if there’s a plan in place, and it’s a structured process, it’s not necessarily a risk. The danger comes when things are done chaotically, without oversight, and without a plan to fix it later. Technical debt doesn’t immediately cause problems. It’s a long-term issue that can take months or years to manifest. But when it does, the consequences can be significant.
Damian: Technical debt should be treated as an ongoing process, not something that suddenly appears out of nowhere. It’s a continuous, long-term process that grows over time if left unchecked.
Paweł: Okay, now I’d like us to move on to technical decisions that contribute to the appearance of technical debt in projects. Can we point out some typical technical practices that lead to increasing debt? What are the symptoms of technical debt in code and infrastructure?
Damian: Yes, first of all, an incorrect choice of technology. From the very start, a project can be built with technical debt if we choose the wrong framework or library - one that hasn’t been updated for a long time, has been abandoned, or contains numerous bugs and security vulnerabilities. Another major factor is failing to keep dependencies up to date. Many teams neglect this aspect - new versions of frameworks and libraries are released, but no one ensures they are regularly updated. Eventually, the project ends up running on outdated software, which may no longer be supported or have known security flaws. Another common issue is a lack of proper documentation. Surprisingly, technical debt doesn’t only affect the source code. Documentation is also extremely important. If a team adds new functionalities or technologies to a project but doesn’t document them properly, the knowledge remains only in the heads of individual developers. Later, when new team members join the project - or even when the original developers return after a long time - there is no reference material to explain how certain elements work. This can significantly increase the time required for further development and maintenance. Proper documentation, updating dependencies, and carefully selecting technologies are key factors in minimizing technical debt. Additionally, code quality is crucial. This involves writing code according to best practices, maintaining clean architecture, and regularly reviewing and refactoring it. Code reviews, pair programming, and providing continuous feedback among developers help maintain high code quality. Relying solely on one person can be risky, as they may not be aware of mistakes they are making. A fresh perspective from another developer can reveal areas where improvements are needed. Technical debt can creep in at any level - from individual lines of code to high-level architecture. If a team neglects best practices at any stage, debt begins to accumulate.
Take care of the security of your system.
Paweł: Let’s go back to frameworks. When we design a product, can we be sure that a given framework won’t be abandoned by its creators after a few years? I once worked on a project where we had to rewrite the entire system due to massive technical debt. It was originally built in Visual Basic, which was last updated around 1998 and abandoned around 2006. For the developers who had to migrate the project, it was a nightmare - translating all the relationships, handling data migrations, and adapting old functionalities to modern technologies was incredibly difficult.
Damian: Here, unfortunately, there is no magic crystal ball that will indicate whether a given technology will survive on the market. And it’s not really fair to blame the person who chose that technology - unless it was already obvious at the selection stage that this technology had no future. I know from experience, from our PHP ecosystem, which we specialize in, that ten years ago there were many frameworks available. No one was really able to predict which of them would last longer on the market and become the stable framework. You could have chosen Zend, CodeIgniter, or other more niche frameworks, some of which simply no longer exist today. If someone made a good decision back then, for example, choosing Symfony or Laravel, then as long as the framework was regularly updated, technical debt is not such a big issue. So, it’s really difficult to predict, and I would caution against assuming that any technology is a safe bet. Instead, when choosing a technology, it's better to assess whether it is already at risk of becoming obsolete. Secondly, it’s important to consider its future prospects. Sometimes, you can get a sense of this from the developer community and general industry sentiment. Of course, we can never fully predict whether a completely new technology will emerge in five years and completely disrupt the market. However, taking this structured approach is still more rational than selecting something inherently uncertain from the outset. In the case of Visual Basic, when the client originally started their project, no one could have predicted that the technology would become obsolete. It’s not like a technology disappears overnight - there are always warning signs. At first, development slows down, then rumors start circulating that the technology might be abandoned. At that stage, it’s already a good idea to raise this issue with the client, making them aware that support for their chosen technology could end in the near future. This is when they should start considering migration options or at least ensuring that their system remains as secure as possible. Even if the client decides, "We’re not going to rewrite the whole project right now", they should at least take steps to extend the support for as long as possible, while simultaneously planning in the background for eventual migration of core functions. In the first year or two, an outdated technology may not seem like a major issue. But after several more years - or even a decade - it becomes a serious problem. It’s the same as the example with the developer looking at outdated code - when they see it, they might say, "This is completely unmanageable". At that point, documentation for the framework or language may no longer exist online, and finding any knowledge resources might be nearly impossible. And that’s when the real, serious problem begins.

Paweł: Okay, now I’d like to consider whether technical debt is always bad. Are there situations where taking on debt is strategically beneficial for a business? And what could be the benefits of short-term technical debt when we deliberately accept it because we want to launch something new on the market, we have a vision, and we want to turn it into a working product, but we have a limited budget?
Szymon: Technical debt is often a shortcut. It usually arises because of the need to speed things up. Now, if we’re talking about technical debt that was created to accelerate development and was planned, then it can be considered not necessarily bad. But if technical debt results from a lack of competence - as Damian mentioned earlier - then, by definition, it will be harmful because it doesn’t stem from a conscious decision to speed things up but from poor choices or lack of knowledge. For example, if from the start we select a technology that has already announced its end-of-life support, and we still go with it, then the problem isn’t technical debt - it’s a bad decision.
Damian: I’ll say this - let the first person who never received a task labeled "this has to be done by yesterday" throw the first stone. In such cases, taking on technical debt is absolutely justified. You have two options: either you don’t deliver the task at all because you need to go through a full development cycle and do it properly, or you take shortcuts, simplify things, and deliver it within an unrealistic deadline. The important thing is that after this pressure is gone, you take the time to sit down and refactor the code.
Szymon: The worst thing you can do is pretend that the problem doesn’t exist and ignore it because of time constraints.
Damian: That’s a conscious decision. Another scenario where technical debt is not harmful is when dealing with legacy projects that are stable and well-secured. In such cases, even if the code is outdated, the system is stable, and additional security layers ensure it won’t suddenly break, then it’s often better not to touch it. If there is no business, logical, or technological reason to refactor or rewrite it, then sometimes the best approach is simply to let it run as it is.
Paweł: So, if it works, don’t touch it?
Damian: Yes, accept the debt and let it function, provided that at some point, it doesn’t require extensive modifications or continuous updates. If the project transitions from being legacy to active development again, then there’s no excuse anymore - it needs to be modernized.
Szymon: Especially during migrations - because often, when moving to a new system, the old system still needs to function for a certain period. In such cases, fighting against technical debt, trying to refactor everything in a system that is already planned for decommissioning, just doesn’t make sense.
Paweł: I’d like to go back to those "this needs to be done by yesterday" tasks because this is an interesting issue. Business has a huge influence on technology, and if we keep assigning these "done by yesterday" tasks due to shifting priorities, we may run into trouble. Often, in production environments, we see this pattern: on the one hand, customers expect new features to be delivered quickly; on the other hand, they report bugs that also need to be fixed. These tasks accumulate. As a result, we can end up in a situation where, for example, a project manager approaches the developers and says, "This needs to be delivered ASAP, it was due yesterday, it’s critical." But from a technical perspective, how can we make the business side aware that, "Hey, we can’t ignore this, because in X amount of time, this functionality will cause serious issues"?
Damian: It’s important to have someone in the role of a Tech Lead, someone who oversees the technology team and ensures that such issues are flagged. This person should not only signal when technical debt is increasing but also document it and systematically remind the client that a budget must be allocated for repaying this debt. If that doesn’t happen, the debt will continue to accumulate, leading to increasing development difficulties. And ultimately, this will mean a growing number of issues, slower development, and reduced stability.
Paweł: Okay, and what about situations where we are maintaining an existing production system, and there are many customer reports? For example, fixing one bug in one module leads to additional problems in other parts of the system. How should we react in such cases?
Damian: That actually contradicts the idea of a legacy project because, for me, a legacy project is one that has already gone through its debugging phase. If a system has been running for a long time and is stable, then occasional bugs may appear - but these should be rare. Of course, there is no such thing as completely bug - free software, and after a while, some issues may surface. But then, it becomes a business calculation. If fixing a bug takes only a fraction of the time that the system has been operating successfully, while rewriting everything would be a major investment, then from a business perspective, it makes sense to patch the issue rather than rebuild the entire system. However, if such situations happen repeatedly and new issues keep emerging, then we should reconsider whether we are really dealing with a legacy system-or whether it’s actually an actively developed product that just hasn’t been properly maintained.
Szymon: It’s all about setting the right expectations and choosing the right approach. If we call a project "legacy" and assume it’s in maintenance mode, but at the same time, we continue actively developing new features, then these two approaches contradict each other.
Paweł: Yes, let’s assume that no decision has been made yet about rewriting the application in a new technology, and we still have to maintain it somehow.
Szymon: In that case, the best approach is to find a middle ground. Trying to eliminate all technical debt and refactor everything might be completely unrealistic - and often not justified from a business standpoint. On the other hand, allowing technical debt to grow uncontrollably will eventually lead to a crisis, where a full rewrite becomes unavoidable. And having to make that decision under time pressure is never a good situation to be in. After all, as we’ve mentioned, technical debt is often the result of time constraints and the need for quick fixes.
Paweł: Exactly. And I see a strong analogy here with startups. In many startups, the primary focus is rapid growth and increasing sales. There’s little to no time for thinking about clean code or properly organizing technical processes. The same applies to documentation - often, there’s just no time for it. In many cases, a small group of developers keeps the entire architecture in their heads. And then, a serious problem arises when one of them decides to leave.
Damian: That’s why the statistic says 9 out of 10 startups fail, right?
Szymon: Well, you could put it that way.
Damian: Business challenges and whether the idea itself was viable are one thing. But many startups fail simply because they can’t handle the weight of their own technical debt. Adding new features takes longer and longer, and investors start to notice. At the same time, system performance drops, which begins to drive users away. These statistics exist for a reason. Startups often experience explosive growth, fueled by investments and enthusiasm. But then, they hit a wall - because their technology is poorly structured and they can’t scale properly.

Paweł: Yes, because this brings us to the issue of how technical debt impacts the development of our application, our product. And here’s something interesting that you both mentioned - we may hit a wall at some point, where even adding a new feature results in getting buried under a pile of existing bugs and issues, which are interconnected with other functionalities. I’ve experienced this myself - a valuable lesson from working in a startup. But ideally, we want the product to remain alive and profitable.
Damian: Let me add to that - one of the consequences of technical debt is a lack of long-term thinking. Even if a legacy project is currently functioning well, we never know if, over time, it will accumulate such a large database that it becomes unstable. I think this is also a major challenge for startups. Even if their product works efficiently, when it suddenly gains traction and attracts a much larger number of users, the fragility of its architecture becomes apparent. And even if we’re not dealing with a quality-related debt per se, we might still have performance debt - where certain optimizations were never done. Eventually, this kind of system can collapse under its own weight.
Paweł: Okay, and speaking of architectural mistakes - have you come across, or heard of, false trends in IT that led to many companies making the wrong choice when designing their system architecture? I’ve encountered projects where poorly planned architecture became an issue. However, in some cases, it was possible to gradually work out of this debt - taking small steps, making long-term improvements, and ensuring the business continued to thrive. But a big part of this was the client's awareness of the issue. With proper planning ahead of time, businesses can manage technical debt wisely and come out of it in a sensible way.
Szymon: Looking at it from a different angle - and I might be stirring up a hornet’s nest here - this reminds me of a conversation I had today with a client. It was about how a poor choice of technology or approach can come back as serious technical debt. And I say hornet’s nest because these technologies are growing rapidly and are becoming increasingly popular. I’m talking about no-code, low-code. In many cases, they can be a great choice - a solid direction. But there are also situations where, after some time, you hit a wall. For example, performance issues-where the chosen platform lacks proper scalability. At a certain level, performance starts to degrade, and there’s no way to fix it because we don’t have access to the code. Or another scenario - at first, a specific functionality wasn’t considered necessary, but later on, users start demanding it. And suddenly, it turns out that implementing it on that platform is much more difficult than expected. We reach a limit where something is simply impossible to do. Of course, I’m generalizing a bit-because in the end, everything depends on choosing the right platform and ensuring it fits the project’s needs. But this is a real-world example-as I said, something I discussed with a client today. A strategic mistake made at the planning stage can start causing problems very quickly. And in the end, this can lead to the entire project needing to be rewritten from scratch, using classic technologies.
Damian:For me, one of the most critical mistakes happens when the person choosing the technology doesn’t think ahead. If they don’t ask the client about their project’s estimated scale in different scenarios-pessimistic vs. optimistic-then they are failing to plan properly. Many technologies can be chosen wisely if we base our decision on real predictions. For example, if we know that the client expects to have millions of records in a database, but we never test whether the chosen database can handle such volume efficiently, then we are already making an architectural mistake. We should always choose technology based on performance needs-how quickly we need to fetch and process data, and what our storage capabilities are. A few years ago, non-relational databases became hugely popular-they were the hottest trend. But that wasn’t always the right choice. Again, there are two sides to every decision. Yes, we can select a high-performance database that handles large data volumes well-but what if the project doesn’t actually need that? Over time, an unnecessary technology choice can cause more harm than good. That’s why we always need to think ahead-and ask ourselves whether we will truly make use of a given technology’s full potential.
Paweł: This really highlights how important the planning phase is. Gathering client requirements, understanding their vision, and knowing the industry they operate in are all critical factors. It’s essential to approach this responsibly, so we don’t end up facing problems later on. Otherwise, it just leads to wasted money. So, I think this is a good point to wrap up the first part of our discussion on technical debt. It feels like we could talk about this forever. Thanks, guys, for taking the time-it was great talking with you. And we invite everyone to tune in for part two of our podcast, which will be released soon.
Damian: Thanks.
Szymon: Thanks.






