Just read the question about the Big Rewrites and I remembered a question that I've been wanting answered myself.

I have a horrible project passed down to me, written in old Java, using Struts 1.0, tables with inconsistent relationships, or no relationships at all and even tables without primary keys or fields meant to be primary keys but aren't unique at all. Somehow most of the app "just works". Most of the pages are reused (copy pasted code) and hard-coded. Everyone who's ever worked on the project has cursed it in one form or the other.

Now I had long considered to propose to upper management a total rewrite of this horrendous application.  I'm slowly attempting to on personal time but I really feel that this deserves some dedicated resources to make it happen. Having read the articles on big rewrites I'm having second thoughts. And that's not good when I want to convince my superiors to support my rewrite. (I work in a fairly small company so the proposal has the possibility of being approved)

TL;DR
When is a big rewrite the answer and what arguments can you use to support it?

Sorry, this is going to be long, but it's based on personal experience as both architect and developer on multiple rewrite projects.

The following conditions should cause you to consider some sort of rewrite.  I'll talk about how to decide which one to do after that.


Developer ramp-up time is very high.  If it takes any longer than below (by experience level) to ramp up a new developer, then the system needs to be redesigned.  By ramp-up time, I mean the amount of time before the new developer is ready to do their first commit (on a small feature)


Fresh out of college - 1.5 months
Still green, but have worked on other projects before - 1 month
Mid level - 2 weeks
Experienced - 1 week
Senior level - 1 day

Deployment cannot be automated, because of the complexity of the existing architecture
Even simple bug fixes take too long because of the complexity of existing code
New features take too long, and cost too much because of the interdependence of the codebase (new features cannot be isolated, and therefore affect existing features)
The formal testing cycle takes too long because of the interdependence of the existing codebase.
Too many use cases are executed on too few screens. This causes training issues for the users and developers.
The technology that the current system is in demands it


Quality developers with experience in the technology are too hard to find
It is deprecated (It can't be upgraded to support newer platforms/features)
There is simply a much more expressive higher-level technology available
The cost of maintaining the infrastructure of the older technology is too high



These things are pretty self-evident. When to decide on a complete rewrite versus an incremental rebuild is more subjective, and therefore more politically charged. What I can say with conviction is that to categorically state that it is never a good idea is wrong.

If a system can be incrementally redesigned, and you have the full support of project sponsorship for such a thing, then you should do it.  Here's the problem, though. Many systems cannot be incrementally redesigned. Here are some of the reasons I have encountered that prevent this (both technical and political).


Technical


The coupling of components is so high that changes to a single component cannot be isolated from other components.  A redesign of a single component results in a cascade of changes not only to adjacent components, but indirectly to all components.
The technology stack is so complicated that future state design necessitates multiple infrastructure changes. This would be necessary in a complete rewrite as well, but if it's required in an incremental redesign, then you lose that advantage.
Redesigning a component results in a complete rewrite of that component anyway, because the existing design is so fubar that there's nothing worth saving. Again, you lose the advantage if this is the case.

Political


The sponsors cannot be made to understand that an incremental redesign requires a long-term commitment to the project. Inevitably, most organizations lose the appetite for the continuing budget drain that an incremental redesign creates. This loss of appetite is inevitable for a rewrite as well, but the sponsors will be more inclined to continue, because they don't want to be split between a partially complete new system and a partially obsolete old system.
The users of the system are too attached with their "current screens." If this is the case, you won't have the license to improve a vital part of the system (the front-end). A redesign lets you circumvent this problem, since they're starting with something new. They'll still insist on getting "the same screens," but you have a little more ammunition to push back.



Keep in mind that the total cost of redesiging incrementally is always higher than doing a complete rewrite, but the impact to the organization is usually smaller.  In my opinion, if you can justify a rewrite, and you have superstar developers, then do it.

Only do it if you can be certain that there is the political will to see it through to completion.  This means both executive and end user buy-in.  Without it, you will fail. I'm assuming that this is why Joel says it's a bad idea.  Executive and end-user buy-in looks like a two-headed unicorn to many architects. You have to sell it aggressively, and campaign for its continuation continuously until it's complete.  That's difficult, and you're talking about staking your reputation on something that some will not want to see succeed.

Some strategies for success:


If you do, however, do not try to convert existing code. Design the system from scratch. Otherwise you're wasting your time. I have never seen or heard of a "conversion" project that didn't end up miserably.
Migrate users to the new system one team at a time. Identify the teams that have the MOST pain with the existing system, and migrate them first. Let them spread the good news by word of mouth. This way your new system will be sold from within.
Design your framework as you need it. Don't start with some I-spent-6-months-building-this framework that has never seen real code.
Keep your technology stack as small as possible. Don't over-design. You can add technologies as needed, but taking them out is difficult. Additionally, the more layers you have, the more work it is for developers to do things. Don't make it difficult from the get-go.
Involve the users directly in the design process, but don't let them dictate how to do it. Earn their trust by showing them that you can give them what they want better if you follow good design principles.

