I really suggest to also looking at GETRANGE and SETRANGE operations that allow to access sub-ranges of a large bitmap fetching or setting arbitrary ranges fo bits.
Probably Lua scripting in 2.6 will enable a lot more interesting things combining server side execution and bitmaps. Thanks for sharing this work.
I'm pretty excited about this.
bits = GETRANGE ...
bits = bits | buffered_bits
SETRANGE .... bits
Although it is another command in a growing list of them. maybe something for lua.
Also, will you create some kind of market for Redis scripts? That seems useful - even if it's just links to Github! ;)
Though, if you are storing binary users, 700 million users take less than 90 MB of space (assuming a straight array implementation). Old days wouldn't need to be kept in memory. If you want to think beyond redis, you could keep the active data in redis then flush old data to disk for later querying.
Sounds useful if your users map to a (0, Max] integer representation. Sounds complicated if you use uuids or external vendor IDs for users anywhere (you'd need an intermediate mapping table somewhere).
Obviously, each use case is different and for very sparse case, sets would be a better choice.
In my (limited) use cases for redis which interfaced with external information like that I usually had a mapping table anyway, to get something like
Note again that I'm no expert on redis. There might be problems with that approach that I don't know about - but for me this worked out quite well and seemed to save memory vs any foo:externalIdOrUsername:dataHere name scheme.
You can take advantage of sparse bits and doing logic operations on them in compressed state.