Skip to content

Conversation

@busla
Copy link
Contributor

@busla busla commented Jan 8, 2026

Summary

Adds a new REDIS_SINGLE_KEY_OPS configuration option to support AWS ElastiCache Serverless (Valkey 8.1) which internally shards data but doesn't expose the Redis Cluster protocol.

Problem

  • ElastiCache Serverless shards data across slots internally
  • Setting USE_REDIS_CLUSTER=false causes CROSSSLOT errors on batch operations
  • Setting USE_REDIS_CLUSTER=true fails with ClusterAllFailedError because ElastiCache Serverless doesn't support CLUSTER NODES/CLUSTER SLOTS commands

Solution

  • New REDIS_SINGLE_KEY_OPS env var forces single-key operations without requiring cluster client
  • Decouples operation style (batch vs individual) from client type (single-node vs cluster)
  • For ElastiCache Serverless: use USE_REDIS_CLUSTER=false + REDIS_SINGLE_KEY_OPS=true

Change Type

  • New feature (non-breaking change which adds functionality)

Testing

  1. Set USE_REDIS=true, USE_REDIS_CLUSTER=false, REDIS_SINGLE_KEY_OPS=true
  2. Connect to AWS ElastiCache Serverless
  3. Verify no CROSSSLOT errors during cache operations
  4. Check logs for single-key-ops mode indicator

Technical Details

Files Changed:

  • packages/api/src/cache/cacheConfig.ts - Added REDIS_SINGLE_KEY_OPS configuration
  • packages/api/src/cache/redisUtils.ts - Updated batchDeleteKeys() to respect new option

Configuration:

# For AWS ElastiCache Serverless
USE_REDIS=true
USE_REDIS_CLUSTER=false
REDIS_SINGLE_KEY_OPS=true
REDIS_URI=rediss://your-elasticache-endpoint:6379

busla and others added 4 commits January 8, 2026 18:00
…Serverless

Add REDIS_SINGLE_KEY_OPS configuration option to force single-key Redis
operations even in non-cluster mode. This is required for AWS ElastiCache
Serverless which internally shards data but doesn't support the Redis
Cluster protocol, causing CROSSSLOT errors with batch operations.

- Add REDIS_SINGLE_KEY_OPS env var (default: false) in cacheConfig.ts
- Update batchDeleteKeys() in redisUtils.ts to use single-key ops when enabled
- Add 'single-key-ops' mode logging for observability

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Fixes race condition in addToIndex/removeFromIndex that caused index
corruption during parallel server initialization with Promise.allSettled().

Changes:
- Add LUA_ADD_TO_INDEX script for atomic index additions
- Add LUA_REMOVE_FROM_INDEX script for atomic index removals
- Use ioredisClient.call('EVAL', ...) to execute Lua scripts
- Preserve Keyv's JSON wrapper format: {"value": [...], "expires": null}
- Add MCP_SERVER_INDEX_KEY config option (default: '__server_index__')
- Fallback to non-atomic operations if ioredis unavailable

Required for ElastiCache Serverless where REDIS_SINGLE_KEY_OPS=true
causes parallel index updates to race and lose entries.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant