The fastest Redis client for Node.js.
Zero dependencies, 2x+ faster than ioredis, battle-tested in production.
Quick Start · Features · Configuration · Architecture · Extensions · 한국어
0 deps zero dependencies |
383 commands |
19K+ lines of tests |
< 29KB min bundle |
npm install @vcms-io/solidisimport { SolidisFeaturedClient } from '@vcms-io/solidis/featured';
const client = new SolidisFeaturedClient({ host: '127.0.0.1', port: 6379 });
await client.set('key', 'value');
const value = await client.get('key');Tip
Need a smaller bundle? Use SolidisClient with .extend() to import only the commands you use.
Minimum bundle drops to < 29KB with tree-shaking.
Tree-shakable client
import { SolidisClient } from '@vcms-io/solidis';
import { get } from '@vcms-io/solidis/command/get';
import { set } from '@vcms-io/solidis/command/set';
import type { SolidisClientExtensions } from '@vcms-io/solidis';
const extensions = { get, set } satisfies SolidisClientExtensions;
const client = new SolidisClient({ host: '127.0.0.1', port: 6379 }).extend(extensions);Transactions & Pipelines
// Transaction (MULTI/EXEC)
const tx = client.multi();
tx.set('key', 'value');
tx.incr('counter');
const results = await tx.exec();
// Pipeline (raw)
const results = await client.send([
['set', 'a', '1'],
['incr', 'counter'],
['get', 'a']
]);Pub/Sub
client.on('message', (channel, message) => {
console.log(`${channel}: ${message}`);
});
await client.subscribe('events');Generated on 2026-06-22 15:21:54 · linux x64 · Node.js v22.22.3
15 / 15 benchmarks won · 74% average speed improvement · 111% peak speed improvement
100,000 iterations × 10,000 concurrency · 1 KB payload · 10 repeats
These benchmarks have library-specific behavior that prevents a strictly fair comparison.
Ranked by performance gain of solidis over ioredis (baseline). Elapsed = median time across repeats.
All metrics per library: operations/s, commands/s, median elapsed time, and spread (coefficient of variation).
Click to expand detailed metrics table
| Benchmark | Library | ops/s | cmds/s | Elapsed | Spread |
|---|---|---|---|---|---|
| Set Mutation: SADD SISMEMBER SREM 1 KB |
solidis | 62.1K | 186.4K | 1610ms | ±8.9% |
| ioredis | 29.4K | 88.3K | 3398ms | ±5.1% | |
| List Mutation: LPUSH RPUSH LPOP RPOP LLEN 1 KB |
solidis | 40.4K | 202.0K | 2475ms | ±1.4% |
| ioredis | 21.8K | 108.8K | 4597ms | ±3.3% | |
| Set Read: SADD SISMEMBER SMEMBERS 1 KB |
solidis | 58.7K | 176.2K | 1703ms | ±1.2% |
| ioredis | 31.8K | 95.5K | 3142ms | ±1.2% | |
| Sorted Set: ZADD ZRANGE ZREM 1 KB |
solidis | 57.7K | 173.0K | 1734ms | ±2.0% |
| ioredis | 31.4K | 94.3K | 3182ms | ±1.4% | |
| Set: SET 1 KB |
solidis | 132.6K | 132.6K | 754ms | ±8.0% |
| ioredis | 73.1K | 73.1K | 1367ms | ±2.1% | |
| Expire: SET EXPIRE TTL 1 KB |
solidis | 65.7K | 197.1K | 1522ms | ±2.3% |
| ioredis | 36.3K | 109.0K | 2751ms | ±3.1% | |
| List Range: LPUSH RPUSH LRANGE 1 KB |
solidis | 48.9K | 146.7K | 2045ms | ±1.9% |
| ioredis | 27.1K | 81.3K | 3692ms | ±1.6% | |
| Hash Mutation: HMSET HMGET HDEL 1 KB |
solidis | 48.7K | 146.2K | 2052ms | ±3.1% |
| ioredis | 28.1K | 84.2K | 3564ms | ±1.0% | |
| Multi-Key: MSET MGET 1 KB |
solidis | 67.8K | 135.6K | 1475ms | ±3.3% |
| ioredis | 39.2K | 78.4K | 2551ms | ±1.8% | |
| Stream: XADD XRANGE XLEN 1 KB |
solidis | 54.1K | 162.4K | 1847ms | ±1.6% |
| ioredis | 31.4K | 94.1K | 3189ms | ±2.8% | |
| Non-Transaction: SETPX GET 1 KB |
solidis | 74.2K | 148.3K | 1348ms | ±8.4% |
| ioredis | 44.1K | 88.2K | 2269ms | ±1.2% | |
| Pipeline Mixed: SET INCR GET 1 KB |
solidis | 59.2K | 177.7K | 1688ms | ±9.3% |
| ioredis | 36.5K | 109.6K | 2738ms | ±2.4% | |
| Counter: INCR DECR 1 KB |
solidis | 98.5K | 197.0K | 1015ms | ±4.0% |
| ioredis | 62.5K | 125.0K | 1599ms | ±2.8% | |
| Hash Round-Trip: HSET HGET HGETALL 1 KB |
solidis | 52.6K | 157.8K | 1901ms | ±2.3% |
| ioredis | 35.4K | 106.1K | 2827ms | ±5.5% | |
| Get Buffer: GETBUFFER 1 KB |
solidis | 160.1K | 160.1K | 624ms | ±7.2% |
| ioredis | 107.7K | 107.7K | 928ms | ±2.2% |
Click to expand benchmark configuration
| Parameter | Value |
|---|---|
| Mode | autopipeline |
| Payload Sizes | 1 KB |
| Iterations | 100,000 |
| Warmup | 1,000 |
| Clients | 1 |
| Concurrency / Client | 10000 |
| Total Concurrency | 10000 |
| Repeats | 10 |
| Cooldown | 2500ms |
| Platform | linux x64 |
| Node.js | v22.22.3 |
| Date | 2026-06-22 15:21:54 |
- Each benchmark is run in an isolated worker thread to prevent GC and JIT cross-contamination
- Libraries are alternated between repeats to reduce ordering bias
- The Redis server is flushed and settled between each benchmark case
- Payloads use a deterministic pseudo-random pool shared by both libraries
- Elapsed time is the median across all repeat samples
- Spread is the coefficient of variation (σ / median × 100%)
|
|
|
|
|
|
Full options reference
const client = new SolidisClient({
// Connection
uri: 'redis://localhost:6379',
host: '127.0.0.1',
port: 6379,
tls: { /* tls.ConnectionOptions */ },
lazyConnect: false,
// Auth
authentication: { username: 'user', password: 'pass' },
database: 0,
// Protocol & Recovery
clientName: 'solidis',
protocol: 'RESP2', // 'RESP2' | 'RESP3'
autoReconnect: true,
enableReadyCheck: true,
maxReadyCheckRetries: 100,
readyCheckInterval: 100,
maxConnectionRetries: 20,
connectionRetryDelay: 100,
autoRecovery: {
database: true,
subscribe: true,
ssubscribe: true,
psubscribe: true,
},
// Timeouts (ms)
commandTimeout: 5000,
connectionTimeout: 2000,
socketWriteTimeout: 1000,
// Performance
maxCommandsPerPipeline: 300,
maxProcessRepliesPerChunk: 4096,
maxProcessReplyBytesPerChunk: 8_388_608, // 8MB
maxSocketWriteSizePerOnce: 65_536, // 64KB
rejectOnPartialPipelineError: false,
// Parser
parser: {
buffer: { initial: 4_194_304, shiftThreshold: 2_097_152 },
maxBulkStringLength: 536_870_912, // 512MB
},
// Misc
maxEventListenersForClient: 10_240,
maxEventListenersForSocket: 10_240,
debug: false,
debugMaxEntries: 10_240,
});graph TD
subgraph SolidisClient
direction LR
Conn[Connection<br/><sub>TCP · TLS · Reconnect</sub>]
Req[Requester<br/><sub>Queue · Pipeline · Timeout</sub>]
Parse[Parser<br/><sub>RESP2 · RESP3 · Binary-safe</sub>]
PS[PubSub<br/><sub>Channel · Pattern · Shard</sub>]
DM[Debug Memory<br/><sub>Ring buffer · Sanitized</sub>]
end
Conn -->|socket data| Req
Req -->|raw bytes| Parse
Req -->|push messages| PS
DM -.->|injected| Conn
DM -.->|injected| Req
style Conn fill:#1a1a2e,stroke:#f5a623,color:#fff
style Req fill:#1a1a2e,stroke:#f5a623,color:#fff
style Parse fill:#1a1a2e,stroke:#f5a623,color:#fff
style PS fill:#1a1a2e,stroke:#f5a623,color:#fff
style DM fill:#16213e,stroke:#555,color:#aaa
sequenceDiagram
participant App
participant Client as SolidisClient
participant Req as Requester
participant Socket as TCP Socket
App->>Client: await client.set('key', 'value')
Client->>Req: enqueue command
Note over Req: setImmediate batching
Req->>Socket: write pipeline chunk
Socket-->>Req: RESP reply bytes
Req-->>Client: parsed reply
Client-->>App: 'OK'
client.on('connect', () => {}); // TCP connected
client.on('ready', () => {}); // Auth done, ready for commands
client.on('reconnected', () => {}); // Re-established after disconnect
client.on('end', () => {}); // Connection closed
client.on('error', (err) => {}); // Non-fatal error
client.on('message', (ch, msg) => {}); // Pub/Sub message
client.on('pmessage', (pat, ch, msg) => {});
client.on('smessage', (ch, msg) => {}); // Shard channel
client.on('debug', (entry) => {}); // Debug log entryimport { unwrapSolidisError, SolidisConnectionError, SolidisRequesterError } from '@vcms-io/solidis';
try {
await client.set('key', 'value');
} catch (error) {
const root = unwrapSolidisError(error); // full causal chain
}Note
Every error thrown by Solidis is an instance of SolidisError.
Use unwrapSolidisError() to traverse the full causal chain to the root cause.
| Error Class | When |
|---|---|
SolidisConnectionError |
TCP/TLS connect failure, timeout, reset |
SolidisRequesterError |
Command timeout, pipeline rejection, write failure |
SolidisParserError |
Malformed RESP, oversized bulk string |
SolidisPubSubError |
Subscription lifecycle error |
npm install @vcms-io/solidis-extensions| Extension | Description |
|---|---|
| SpinLock | Lightweight Redis-backed mutex (single instance) |
| RedLock | Fault-tolerant distributed lock (Redlock algorithm) |
git clone https://github.com/vcms-io/solidis.git && cd solidis
npm install && npm run build && npm testTypeScript strict · zero new deps · minimal bundle impact · SemVer
MIT · See LICENSE

