100% Redis-compatible database on Cloudflare Workers, Durable Objects, and SQLite
npm install redis.do
100% Redis-compatible database on Cloudflare Workers
---
Redis.do is a fully Redis-compatible database built on Cloudflare Workers, Durable Objects, and SQLite. Deploy your own Redis instance at the edge with zero operational overhead.
- 100% Redis Protocol Compatible - Drop-in replacement for Redis with support for all major data types
- Edge-Native - Runs on Cloudflare's global network with sub-millisecond latency worldwide
- Durable Storage - Data persisted in SQLite-backed Durable Objects for reliability
- Serverless - No servers to manage, scales automatically with demand
- MCP Integration - Built-in Model Context Protocol server for AI agent integration
- Upstash-Compatible REST API - Use existing Upstash clients seamlessly
- ioredis-Compatible Client - Familiar API with pipelining support
- Secure Code Execution - Sandboxed Worker Loader for running custom code safely
Strings: GET, SET, MGET, MSET, INCR, DECR, INCRBY, DECRBY, APPEND, STRLEN, SETEX, SETNX, GETSET
Hashes: HGET, HSET, HMGET, HMSET, HGETALL, HDEL, HEXISTS, HKEYS, HVALS, HLEN, HINCRBY
Lists: LPUSH, RPUSH, LPOP, RPOP, LRANGE, LINDEX, LSET, LLEN, LREM, LTRIM, LINSERT
Sets: SADD, SREM, SMEMBERS, SISMEMBER, SCARD, SPOP, SRANDMEMBER, SDIFF, SINTER, SUNION
Sorted Sets: ZADD, ZREM, ZSCORE, ZRANK, ZRANGE, ZREVRANGE, ZCARD, ZCOUNT, ZINCRBY, ZPOPMIN, ZPOPMAX
Keys: DEL, EXISTS, EXPIRE, TTL, PTTL, PERSIST, TYPE, KEYS, SCAN, RENAME
Server: PING, ECHO, DBSIZE, FLUSHDB, INFO
Pub/Sub: PUBLISH (subscribe via WebSocket)
``bash`
npm install redis.do
Clone and deploy your own Redis.do instance:
`bash`
git clone https://github.com/dot-do/redis.git
cd redis.do
npm install
npm run deploy
`typescript
import { Redis } from 'redis.do/client'
const redis = new Redis({
url: 'https://your-redis.do.workers.dev',
token: 'your-auth-token' // optional
})
// Use like any Redis client
await redis.set('key', 'value')
const value = await redis.get('key')
`
`bashnpm
npm install redis.do
Usage
$3
`typescript
import { Redis } from 'redis.do/client'const redis = new Redis({ url: 'https://your-redis.do.workers.dev' })
// Strings
await redis.set('name', 'Alice')
await redis.set('session', 'abc123', { ex: 3600 }) // expires in 1 hour
const name = await redis.get('name') // 'Alice'
// Counters
await redis.set('views', '0')
await redis.incr('views') // 1
await redis.incrby('views', 10) // 11
// Hashes
await redis.hset('user:1', 'name', 'Alice', 'email', 'alice@example.com')
const user = await redis.hgetall('user:1')
// { name: 'Alice', email: 'alice@example.com' }
// Lists
await redis.lpush('queue', 'job1', 'job2', 'job3')
const job = await redis.rpop('queue') // 'job1'
const jobs = await redis.lrange('queue', 0, -1) // ['job3', 'job2']
// Sets
await redis.sadd('tags', 'redis', 'cloudflare', 'serverless')
const isMember = await redis.sismember('tags', 'redis') // 1
const tags = await redis.smembers('tags')
// Sorted Sets
await redis.zadd('leaderboard', 100, 'alice', 200, 'bob', 150, 'charlie')
const top = await redis.zrevrange('leaderboard', 0, 2) // ['bob', 'charlie', 'alice']
`$3
Batch multiple commands for efficient execution:
`typescript
const pipeline = redis.pipeline()
pipeline.set('key1', 'value1')
pipeline.set('key2', 'value2')
pipeline.get('key1')
pipeline.get('key2')
pipeline.incr('counter')const results = await pipeline.exec()
// [[null, 'OK'], [null, 'OK'], [null, 'value1'], [null, 'value2'], [null, 1]]
`$3
`typescript
// Set with expiration
await redis.set('temp', 'data', { ex: 60 }) // expires in 60 seconds
await redis.set('temp2', 'data', { px: 5000 }) // expires in 5000ms// Set expiration on existing key
await redis.expire('mykey', 300) // expires in 5 minutes
// Check TTL
const ttl = await redis.ttl('mykey') // seconds remaining
const pttl = await redis.pttl('mykey') // milliseconds remaining
// Remove expiration
await redis.persist('mykey')
`$3
Redis.do exposes an Upstash-compatible REST API:
`bash
GET request
curl https://your-redis.do.workers.dev/GET/mykeyPOST request with JSON array
curl -X POST https://your-redis.do.workers.dev \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token" \
-d '["SET", "mykey", "myvalue"]'
`API Overview
$3
`typescript
import { Redis } from 'redis.do/client'const redis = new Redis({
url: string, // Your Redis.do worker URL
token?: string, // Optional auth token
enableAutoPipelining?: boolean // Auto-batch commands (default: false)
})
`$3
When using Redis.do as a library in your Cloudflare Worker:
`typescript
// Main exports
export { RedisShard, RedisPubSub, RedisCoordinator } from 'redis.do'
export { Redis.doEntrypoint } from 'redis.do'// Types
export type { Env, SetOptions, ScanOptions, ZAddOptions, ZRangeOptions } from 'redis.do'
`MCP Integration
Redis.do includes a built-in Model Context Protocol (MCP) server, enabling AI agents to interact with your Redis data directly.
$3
The MCP server is available at
/mcp on your Redis.do deployment:`
https://your-redis.do.workers.dev/mcp
`$3
Add to your Claude Desktop config (
~/Library/Application Support/Claude/claude_desktop_config.json):`json
{
"mcpServers": {
"redis.do": {
"command": "npx",
"args": ["redis.do-mcp"],
"env": {
"REDOIS_URL": "https://your-redis.do.workers.dev",
"REDOIS_TOKEN": "your-auth-token"
}
}
}
}
`$3
The MCP server exposes Redis commands as tools:
- redis_get - Get a string value
- redis_set - Set a string value with optional expiration
- redis_del - Delete keys
- redis_keys - List keys matching a pattern
- redis_hget / redis_hset / redis_hgetall - Hash operations
- redis_lpush / redis_rpush / redis_lrange - List operations
- redis_sadd / redis_smembers - Set operations
- redis_zadd / redis_zrange - Sorted set operations
- redis_do - Execute arbitrary Redis commands or JavaScript with Redis access
$3
The
redis_do tool allows executing sandboxed JavaScript with full Redis access:`javascript
// Example: Complex data processing
const keys = await redis.keys('user:*')
const users = await Promise.all(
keys.map(async (key) => ({
id: key.split(':')[1],
...await redis.hgetall(key)
}))
)
return users.filter(u => u.active === 'true')
`Deployment
$3
- Cloudflare account
- Wrangler CLI
- Node.js 18+
$3
1. Clone the repository
`bash
git clone https://github.com/dot-do/redis.git
cd redis.do
`2. Install dependencies
`bash
npm install
`3. Configure authentication (optional)
Create a
.dev.vars file for local development:`
AUTH_TOKEN=your-secret-token
`For production, set the secret:
`bash
wrangler secret put AUTH_TOKEN
`4. Deploy
`bash
Development
npm run devProduction
npm run deploy
`$3
Configure via
wrangler.jsonc:`jsonc
{
"name": "redis.do",
"main": "src/worker.ts",
"compatibility_date": "2025-01-01",
"compatibility_flags": ["nodejs_compat"],
"durable_objects": {
"bindings": [
{ "name": "REDIS_SHARDS", "class_name": "RedisShard" },
{ "name": "REDIS_PUBSUB", "class_name": "RedisPubSub" },
{ "name": "REDIS_COORDINATOR", "class_name": "RedisCoordinator" }
]
}
}
`$3
Verify your deployment:
`bash
curl https://your-redis.do.workers.dev/health
{"status":"ok","version":"0.1.0"}
`Documentation
- Getting Started
- Client Library
- Command Reference
- MCP Integration
- Deployment Guide
- Architecture
Limitations
$3
Redis.do does NOT provide true MULTI/EXEC transaction atomicity. In standard Redis, MULTI/EXEC guarantees that all commands in a transaction are executed atomically without interleaving from other clients. Redis.do does not provide this guarantee.
When using
multi() or pipeline() in Redis.do:- Commands are batched - Sent together for reduced network round trips
- Sequential execution - Commands execute in order within the batch
- No isolation - Other clients' commands may interleave between your batch commands
- No rollback - Partial execution is possible if a command fails mid-batch
- No WATCH/UNWATCH - Optimistic locking is not supported
`typescript
// This batches commands but does NOT provide atomicity
const multi = redis.multi()
multi.set('key1', 'value1')
multi.incr('counter')
const results = await multi.exec()
``Workarounds for atomicity requirements:
1. Lua scripts via EVAL - For operations that must be atomic, use Lua scripting
2. Single Durable Object - Structure data to live within a single shard for stronger consistency
3. Application-level locking - Implement distributed locks for critical sections
- Pub/Sub - SUBSCRIBE is only available via WebSocket; use PUBLISH for sending messages
- Cluster mode - Redis.do handles sharding internally; Redis Cluster commands are not supported
- Persistence - Data is persisted to SQLite in Durable Objects, not RDB/AOF files
- Lua scripting - EVAL/EVALSHA support is limited compared to standard Redis
Contributions are welcome! Please read our Contributing Guide for details.
MIT - see LICENSE file for details.
---
Built with Cloudflare Workers, Durable Objects, and SQLite