{"acl_categories":["@read","@bitmap","@slow"],"arguments":[{"display_text":"key","key_spec_index":0,"name":"key","type":"key"},{"arguments":[{"display_text":"start","name":"start","type":"integer"},{"display_text":"end","name":"end","type":"integer"},{"arguments":[{"display_text":"byte","name":"byte","token":"BYTE","type":"pure-token"},{"display_text":"bit","name":"bit","token":"BIT","type":"pure-token"}],"name":"unit","optional":true,"since":"7.0.0","type":"oneof"}],"name":"range","optional":true,"type":"block"}],"arity":-2,"categories":["docs","develop","stack","oss","rs","rc","oss","kubernetes","clients"],"command_flags":["readonly"],"complexity":"O(N)","description":"Counts the number of set bits (population counting) in a string.","duplicateOf":"head:data-ai-metadata","group":"bitmap","key_specs":[{"RO":true,"access":true,"begin_search":{"spec":{"index":1},"type":"index"},"find_keys":{"spec":{"keystep":1,"lastkey":0,"limit":0},"type":"range"}}],"location":"body","since":"2.6.0","syntax_fmt":"BITCOUNT key [start end [BYTE | BIT]]","title":"BITCOUNT","tableOfContents":{"sections":[{"id":"examples","title":"Examples"},{"id":"pattern-real-time-metrics-using-bitmaps","title":"Pattern: real-time metrics using bitmaps"},{"id":"performance-considerations","title":"Performance considerations"},{"id":"redis-software-and-redis-cloud-compatibility","title":"Redis Software and Redis Cloud compatibility"},{"id":"return-information","title":"Return information"}]},"codeExamples":[]}
bitcount(
key: K// the key.
) → Long// Long integer-reply The number of bits set to 1.bitcount(
key: K, // the key.start: long, // the start.end: long// the end.
) → Long// Long integer-reply The number of bits set to 1.
bitcount(
key: K// the key.
) → RedisFuture<Long>// Long integer-reply The number of bits set to 1.bitcount(
key: K, // the key.start: long, // the start.end: long// the end.
) → RedisFuture<Long>// Long integer-reply The number of bits set to 1.
bitcount(
key: K// the key.
) → Mono<Long>// Long integer-reply The number of bits set to 1.bitcount(
key: K, // the key.start: long, // the start.end: long// the end.
) → Mono<Long>// Long integer-reply The number of bits set to 1.
StringBitCount(
key: RedisKey, // The key of the string.start: long, // The start byte to count at.end: long, // The end byte to count at.flags: CommandFlags// The flags to use for this operation.
) → long// The number of bits set to 1.StringBitCount(
key: RedisKey, // The key of the string.start: long, // The start byte to count at.end: long, // The end byte to count at.indexType: StringIndexType, // In Redis 7+, we can choose if start and end specify a bit index or byte index (defaults to Byte).flags: CommandFlags// The flags to use for this operation.
) → long// The number of bits set to 1.StringBitCountAsync(
key: RedisKey,
start: long,
end: long,
flags: CommandFlags
) → Task<long>StringBitCountAsync(
key: RedisKey,
start: long,
end: long,
indexType: StringIndexType,
flags: CommandFlags
) → Task<long>StringBitCount(
key: RedisKey, // The key of the string.start: long, // The start byte to count at.end: long, // The end byte to count at.flags: CommandFlags// The flags to use for this operation.
) → long// The number of bits set to 1.
StringBitCountAsync(
key: RedisKey,
start: long,
end: long,
flags: CommandFlags
) → Task<long>StringBitCountAsync(
key: RedisKey,
start: long,
end: long,
indexType: StringIndexType,
flags: CommandFlags
) → Task<long>StringBitCount(
key: RedisKey, // The key of the string.start: long, // The start byte to count at.end: long, // The end byte to count at.flags: CommandFlags// The flags to use for this operation.
) → long// The number of bits set to 1.StringBitCount(
key: RedisKey, // The key of the string.start: long, // The start byte to count at.end: long, // The end byte to count at.indexType: StringIndexType, // In Redis 7+, we can choose if start and end specify a bit index or byte index (defaults to Byte).flags: CommandFlags// The flags to use for this operation.
) → long// The number of bits set to 1.StringBitCount(
key: RedisKey, // The key of the string.start: long, // The start byte to count at.end: long, // The end byte to count at.flags: CommandFlags// The flags to use for this operation.
) → long// The number of bits set to 1.
bitcount(
$key: string,
$start = null: Any,
$end = null: Any,
string $index = 'byte': Any
) → int
Count the number of set bits (population counting) in a string.
By default all the bytes contained in the string are examined.
It is possible to specify the counting operation only in an interval passing the
additional arguments start and end.
Like for the GETRANGE command start and end can contain negative values in
order to index bytes starting from the end of the string, where -1 is the last
byte, -2 is the penultimate, and so forth.
Non-existent keys are treated as empty strings, so the command will return zero.
By default, the additional arguments start and end specify a byte index.
We can use an additional argument BIT to specify a bit index.
So 0 is the first bit, 1 is the second bit, and so forth.
For negative values, -1 is the last bit, -2 is the penultimate, and so forth.
Examples
Pattern: real-time metrics using bitmaps
Bitmaps are a very space-efficient representation of certain kinds of
information.
One example is a Web application that needs the history of user visits, so that
for instance it is possible to determine what users are good targets of beta
features.
Using the SETBIT command this is trivial to accomplish, identifying every day
with a small progressive integer.
For instance day 0 is the first day the application was put online, day 1 the
next day, and so forth.
Every time a user performs a page view, the application can register that in
the current day the user visited the web site using the SETBIT command setting
the bit corresponding to the current day.
Later it will be trivial to know the number of single days the user visited the
web site simply calling the BITCOUNT command against the bitmap.
In the above example of counting days, even after 10 years the application is
online we still have just 365*10 bits of data per user, that is just 456 bytes
per user.
With this amount of data BITCOUNT is still as fast as any other O(1) Redis
command like GET or INCR.
When the bitmap is big, there are two alternatives:
Taking a separated key that is incremented every time the bitmap is modified.
This can be very efficient and atomic using a small Redis Lua script.
Running the bitmap incrementally using the BITCOUNTstart and end
optional parameters, accumulating the results client-side, and optionally
caching the result into a key.