redis_zrangebylexSorted set lexicographic range — O(log N + M), unbounded without LIMIT
ZRANGEBYLEX returns members between two lexicographic boundaries in a sorted set where all members have equal scores. It enables efficient prefix queries and autocomplete patterns. Without a LIMIT clause, a wide lex range (e.g. [a to [z or - to +) can return an unbounded number of members. The command is O(log N + M) where M is the number of elements in the lex range.
Common Causes
- —Autocomplete implementations without result count limits
- —Alphabetical range scans across large lexicographic sets without pagination
- —Full-alphabet prefix queries on large datasets
- —Using - to + lex range to retrieve all members sorted alphabetically
How to Fix
- 1.Always include LIMIT offset count to cap the result size
- 2.Narrow the lex range to the minimum prefix needed
- 3.Use ZLEXCOUNT to count matching members without fetching them
- 4.Migrate to ZRANGE with BYLEX for Redis 6.2+ codebases
Example
typescript
// Context: all members have score 0, sorted lexicographically
// Useful for: autocomplete, alphabetical indexes, prefix search
// BAD — unbounded lex range, no LIMIT
const allProducts = await redis.zrangebylex('products:index', '-', '+');
// BAD — prefix query without result cap (could match thousands)
const aProducts = await redis.zrangebylex('products:index', '[a', '[a\xff');
// GOOD — bounded prefix autocomplete
async function autocomplete(redis: Redis, prefix: string, limit = 10) {
const lower = `[${prefix}`;
const upper = `[${prefix}\xff`; // \xff is beyond any normal char
return redis.zrangebylex('products:index', lower, upper, 'LIMIT', 0, limit);
}
const suggestions = await autocomplete(redis, 'mac', 8);
// ['macbook', 'macbook-air', 'macbook-pro', 'macos', 'macpro']
// GOOD — count matching prefix without fetching
const matchCount = await redis.zlexcount('products:index', '[mac', '[mac\xff');
// GOOD — Redis 6.2+ equivalent
const results = await redis.zrange(
'products:index',
'[mac', '[mac\xff',
'BYLEX',
'LIMIT', 0, 10
);
// GOOD — build the autocomplete index
await redis.zadd('products:index', 0, 'macbook');
await redis.zadd('products:index', 0, 'macbook-air');
await redis.zadd('products:index', 0, 'macbook-pro');Use \\xff as the upper lex bound for prefix queries
The character
\xff has the highest byte value and serves as a reliable upper bound for any prefix — [mac to [mac\xff matches all members that start with "mac" and nothing beyond.