The code for any software system is where most of the focus remains for the majority of the software development life cycle and this makes sense because the code is the ultimate deliverable. But if you had to explain to somebody how that system worked, would you start with the code?
Unfortunately the code doesn't tell the whole story and, in the absence of documentation, people will typically start drawing boxes and lines on a whiteboard or piece of paper to explain what the major building blocks are and how they are connected. Many of these diagrams, which are also used when designing software, quickly become cluttered and confused, showing too much detail at varying levels of abstraction simultaneously. Picking up a tool such as Microsoft Visio or Rational Software Architect usually adds to the complexity too, rather than making life easier.
When documenting software, we have a tendency to include as much detail as possible. This may be because we're anticipating questions or because we're a little too focussed on the specifics of how the system works at a code level. Rather than a single diagram then, it's often worth drawing a number of different diagrams at varying levels of abstraction because a number of simple diagrams can describe software in a much more effective way than a single diagram that tries to encompass everything.
In summary, I tend to draw the following types of diagrams, which are based upon a set of simple architectural constructs.
A single diagram can quickly become cluttered and confused, but a collection of diagrams allows you to present the software from a number of different levels of abstraction. If you keep the diagrams as simple as possible, illustrating your software can be a quick and easy task and that requires little ongoing effort to keep those diagrams up to date.