Skip to content

Command Comparison: ioredis → Glide

The SET command stores a key-value pair in Valkey, while GET retrieves the value associated with a key.

  • Both ioredis and Glide support these commands in the same way.

ioredis

await redis.set('key', 'value');
const val = await redis.get('key'); // "value"
// With options
await redis.set('key', 'value', 'EX', 60); // Set with 60 second expiry

Glide

await client.set('key', 'value');
const val = await client.get('key'); // "value"
// With options
import { TimeUnit } from "@valkey/valkey-glide";
await client.set('key', 'value', {
expiry: {
type: TimeUnit.Seconds,
count: 60
}
});

The SETEX command sets a key with an expiration time in seconds.

  • In ioredis, this is a dedicated function.
  • In Glide, expiration is handled using options within the set() command.

ioredis

await redis.setex('key', 5, 'value'); // Set with 5 second expiry

Glide

import { TimeUnit } from "@valkey/valkey-glide";
await client.set('key', 'value', {
expiry: {
type: TimeUnit.Seconds,
count: 5
}
});

The SETNX command sets a key only if it does not already exist.

  • In ioredis, this is a dedicated function that returns 1 if the key was set, 0 if the key already exists.
  • In Glide, this is handled using options within the set() command.

ioredis

const result = await redis.setnx('key', 'value'); // Returns 1 if key was set, 0 if key exists

Glide

// Returns "OK" if key was set, null if key exists
const result = await client.set("key", "value", {conditionalSet: "onlyIfDoesNotExist"});

The MSET command sets multiple key-value pairs in a single operation, while MGET retrieves values for multiple keys.

  • In ioredis, mset() accepts either key-value pairs as arguments or an object.
  • In Glide, mset() accepts only an object with key-value pairs.
  • For mget(), ioredis accepts multiple keys as arguments, while Glide requires an array of keys.

ioredis

// Multiple set
await redis.mset('key1', 'value1', 'key2', 'value2');
// or as an object
await redis.mset({
key1: 'value1',
key2: 'value2'
});
// Multiple get
const values = await redis.mget('key1', 'key2'); // ['value1', 'value2']

Glide

// Multiple set
await client.mset({
key1: 'value1',
key2: 'value2'
});
// Multiple get
const values = await client.mget(['key1', 'key2']); // ['value1', 'value2']

The INCR command increments the value of a key by 1, while DECR decrements it by 1.

  • Both ioredis and Glide support these commands in the same way.
  • The key must contain an integer value, otherwise an error will be returned.

ioredis

await redis.incr('counter'); // counter = 1
await redis.decr('counter'); // counter = 0

Glide

await client.incr('counter'); // counter = 1
await client.decr('counter'); // counter = 0

The INCRBY command increases the value of a key by a specified amount, while DECRBY decreases it by a specified amount.

  • Both ioredis and Glide support these commands in the same way.
  • The key must contain an integer value, otherwise an error will be returned.

ioredis

await redis.incrby('counter', 5); // 5
await redis.decrby('counter', 2); // 3

Glide

await client.incrBy('counter', 5); // 5
await client.decrBy('counter', 2); // 3

The APPEND command appends a value to the end of an existing string stored at a key.

  • Both ioredis and Glide support this command in the same way.
  • Returns the length of the string after the append operation.

ioredis

await redis.set('greeting', 'Hello');
await redis.append('greeting', ' World'); // Returns length: 11
const result = await redis.get('greeting'); // "Hello World"

Glide

await client.set('greeting', 'Hello');
await client.append('greeting', ' World'); // Returns length: 11
const result = await client.get('greeting'); // "Hello World"

The GETRANGE command retrieves a substring from a string value stored at a key, while SETRANGE overwrites part of a string at a key starting at a specified offset.

  • Both ioredis and Glide support these commands in the same way.
  • Note the camelCase method names in Glide: getRange and setRange.

ioredis

await redis.set('key', 'Hello World');
const result = await redis.getrange('key', 0, 4); // "Hello"
await redis.setrange('key', 6, 'Redis'); // Returns length: 11
const updated = await redis.get('key'); // "Hello Redis"

