Skip to content

Ask the HotKV docs

Answers come only from these docs and can be wrong; check the linked pages before you rely on them.

Bitmaps

Last updated

Bitmaps are not a separate type: they are strings read and written one bit at a time. Bit offset 0 is the most significant bit of the first byte. Because each flag costs a single bit, a bitmap can record a yes/no fact for millions of numeric IDs in a few megabytes, and the server can count or combine them quickly. Typical uses are “which users were active today”, feature flags per user ID, and presence grids.

BITFIELD goes one step further and packs small integers (for example many 8-bit counters) into one string.

SETBIT sets or clears one bit and replies with its previous value. A missing key is created, and the string grows (padded with zero bits) to reach the offset. GETBIT reads a bit; bits past the end of the string read as 0.

127.0.0.1:6379> SETBIT logins:2026-10-01 3 1
(integer) 0
127.0.0.1:6379> SETBIT logins:2026-10-01 7 1
(integer) 0
127.0.0.1:6379> SETBIT logins:2026-10-02 3 1
(integer) 0
127.0.0.1:6379> SETBIT logins:2026-10-02 5 1
(integer) 0
127.0.0.1:6379> GETBIT logins:2026-10-02 5
(integer) 1
127.0.0.1:6379> GETBIT logins:2026-10-02 100
(integer) 0
127.0.0.1:6379> BITCOUNT logins:2026-10-01
(integer) 2
127.0.0.1:6379> BITPOS logins:2026-10-02 1
(integer) 3

Here the offset is a user ID: user 3 logged in on both days, user 7 only on the first, user 5 only on the second.

  • BITCOUNT counts set bits, optionally in a range. The range is in bytes by default; add BIT to give it in bits.
  • BITPOS finds the first bit set to 1 (or 0), optionally within a range.
  • Since a bitmap is a string, GET returns the raw bytes and DEL removes it.

BITOP computes AND, OR, XOR, NOT, DIFF, DIFF1, ANDOR or ONE across bitmaps and stores the result. It replies with the length of the result in bytes.

127.0.0.1:6379> BITOP AND logins:both logins:2026-10-01 logins:2026-10-02
(integer) 1
127.0.0.1:6379> BITCOUNT logins:both
(integer) 1
127.0.0.1:6379> BITOP OR logins:either logins:2026-10-01 logins:2026-10-02
(integer) 1
127.0.0.1:6379> BITCOUNT logins:either
(integer) 3

NOT takes exactly one source key. Shorter inputs are treated as if padded with zero bytes.

BITFIELD reads and writes integers of any width from 1 to 64 bits (signed i<n>, or unsigned u<n> up to 63 bits) at any bit offset, several in one call. OVERFLOW chooses what INCRBY does past the type’s range: WRAP (the default), SAT to stick at the minimum or maximum, or FAIL to leave the value and return nil.

127.0.0.1:6379> BITFIELD player:42 SET u8 0 200
1) (integer) 0
127.0.0.1:6379> BITFIELD player:42 INCRBY u8 0 100
1) (integer) 44
127.0.0.1:6379> BITFIELD player:42 OVERFLOW SAT INCRBY u8 0 250
1) (integer) 255
127.0.0.1:6379> BITFIELD player:42 GET u8 0 GET u8 8
1) (integer) 255
2) (integer) 0

BITFIELD_RO accepts only GET, so it can run on read-only replicas.

Daily active users. SETBIT active:<date> <user-id> 1 on each visit. BITCOUNT gives the day’s count, BITOP AND across a week gives users active every day, BITOP OR users active on any day.

Per-user feature flags. One bitmap per feature, offset = user ID. GETBIT feature:new-checkout 42 is a constant-time check.

Many small counters. With BITFIELD, a single key can hold thousands of fixed-width counters, addressed by offset, with saturating increments.

A bitmap is as large as its highest set bit requires: setting bit 1,000,000 makes a string of about 122 KB even if no other bit is set. This makes bitmaps a great fit for dense numeric IDs and a poor one for sparse or very large IDs; for those, use a set, or a HyperLogLog if an approximate count is enough.

The highest usable bit offset follows proto-max-bulk-len: with the default 512 MB, offsets go up to 2^32 - 1. Larger offsets are refused with ERR bit offset is not an integer or out of range.

A bitmap expires as a whole, like any string. Name keys by period (active:2026-10-02) and give each an expiry, so old periods clean themselves up.

Bitmap commands follow Redis 8.2, including the DIFF, DIFF1, ANDOR and ONE operations of BITOP.

Command What it does
SETBIT Set or clear a bit
GETBIT Read a bit
BITCOUNT Count set bits
BITPOS Find the first 0 or 1 bit
BITOP Combine bitmaps
BITFIELD Read and write packed integers
BITFIELD_RO Read-only BITFIELD
import hotkv
client = hotkv.HotKV(host="localhost", port=6379, decode_responses=True)
client.setbit("logins:2026-10-02", 3, 1)
client.setbit("logins:2026-10-02", 5, 1)
print(client.getbit("logins:2026-10-02", 5)) # 1
print(client.bitcount("logins:2026-10-02")) # 2
client.close()