<i>Messaging: Sending a message is fast. But remember you are doing a copy of the data into the other process memory space (unless you are sending a binary, see above). For small messages, this doesn't matter, but you shouldn't be tempted to send that one million node binary tree ;)</i>
Two points here: as you stated in the point above this one, large binaries are shared, so sending a large binary as a message isn't terribly expensive. For everything else, copying messages is an implementation detail, not a specified behaviour. If you run erl -hybrid, then all processes do share a single heap and messages are not copied (unless sent between nodes, of course). Hybrid mode is still very unstable and you don't want to use it unless it really does happen to work for you, but it's proof that the copying of message data isn't a requirement of erlang, but instead is just a current implementation detail.
<i>A string of 100 bytes takes up 1600 bytes on a 64-bit machine.</i>
Erlang strings (i.e. any string literal, such as "hi there") are implemented as linked lists of integers. If you're doing string processing on large strings, you probably want to use binaries, which are 8 bits per character (plus the binary head, which is a varint, IIRC). These can be stated as <<"Hi there">> and are much more memory-efficient, although not as convenient to work with as linked lists.