Glide

await client.set('key', 'Hello World');
const result = await client.getRange('key', 0, 4); // "Hello"
await client.setRange('key', 6, 'Redis'); // Returns length: 11
const updated = await client.get('key'); // "Hello Redis"

The DEL command removes one or more keys from Valkey.

  • In ioredis, del() accepts multiple keys as separate arguments.
  • In Glide, del() requires an array of keys.

ioredis

await redis.del('key1', 'key2'); // 2 (number of keys deleted)

Glide

await client.del(['key1', 'key2']); // 2 (number of keys deleted)

The EXISTS command checks if one or more keys exist in Valkey.

  • In ioredis, exists() accepts multiple keys as separate arguments and returns the number of keys that exist.
  • In Glide, exists() requires an array of keys and also returns the number of keys that exist.

ioredis

await redis.exists('existKey', 'nonExistKey'); // 1 (number of keys that exist)

Glide

await client.exists(['existKey', 'nonExistKey']); // 1 (number of keys that exist)

The EXPIRE command sets a time-to-live (TTL) for a key, after which it will be automatically deleted. The TTL command returns the remaining time-to-live for a key.

  • In ioredis, expire() returns 1 if successful, 0 if the key doesn’t exist or couldn’t be expired.
  • In Glide, expire() returns true if successful, false otherwise.

ioredis

await redis.expire('key', 10); // 1 (success)
const ttl = await redis.ttl('key'); // 10 (seconds remaining)

Glide

await client.expire('key', 10); // true (success)
const ttl = await client.ttl('key'); // 10 (seconds remaining)

The KEYS command returns all keys matching a pattern, while SCAN iterates through keys in a more efficient way for production use.

  • KEYS is not recommended for production use as it blocks the server until completion.
  • SCAN is the preferred method for iterating through keys in production environments.
  • In Glide, the cursor returned by scan() needs to be converted to a string using toString().

ioredis

// KEYS (not recommended for production)
const allKeys = await redis.keys('*');
// SCAN (recommended for production)
let cursor = '0';
let result;
do {
result = await redis.scan(cursor);
cursor = result[0];
const keys = result[1];
if (keys.length > 0) {
console.log('SCAN iteration: ' + keys.join(', '));
}
} while (cursor !== '0');

Glide

// KEYS (not recommended for production)
const allKeys = await client.keys('*');
// SCAN (recommended for production)
let cursor = '0';
let result;
do {
result = await client.scan(cursor);
cursor = result[0].toString();
const keys = result[1];
if (keys.length > 0) {
console.log('SCAN iteration: ' + keys.join(', '));
}
} while (cursor !== '0');

The RENAME command renames a key, while RENAMENX renames a key only if the new key does not already exist.

  • In ioredis, renamenx() returns 1 if successful, 0 if the target key already exists.
  • In Glide, renameNx() returns true if successful, false if the target key already exists.
  • Note the camelCase method name in Glide: renameNx.

ioredis

await redis.set('oldkey', 'value');
await redis.rename('oldkey', 'newkey'); // "OK"
await redis.set('key1', 'value1');
const result = await redis.renamenx('key1', 'key2'); // 1 (success)

Glide

await client.set('oldkey', 'value');
await client.rename('oldkey', 'newkey'); // "OK"
await client.set('key1', 'value1');
const result = await client.renameNx('key1', 'key2'); // true (success)

The HSET command sets field-value pairs in a hash stored at a key, while HGET retrieves the value of a specific field.

  • In ioredis, hset() accepts field-value pairs as separate arguments.
  • In Glide, hset() accepts an object with field-value pairs.

ioredis

// Set multiple fields
await redis.hset('hash', 'key1', '1', 'key2', '2'); // 2 (fields added)
// Get a single field
const value = await redis.hget('hash', 'key1'); // "1"

Glide

// Set multiple fields
await client.hset('hash', { key1: '1', key2: '2' }); // 2 (fields added)
// Get a single field
const value = await client.hget('hash', 'key1'); // "1"

