So I'm working in C# and normally I use protocol buffers and heavy usage of varints, but the best existing library boxes value types. So for a handful of our high traffic messages I created a simple code generation based encoder. To signify which fields to include in the stream I use a bit per field. Then encode those bits as varints and they go in the header. I use 32 bit chunks for this (BitVector32 as it just makes bit twiddling easier).
An obvious more efficient approach is to just create more granular messaging so you don't have a lot of fields with default values, or leverage other things that are context specific. I'm trying to find the perfect middle ground. It seems that there should be a way to use less then a bit per field. Like some type of mask that takes less, maybe some type of lookup table, even if it does use a bit of memory.