- Recently, we needed to implement a “check-in for N days to receive gifts” feature in a project. This naturally led us to consider using Redis'
bitmap
for implementation.
- Check-in can be done with
setbit {key} {offset} 1
- Cumulative check-in days can be retrieved using
bitcount {key} {start} {end}
index.md
- Initially, we implemented it like this:
# Base date example: 2023-09-12, offset 0 for this day
setbit users:id 0 1
# Binary: 10000000
# Next day, 2023-09-13, offset 1
setbit users:id 1 1
# Binary: 11000000
# Retrieving check-in days from 2023-09-12 to 2023-09-20:
bitcount users:id 0 8
# Output: 2. However, testers reported issues when querying 2023-09-13 to 2023-09-20:
bitcount users:id 1 7
# Output: 0. The command actually checks bits 9-16 (bytes 1-7), which are all 0s.
- We mistakenly assumed
start
and end
were bit positions, but Redis versions <7.0 treat them as byte indexes.
Workaround for Older Redis Versions
- Multiply the
offset
by 8 to avoid overlapping bits within the same byte. Although this consumes 8x more space, it simplifies the logic.
setbit {key} {offset*8} 1
bitcount {key} {start} {end}
Solution for Redis ≥7.0
- Use the
BIT
parameter to specify bit-level ranges directly:
bitcount {key} {start} {end} BIT