Wednesday, December 30, 2009
When is it OK to build up Technical Debt?
As I previously mentioned I’ve been writing a bit of Ruby on Rails. I’m surprised at how quickly I can slap something together and get results, especially prototypes, up and running quickly.
Technical Debt is generally defined as the eventual consequence of building software in a quick and dirty way. This most commonly occurs when a developer jumps directly into writing code without architecting or thinking through the solution. Usually a solution is spit out prematurely and will quickly fall over under heavy load or stringent testing.
The opposite of this would be to slowly build skills, tooling, requirements, specifications, tests, libraries, etc. until the problem is well defined and it’s just a matter of converting requirements and specifications into code. The problem with this is it is SLOW.
Other development techniques have been developed to bridge this gap. To provide the right amount of guidance when it’s necessary, but not so much that we develop requirement paralysis. TDD and Agile are two techniques that come to mind, but other technological solutions such as Object Oriented Programming, fantastic libraries and frameworks also help us get results and make headway quickly.
Still there will come a time, even with TDD, Agile, OOP, and a framework that makes you happy, when you have to decide between the right way, and the right-now way. At these times it’s important to know how to weigh those decisions properly. Here are some questions that might help you decide whether to build up technical debt or to build your software in a more measured way.
How long until the next version? – if this is a quick demo version that will be completely replaced it makes more sense to build it quickly leveraging anything you can get your hands on, using the skills you have now, rather than trying to learn a new tool. However, if this version has to stand on its own for an extended period of time, real customers will use it or if it will have to stand up to heavy live testing or load then you may not be able to cut corners.
How many customers are likely to become dependent on this? – Don’t forget that you may not just building up technical debt for yourself, but also for your customers who rely on stable software to build their solutions on. Changing large amounts of the software under existing customers can be difficult, you may even lose some of them to a competitor. Preserving perfect backwards compatibility makes it easier for your customers but forces you to shoulder the whole burden of your technical debt. Making this decision too many times can cause you to lose revenue to support and maintenance staff.
Is there an easy way out? - Using layers of abstraction to firewall the well architected pieces from the “quick and dirty” pieces is a good way to be able to componentize pieces that need to be replaced later. Before laying down thousands of lines of code ask yourself “How easy will it be to replace the technical debt pieces?” and if it’s going to be easy or there’s a way to make it easier on yourself then you might have the right decision. If your technical debt is taking a large dependency (for example a framework that is not well supported and will need to be replaced) then it may not make sense.
How likely will it be that you’ll have time to pay down your technical debt? – If you work at a company like most of the people I talk to you probably have a stack of todo items five feet tall and the only way anything ever gets done is if it is figuratively and sometimes literally on fire. If that’s the case then paying down the technical debt when you have a chance so you do it right the first time makes the most sense which will reduce future headaches. However if you need to release something right away and you know you can schedule time to return to the pieces that need attention you may be able to take on some debt without too much risk.
What kind of load will your application be under in this version? – If you’re anticipating very heavy load immediately upon release performance needs to be in the forefront of your decision making. One of the best examples of this is twitter; they were able to slide by on a shaky ruby-on-rails application until they grew to be one of the most visited sites on the internet. When they were in the throes of their growth pains we saw the fail whale often. They’ve had to quickly pay down their technical debt by replacing most of the backend of twitter with scala, memcache and starling, erlang, MySQL, Mongrel and more.
How much (real) market pressure is there to release a solution immediately? – Sometimes we feel every day we don’t release is another day people are filling the terrible hole in their lives with some other product. Unfortunately or fortunately this is often not the case. If we look at many examples of current market leaders they weren’t the first to market, but the best. The first mp3 player wasn’t the iPod, the first windowed GUI operating system wasn’t Windows, the first (nor the last) social media site was facebook. If you’ve promised a customer or client a solution it’s good to be on time, but if you don’t have customers shipping a half-baked product may give any potential customers such a bad taste in their mouth they won’t reconsider when you’ve had a chance to repay that technical debt you built up.
Many times it’s more important to get something out to get traction. As I mentioned in my “Let the pedestrians define the walkways” blog sometimes it’s better to get traction and feedback with people now and build up a little technical debt than to build a perfect solution that nobody can use.
Remember until you release nobody cares how fast, well architected, well commented or beautiful your software is.
Technical Debt is generally defined as the eventual consequence of building software in a quick and dirty way. This most commonly occurs when a developer jumps directly into writing code without architecting or thinking through the solution. Usually a solution is spit out prematurely and will quickly fall over under heavy load or stringent testing.
The opposite of this would be to slowly build skills, tooling, requirements, specifications, tests, libraries, etc. until the problem is well defined and it’s just a matter of converting requirements and specifications into code. The problem with this is it is SLOW.
Other development techniques have been developed to bridge this gap. To provide the right amount of guidance when it’s necessary, but not so much that we develop requirement paralysis. TDD and Agile are two techniques that come to mind, but other technological solutions such as Object Oriented Programming, fantastic libraries and frameworks also help us get results and make headway quickly.
Still there will come a time, even with TDD, Agile, OOP, and a framework that makes you happy, when you have to decide between the right way, and the right-now way. At these times it’s important to know how to weigh those decisions properly. Here are some questions that might help you decide whether to build up technical debt or to build your software in a more measured way.
How long until the next version? – if this is a quick demo version that will be completely replaced it makes more sense to build it quickly leveraging anything you can get your hands on, using the skills you have now, rather than trying to learn a new tool. However, if this version has to stand on its own for an extended period of time, real customers will use it or if it will have to stand up to heavy live testing or load then you may not be able to cut corners.
How many customers are likely to become dependent on this? – Don’t forget that you may not just building up technical debt for yourself, but also for your customers who rely on stable software to build their solutions on. Changing large amounts of the software under existing customers can be difficult, you may even lose some of them to a competitor. Preserving perfect backwards compatibility makes it easier for your customers but forces you to shoulder the whole burden of your technical debt. Making this decision too many times can cause you to lose revenue to support and maintenance staff.
Is there an easy way out? - Using layers of abstraction to firewall the well architected pieces from the “quick and dirty” pieces is a good way to be able to componentize pieces that need to be replaced later. Before laying down thousands of lines of code ask yourself “How easy will it be to replace the technical debt pieces?” and if it’s going to be easy or there’s a way to make it easier on yourself then you might have the right decision. If your technical debt is taking a large dependency (for example a framework that is not well supported and will need to be replaced) then it may not make sense.
How likely will it be that you’ll have time to pay down your technical debt? – If you work at a company like most of the people I talk to you probably have a stack of todo items five feet tall and the only way anything ever gets done is if it is figuratively and sometimes literally on fire. If that’s the case then paying down the technical debt when you have a chance so you do it right the first time makes the most sense which will reduce future headaches. However if you need to release something right away and you know you can schedule time to return to the pieces that need attention you may be able to take on some debt without too much risk.
What kind of load will your application be under in this version? – If you’re anticipating very heavy load immediately upon release performance needs to be in the forefront of your decision making. One of the best examples of this is twitter; they were able to slide by on a shaky ruby-on-rails application until they grew to be one of the most visited sites on the internet. When they were in the throes of their growth pains we saw the fail whale often. They’ve had to quickly pay down their technical debt by replacing most of the backend of twitter with scala, memcache and starling, erlang, MySQL, Mongrel and more.
How much (real) market pressure is there to release a solution immediately? – Sometimes we feel every day we don’t release is another day people are filling the terrible hole in their lives with some other product. Unfortunately or fortunately this is often not the case. If we look at many examples of current market leaders they weren’t the first to market, but the best. The first mp3 player wasn’t the iPod, the first windowed GUI operating system wasn’t Windows, the first (nor the last) social media site was facebook. If you’ve promised a customer or client a solution it’s good to be on time, but if you don’t have customers shipping a half-baked product may give any potential customers such a bad taste in their mouth they won’t reconsider when you’ve had a chance to repay that technical debt you built up.
Many times it’s more important to get something out to get traction. As I mentioned in my “Let the pedestrians define the walkways” blog sometimes it’s better to get traction and feedback with people now and build up a little technical debt than to build a perfect solution that nobody can use.
Remember until you release nobody cares how fast, well architected, well commented or beautiful your software is.
Labels: development, software development
Monday, December 7, 2009
Fake ‘Savoir Faire’ with ‘Mise en Place’
I recently went home to see my parents for Thanksgiving. NPR was playing in the car and a short story came on that struck close to my heart in two ways. It was about how to pull off a seemingly effortless multi-course meal by effectively front-loading most of your heavy cooking to prep work so that all you have to do when your guests arrive is to ‘finish’ each dish. This means that absolutely everything that can be is chopped, blanched, steamed, mixed or even completely ready to serve (in the case of many deserts) before your first guest arrives.
When you do this it makes the cooking look like magic.
As we were driving down the road I realized this is a great thing to strive for in software development and professional interactions as well. I’ve noticed the more preparation I can do before a meeting the better it goes. Some people have the ability to make this all look effortless, those people have “Savoir Faire,” but it always catches up to them. There will be a time when they’ll get burned by their lack of preparation.
Here are a few tips on how to prepare for a meeting or delivery of a final project.
Ask the tough questions – Make a list of the top 15-20 questions you don’t want to hear in a meeting. Answer those questions to the best of your ability. Often we go into the meeting expecting our best case scenario, but everybody else in that meeting is there to understand your proposition deeply. Help them understand, and cover all your bases.
Think about your backup plan – What do you need in order to deliver your presentation? What if those things aren’t there, break down, or you forget them? Computers are notorious for not connecting to projectors when you want them to. Thumb drives fail, projectors overheat, networks aren’t always available, dry erase markers dry up, and audio equipment fails. Think about each thing you need in your meeting and think about how you can continue when the failures occur.
Run through your presentation exactly once – Make sure you run through your presentation end to end once before you are in front of people, but don’t memorize a script or demo. Memorization will come off as such, and you’ll have a hard time engaging the people in the meeting. You need to be dynamic, but well prepared. As mentioned above, lots can go wrong, if you memorize how you want everything to happen, you’ll have a hard time thinking on your feet when unpredicted things come up.
Relax – Most of the ways that you can recognize being nervous are not visible externally. Nobody else can hear your heart beating in your ears, they can’t see the sweat in your palms, and they’re probably not paying attention to your face becoming flushed. 30 min before the meeting review your talking points quickly, then put them away until the meeting. Take a walk 15 min before, have a small glass of water and take a deep breath. During the meeting remember to breathe and if you’re standing up feel free to move a bit, walking around the room can make the delivery seem more natural. Finally remember you don’t need to fill up every moment with talking, you can stop to take a breath, to walk across the room for emphasis, or to wait for feedback.
Subscribe to Posts [Atom]

