A well-designed application shouldn't need to use NOLOCK except for intentionally-designed concurrency tables such as queues.
Using READ UNCOMMITTED transaction isolation (which is what NOLOCK does) can make up for poorly designed applications that are experiencing a lot of blocking. But I think that while using it as a matter of course can work for a long, long time, some day it may hurt you badly. What is the consequence for reporting or acting on bad data? It depends, doesn't it?
I would avoid NOLOCK as much as possible in the following situations:
- If it's used in medical care and a single wrong value could harm
- If it's used for legal purposes or in any situation that could involve litigation where a single wrong value could create unacceptable risk
- If a single wrong value could cause great monetary loss
P.S. As an example of how to design applications well, one application design best practice is to do insert, update, and delete in the same order in every SP, so that SPs acquire the same types of locks in the same order, thus blocking less often. Fewer blocks and shorter locks means no need for patching the thing up with NOLOCK later.