The HMSET command sets multiple field-value pairs in a hash, while HMGET retrieves values for multiple fields.

  • In ioredis, hmset() accepts either field-value pairs as arguments or an object.
  • In Glide, there is no separate hmset() method; instead, hset() is used for setting multiple fields.
  • For hmget(), ioredis accepts multiple fields as arguments, while Glide requires an array of fields.

ioredis

// Set multiple fields
await redis.hmset('hash', 'key1', '1', 'key2', '2');
// or as an object
await redis.hmset('hash', { key1: '1', key2: '2' });
// Get multiple fields
const values = await redis.hmget('hash', 'key1', 'key2'); // ["1", "2"]

Glide

// Set multiple fields (same as hset in Glide)
await client.hset('hash', { key1: '1', key2: '2' });
// Get multiple fields
const values = await client.hmget('hash', ['key1', 'key2']); // ["1", "2"]

The HGETALL command retrieves all field-value pairs from a hash.

  • Both ioredis and Glide support this command in the same way.
  • Returns an object with field names as keys and their values.

ioredis

await redis.hset('user', { name: 'John', age: '30' });
const user = await redis.hgetall('user'); // { name: 'John', age: '30' }

Glide

await client.hset('user', { name: 'John', age: '30' });
const user = await client.hgetall('user'); // { name: 'John', age: '30' }

The HDEL command removes one or more fields from a hash, while HEXISTS checks if a field exists in a hash.

  • In ioredis, hdel() accepts multiple fields as separate arguments and returns the number of fields removed.
  • In Glide, hdel() requires an array of fields.
  • For hexists(), ioredis returns 1 if the field exists, 0 if it doesn’t, while Glide returns true or false.

ioredis

await redis.hset('hash', { key1: '1', key2: '2', key3: '3' });
await redis.hdel('hash', 'key1', 'key2'); // 2 (fields deleted)
const exists = await redis.hexists('hash', 'key3'); // 1 (exists)
const notExists = await redis.hexists('hash', 'key1'); // 0 (doesn't exist)

Glide

await client.hset('hash', { key1: '1', key2: '2', key3: '3' });
await client.hdel('hash', ['key1', 'key2']); // 2 (fields deleted)
const exists = await client.hexists('hash', 'key3'); // true
const notExists = await client.hexists('hash', 'key1'); // false

The LPUSH command adds elements to the beginning of a list, while RPUSH adds elements to the end of a list.

  • In ioredis, these commands accept multiple elements as separate arguments.
  • In Glide, they require an array of elements.
  • Both return the length of the list after the operation.

ioredis

let lengthOfList = await redis.lpush('list', 'a', 'b', 'c'); // lengthOfList = 3
lengthOfList = await redis.rpush('list', 'd', 'e'); // lengthOfList = 5

Glide

let lengthOfList = await client.lpush('list', ['a', 'b', 'c']); // lengthOfList = 3
lengthOfList = await client.rpush('list', ['d', 'e']); // lengthOfList = 5

The LPOP command removes and returns the first element of a list, while RPOP removes and returns the last element.

  • Both ioredis and Glide support these commands in the same way.
  • Returns null if the list doesn’t exist or is empty.

ioredis

await redis.rpush('list', 'a', 'b', 'c');
const first = await redis.lpop('list'); // "a"
const last = await redis.rpop('list'); // "c"

Glide

await client.rpush('list', ['a', 'b', 'c']);
const first = await client.lpop('list'); // "a"
const last = await client.rpop('list'); // "c"

The LRANGE command retrieves a range of elements from a list.

  • Both ioredis and Glide support this command in the same way.
  • The range is specified by start and stop indices, where 0 is the first element, -1 is the last element.

ioredis

await redis.rpush('list', 'a', 'b', 'c', 'd', 'e');
const elements = await redis.lrange('list', 0, 2); // ["a", "b", "c"]

Glide

await client.rpush('list', ['a', 'b', 'c', 'd', 'e']);
const elements = await client.lrange('list', 0, 2); // ["a", "b", "c"]

