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.

HyperLogLog

Last updated

A HyperLogLog (HLL) estimates how many distinct items you have added to it, without storing the items themselves. Each counter takes at most 12 KB however many items it has seen, and its estimate is typically within about 0.81% of the true count. Use it for unique visitors, distinct search terms, unique IPs per hour, and any cardinality question where an exact answer would mean keeping every item.

You cannot list or remove the items in a HyperLogLog, or ask whether one specific item was added. For exact counts and membership tests use a set; for approximate membership tests use a Bloom filter.

PFADD adds items and creates the key if needed. It replies 1 when the estimate changed and 0 when it did not (for example when every item was already counted). PFCOUNT returns the estimate.

127.0.0.1:6379> PFADD visitors:2026-10-02 "u:17" "u:23" "u:42" "u:88"
(integer) 1
127.0.0.1:6379> PFADD visitors:2026-10-02 "u:23"
(integer) 0
127.0.0.1:6379> PFCOUNT visitors:2026-10-02
(integer) 4
127.0.0.1:6379> PFADD visitors:2026-10-01 "u:42" "u:99"
(integer) 1
127.0.0.1:6379> PFCOUNT visitors:2026-10-01 visitors:2026-10-02
(integer) 5
127.0.0.1:6379> PFMERGE visitors:week visitors:2026-10-01 visitors:2026-10-02
OK
127.0.0.1:6379> PFCOUNT visitors:week
(integer) 5
127.0.0.1:6379> DEL visitors:week
(integer) 1

Counts this small are usually exact; as the number of distinct items grows, the answer becomes an estimate.

  • PFCOUNT with several keys returns the estimate for their union, without changing any of them.
  • PFMERGE stores the union in a destination key, so you can roll daily counters up into weekly or monthly ones.
  • A HyperLogLog is a string, so TYPE reports string and DEL, EXPIRE and RENAME work as usual. Writing to it with string commands such as SET or APPEND replaces or corrupts it.

A HyperLogLog starts out small and stays compact (sparse) until it would take more than hll-sparse-max-bytes (3000 bytes by default); it then switches to its full dense size of 12 KB, as in Redis. See Configuration.

HotKV stores HyperLogLogs in the same format as Redis, so their values can move between Redis and HotKV (with DUMP/RESTORE, MIGRATE, or a plain GET and SET), and both count the same items the same way. PFDEBUG and PFSELFTEST are there for diagnostics.

Unique visitors per day. PFADD uv:<date> <visitor-id> on each page view; PFCOUNT uv:<date> for the day, PFCOUNT over seven keys for the week. Give each daily key an expiry so old days clean themselves up.

Unique counts per dimension. One counter per page, country, or campaign (uv:page:/pricing:<date>): each costs at most 12 KB, so you can afford many.

Rollups. Merge daily keys into a monthly key with PFMERGE at the end of each day, then expire the daily keys.

A HyperLogLog expires as a whole, like any string.

Command What it does
PFADD Add items
PFCOUNT Estimated number of distinct items (of one key, or the union of several)
PFMERGE Store the union of several HyperLogLogs
PFDEBUG Inspect a HyperLogLog’s internal state
PFSELFTEST Run the built-in self test
import hotkv
client = hotkv.HotKV(host="localhost", port=6379, decode_responses=True)
client.pfadd("visitors:2026-10-02", "u:17", "u:23", "u:42")
client.pfadd("visitors:2026-10-01", "u:42", "u:99")
print(client.pfcount("visitors:2026-10-01", "visitors:2026-10-02")) # 4
client.pfmerge("visitors:week", "visitors:2026-10-01", "visitors:2026-10-02")
client.close()