Critical findings about Redis port compatibility and Boost.redis library behavior
Date: 2026-05-26 to 2026-05-27
Context: L3 compression E2E testing and semantic cache development
Windows Redis port has binary payload handling issues that cause LRANGE to block
indefinitely with ~1.6KB serialized data. WSL Redis (same version) works correctly
with identical code and payloads. Production deployments should use Linux Redis.
E2E test for L3 long-term memory compression hangs indefinitely on LRANGE command
when fetching serialized CacheRecord structures (~1.6KB each, 384-dim float vector
- metadata).
// This blocks forever on Windows Redis (port 6379)
boost::redis::request lrange_req;
lrange_req.push("LRANGE", key, "0", "-1");
boost::redis::response<std::vector<std::string>> lrange_resp;
auto status = redis_pool->Exec(lrange_req, lrange_resp); // Hangs here- Windows Redis: Native Windows port, registered as service, auto-starts on port 6379
- WSL Redis: Redis running in WSL2, manually started on port 5000
- Boost.redis: Version 1.85 (from Boost 1.85.0)
- Payload size: ~1.6KB per record (384 float32 values + metadata)
- Test scenario: 3 records written via
RPUSH, then read viaLRANGE
| Test | Windows Redis (6379) | WSL Redis (5000) |
|---|---|---|
| Bare connection test | ✅ Pass | ✅ Pass |
| Small string RPUSH/LRANGE | ✅ Pass | ✅ Pass |
| Binary payload E2E | ❌ Hangs | ✅ Pass |
Bare connection test (redis_bare_connection_test.cpp):
- Simple PING/PONG exchange
- Small string SET/GET
- Passes on both Windows and WSL Redis
E2E test (l3_compression_e2e_test.cpp):
- Serialize 3
CacheRecordstructures (each ~1.6KB) RPUSHto Redis listLRANGEto retrieve all records- Windows Redis: hangs indefinitely on
LRANGE, no timeout, no error - WSL Redis: completes successfully in ~1.4s (including LLM call)
Windows Redis port likely has issues with:
- Binary data handling — may not correctly handle non-UTF8 binary blobs
- Buffer management — possible buffer overflow or incorrect size calculation for large payloads
- Protocol parsing — may misinterpret binary data as protocol markers
The issue is not in Boost.redis client code, as the same code works correctly with WSL Redis.
Issue: KEYS pattern matching causes connection abort in Boost.redis 1.85.
// This aborts the connection
boost::redis::request req;
req.push("KEYS", "cache:batch:*");
boost::redis::response<std::vector<std::string>> resp;
auto status = redis_pool->Exec(req, resp); // Connection abortedWorkaround: Use SCAN with generic_response instead:
std::string cursor = "0";
do {
boost::redis::request req;
req.push("SCAN", cursor, "MATCH", pattern, "COUNT", "100");
boost::redis::generic_response resp;
auto status = redis_pool->Exec(req, resp);
if (!status.ok()) break;
const auto& nodes = resp.value();
cursor = nodes[1].value; // Next cursor
for (size_t i = 3; i < nodes.size(); ++i) {
if (nodes[i].depth == 2) {
keys.push_back(nodes[i].value);
}
}
} while (cursor != "0");Issue: Boost.redis auto-PING can interfere with custom command sequences.
Workaround: Disable health check interval:
boost::redis::config cfg;
cfg.health_check_interval = std::chrono::seconds::zero();-
Use WSL Redis for local development on Windows
- Start Redis in WSL:
redis-server --port 5000 - Configure client to connect to
127.0.0.1:5000 - Avoids Windows Redis port issues entirely
- Start Redis in WSL:
-
Keep Windows Redis for simple tests
- Bare connection tests
- Small string payloads
- Protocol validation
-
Deploy on Linux (native or containerized)
- Use official Redis Docker image or native Linux build
- Avoid Windows Redis port for binary payload workloads
-
Use SCAN instead of KEYS
- More efficient for large keyspaces
- Avoids Boost.redis connection abort issue
- Non-blocking iteration
-
Disable health check if using custom command sequences
- Set
health_check_interval = std::chrono::seconds::zero() - Prevents auto-PING interference
- Set
-
E2E tests should target WSL Redis
- Config:
"redis": {"host": "127.0.0.1", "port": 5000} - Ensures binary payload compatibility
- Config:
-
Unit tests can use Windows Redis
- Small payloads only
- Protocol-level validation
-
Add timeout to all Redis operations
- Use
Execoverload with timeout parameter - Prevents indefinite hangs in case of issues
- Use
std::vector<std::string> ScanKeys(const std::string& pattern) {
std::vector<std::string> keys;
std::string cursor = "0";
do {
boost::redis::request req;
req.push("SCAN", cursor, "MATCH", pattern, "COUNT", "100");
boost::redis::generic_response resp;
auto status = redis_pool_->Exec(req, resp);
if (!status.ok()) {
logger_.error("SCAN failed: {}", status.message());
break;
}
const auto& nodes = resp.value();
if (nodes.size() < 3) {
logger_.warn("SCAN returned unexpected node count: {}", nodes.size());
break;
}
cursor = nodes[1].value;
for (size_t i = 3; i < nodes.size(); ++i) {
if (nodes[i].depth == 2) {
keys.push_back(nodes[i].value());
}
}
} while (cursor != "0");
return keys;
}boost::redis::config cfg;
cfg.addr.host = "127.0.0.1";
cfg.addr.port = "5000"; // WSL Redis
cfg.health_check_interval = std::chrono::seconds::zero(); // Disable auto-PING
auto conn = std::make_shared<boost::redis::connection>(io_context);
conn->async_run(cfg, {}, [](auto ec) {
if (ec) {
// Handle error
}
});boost::redis::request req;
req.push("LRANGE", key, "0", "-1");
boost::redis::response<std::vector<std::string>> resp;
auto status = redis_pool->Exec(req, resp, std::chrono::seconds(5)); // 5s timeout
if (!status.ok()) {
logger_.error("LRANGE failed: {}", status.message());
return status;
}
auto records = std::get<0>(resp).value();
// Process records...src/semantic_cache/redis_connection_pool.h— Redis pool implementationsrc/semantic_cache/redis_connection_pool.cpp— SCAN usage exampletools/redis_bare_connection_test.cpp— Simple Redis connectivity testtools/l3_compression_e2e_test.cpp— E2E test with binary payloadstools/l3_compression_e2e_test.json— Config with WSL Redis port
- 2026-05-26: Discovered Windows Redis
LRANGEblocking issue during E2E testing - 2026-05-26: Confirmed WSL Redis workaround resolves the issue
- 2026-05-26: Documented
KEYScommand abort andSCANworkaround - 2026-05-27: Added crash dump infrastructure to aid debugging
- 2026-05-27: E2E test passes with WSL Redis, validates full L3 compression pipeline
- Investigate Windows Redis source — determine exact cause of binary payload issue
- Report to Redis Windows maintainers — if issue is reproducible with minimal example
- Consider alternative Redis clients — if Boost.redis issues persist (e.g., redis-plus-plus, hiredis)
- Add Redis version detection — warn if running on Windows Redis with binary payloads