The SADD command adds one or more members to a set, while SMEMBERS returns all members of a set.

  • In ioredis, sadd() accepts multiple members as separate arguments.
  • In Glide, sadd() requires an array of members.
  • Both return the number of members that were added to the set (excluding members that were already present).

ioredis

await redis.sadd('set', 'a', 'b', 'c'); // 3 (members added)
const members = await redis.smembers('set'); // ["a", "b", "c"]

Glide

await client.sadd('set', ['a', 'b', 'c']); // 3 (members added)
const members = await client.smembers('set'); // ["a", "b", "c"]

The SREM command removes one or more members from a set, while SISMEMBER checks if a value is a member of a set.

  • In ioredis, srem() accepts multiple members as separate arguments and returns the number of members removed.
  • In Glide, srem() requires an array of members.
  • For sismember(), ioredis returns 1 if the member exists, 0 if it doesn’t, while Glide returns true or false.

ioredis

await redis.sadd('set', 'a', 'b', 'c');
await redis.srem('set', 'a', 'b'); // 2 (members removed)
const isMember = await redis.sismember('set', 'c'); // 1 (is member)
const notMember = await redis.sismember('set', 'a'); // 0 (not member)

Glide

await client.sadd('set', ['a', 'b', 'c']);
await client.srem('set', ['a', 'b']); // 2 (members removed)
const isMember = await client.sismember('set', 'c'); // true
const notMember = await client.sismember('set', 'a'); // false

The ZADD command adds one or more members with scores to a sorted set, while ZRANGE retrieves members from a sorted set by index range.

  • In ioredis, zadd() accepts score-member pairs as separate arguments.
  • In Glide, zadd() requires an array of objects with score and member properties.
  • For zrange() with scores, ioredis uses a ‘WITHSCORES’ string parameter, while Glide uses an options object.

ioredis

await redis.zadd('sortedSet', 1, 'one', 2, 'two', 3, 'three'); // 3 (members added)
const members = await redis.zrange('sortedSet', 0, -1); // ["one", "two", "three"]
// With scores
const withScores = await redis.zrange('sortedSet', 0, -1, 'WITHSCORES');
// ["one", "1", "two", "2", "three", "3"]

Glide

await client.zadd('sortedSet', [
{ score: 1, member: 'one' },
{ score: 2, member: 'two' },
{ score: 3, member: 'three' }
]); // 3 (members added)
const members = await client.zrange('sortedSet', 0, -1); // ["one", "two", "three"]
// With scores
const withScores = await client.zrange('sortedSet', 0, -1, { withScores: true });
// ["one", "1", "two", "2", "three", "3"]

The ZREM command removes one or more members from a sorted set, while ZSCORE returns the score of a member in a sorted set.

  • In ioredis, zrem() accepts multiple members as separate arguments.
  • In Glide, zrem() requires an array of members.
  • Both return the number of members that were removed from the sorted set.

ioredis

await redis.zadd('sortedSet', 1, 'one', 2, 'two', 3, 'three');
await redis.zrem('sortedSet', 'one', 'two'); // 2 (members removed)
const score = await redis.zscore('sortedSet', 'three'); // "3"

Glide

await client.zadd('sortedSet', [
{ score: 1, member: 'one' },
{ score: 2, member: 'two' },
{ score: 3, member: 'three' }
]);
await client.zrem('sortedSet', ['one', 'two']); // 2 (members removed)
const score = await client.zscore('sortedSet', 'three'); // "3"

The ZRANK command returns the rank (position) of a member in a sorted set, while ZREVRANK returns the rank in reverse order.

  • Both ioredis and Glide support these commands in the same way.
  • Ranks are 0-based, meaning the member with the lowest score has rank 0.
  • ZREVRANK returns the rank in descending order, where the member with the highest score has rank 0.

ioredis

await redis.zadd('sortedSet', 1, 'one', 2, 'two', 3, 'three');
const rank = await redis.zrank('sortedSet', 'two'); // 1 (0-based index)
const revRank = await redis.zrevrank('sortedSet', 'two'); // 1 (0-based index from end)

Glide

await client.zadd('sortedSet', [
{ score: 1, member: 'one' },
{ score: 2, member: 'two' },
{ score: 3, member: 'three' }
]);
const rank = await client.zrank('sortedSet', 'two'); // 1 (0-based index)
const revRank = await client.zrevrank('sortedSet', 'two'); // 1 (0-based index from end)

The MULTI command starts a transaction block, while EXEC executes all commands issued after MULTI.

  • In ioredis, transactions are created using redis.multi() and executed with exec().
  • In Glide, transactions are created using the Transaction class and executed with client.exec().
  • The result format differs: ioredis returns an array of arrays with errors and results, while Glide returns an array of results.

ioredis

const transaction = redis.multi()
.set("key", "value")
.get("key");
const result = await transaction.exec();
console.log(result); // [ [ null, 'OK' ], [ null, 'value' ] ]

Glide

import { Transaction } from "@valkey/valkey-glide";
const transaction = new Transaction()
.set("key", "value")
.get("key");
const result = await client.exec(transaction);
console.log(result); // ['OK', 'value']

The EVAL command executes a Lua script on the server, while EVALSHA executes a script cached on the server using its SHA1 hash.

  • In ioredis, these commands require specifying the number of keys and passing keys and arguments separately.
  • In Glide, scripts are created using the Script class and executed with invokeScript(), with keys and arguments passed in a single options object.
  • Glide automatically handles script caching, so there’s no need for separate EVALSHA handling.

ioredis

// EVAL
const luaScript = `return { KEYS[1], ARGV[1] }`;
const scriptOptions = {
keys: ["foo"],
args: ["bar"],
};
const result = await redis.eval(
luaScript,
1,
...scriptOptions.keys,
...scriptOptions.args
);
console.log(result); // ['foo', 'bar']
// EVALSHA
const sha = await redis.script('load', luaScript);
const shaResult = await redis.evalsha(
sha,
1,
...scriptOptions.keys,
...scriptOptions.args
);
console.log(shaResult); // ['foo', 'bar']

Glide

import { Script } from "@valkey/valkey-glide";
const luaScript = new Script("return { KEYS[1], ARGV[1] }");
const scriptOptions = {
keys: ["foo"],
args: ["bar"],
};
const result = await client.invokeScript(luaScript, scriptOptions);
console.log(result); // ['foo', 'bar']

The AUTH command authenticates a client connection to the Valkey server.

  • In ioredis, authentication is done using the auth() method.
  • In Glide, authentication is handled using updateConnectionPassword().

ioredis

await redis.auth('mypass'); // OK

Glide

await client.updateConnectionPassword('mypass'); // OK

The defineCommand feature in ioredis allows defining custom commands, while Glide provides a customCommand method for executing raw commands.

  • In ioredis, you can define custom commands using Lua scripts or execute raw commands using call().
  • In Glide, you can execute raw commands using customCommand() or use the Script class for Lua scripts.

ioredis

// Define a custom command
redis.defineCommand('echo', {
numberOfKeys: 0,
lua: 'return ARGV[1]'
});
// Use the custom command
const result = await redis.echo('Hello');
console.log(result); // "Hello"
// Or execute a raw command
const rawResult = await redis.call('SET', 'key', 'value');
console.log(rawResult); // "OK"

Glide

// Execute a raw command
const result = await client.customCommand(['SET', 'key', 'value']);
console.log(result); // "OK"
// For Lua scripts, use Script class
import { Script } from "@valkey/valkey-glide";
const echoScript = new Script("return ARGV[1]");
const scriptResult = await client.invokeScript(echoScript, {
args: ["Hello"]
});
console.log(scriptResult); // "Hello"

Properly closing connections is important to free up resources and avoid connection leaks.

  • In ioredis, you use disconnect() to close the connection.
  • In Glide, you use close() to close the client connection.

ioredis

// Close connection
await redis.disconnect();
// For cluster connections
await cluster.disconnect();

Glide

// Close client (works for both standalone and cluster)
await client.close();