Command Comparison: Lettuce → Glide
String Operations
Section titled “String Operations”SET & GET
Section titled “SET & GET”The SET command stores a key-value pair in Valkey, while GET retrieves the value associated with a key.
- Both Lettuce and Glide support these commands in a similar way.
- Glide uses CompletableFuture for all operations.
Lettuce
syncCommands.set("key", "value");String val = syncCommands.get("key"); // "value"
// With optionssyncCommands.setex("key", 60, "value"); // Set with 60 second expiryGlide
client.set("key", "value");String val = client.get("key").get(); // "value"
// With optionsclient.set("key", "value", 60);SETEX (Set with Expiry)
Section titled “SETEX (Set with Expiry)”The SETEX command sets a key with an expiration time in seconds.
- In Lettuce, this is a dedicated function.
- In Glide, expiration is handled using an additional parameter in the
set()command.
Lettuce
syncCommands.setex("key", 5, "value"); // Set with 5 second expiryGlide
client.set("key", "value", SetOptions.builder().expiry(Seconds(5L)).build()).get();SETNX (Set if Not Exists)
Section titled “SETNX (Set if Not Exists)”The SETNX command sets a key only if it does not already exist.
- In Lettuce, this is a dedicated function that returns true if the key was set, false if the key already exists.
- In Glide, this is handled using conditional set options within the
set()command.
Lettuce
Boolean result = syncCommands.setnx("key", "value"); // Returns true if key was set, false if key existsGlide
import glide.api.models.commands.SetOptions;import glide.api.models.commands.ConditionalChange;
String result = client.set("key", "value", SetOptions.builder() .conditionalSet(ConditionalChange.ONLY_IF_DOES_NOT_EXIST) .build()).get(); // Returns "OK" if key was set, null if key existsMSET & MGET (Multiple Set/Get)
Section titled “MSET & MGET (Multiple Set/Get)”The MSET command sets multiple key-value pairs in a single operation, while MGET retrieves values for multiple keys.
- In Lettuce,
mset()accepts a Map of key-value pairs. - In Glide,
mset()also accepts a Map with key-value pairs. - For
mget(), Lettuce accepts multiple keys as arguments, while Glide requires an array of keys.
Lettuce
// Multiple setMap<String, String> map = new HashMap<>();map.put("key1", "value1");map.put("key2", "value2");syncCommands.mset(map);
// Multiple getList<KeyValue<String, String>> values = syncCommands.mget("key1", "key2"); // [KeyValue[key1, value1], KeyValue[key2, value2]]Glide
// Multiple setMap<String, String> map = new HashMap<>();map.put("key1", "value1");map.put("key2", "value2");client.mset(map);
// Multiple getString[] values = client.mget(new String[]{"key1", "key2"}).get(); // ["value1", "value2"]INCR & DECR
Section titled “INCR & DECR”The INCR command increments the value of a key by 1, while DECR decrements it by 1.
- Both Lettuce and Glide support these commands in the same way.
- The key must contain an integer value, otherwise an error will be returned.
Lettuce
syncCommands.incr("counter"); // counter = 1syncCommands.decr("counter"); // counter = 0Glide
client.incr("counter").get(); // counter = 1client.decr("counter").get(); // counter = 0INCRBY & DECRBY
Section titled “INCRBY & DECRBY”The INCRBY command increases the value of a key by a specified amount, while DECRBY decreases it by a specified amount.
- Both Lettuce and Glide support these commands in the same way.
- The key must contain an integer value, otherwise an error will be returned.
Lettuce
syncCommands.incrby("counter", 5); // 5syncCommands.decrby("counter", 2); // 3Glide
client.incrBy("counter", 5).get(); // 5client.decrBy("counter", 2).get(); // 3APPEND
Section titled “APPEND”The APPEND command appends a value to the end of an existing string stored at a key.
- Both Lettuce and Glide support this command in the same way.
- Returns the length of the string after the append operation.
Lettuce
syncCommands.set("greeting", "Hello");syncCommands.append("greeting", " World"); // Returns length: 11String result = syncCommands.get("greeting"); // "Hello World"Glide
client.set("greeting", "Hello");client.append("greeting", " World").get(); // Returns length: 11String result = client.get("greeting").get(); // "Hello World"GETRANGE & SETRANGE
Section titled “GETRANGE & SETRANGE”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 Lettuce and Glide support these commands in the same way.
Lettuce
syncCommands.set("key", "Hello World");String result = syncCommands.getrange("key", 0, 4); // "Hello"
syncCommands.setrange("key", 6, "Redis"); // Returns length: 11String updated = syncCommands.get("key"); // "Hello Redis"Glide
client.set("key", "Hello World");String result = client.getRange("key", 0, 4).get(); // "Hello"
client.setRange("key", 6, "Redis").get(); // Returns length: 11String updated = client.get("key").get(); // "Hello Redis"Key Operations
Section titled “Key Operations”DEL (Delete)
Section titled “DEL (Delete)”The DEL command removes one or more keys from Valkey.
- In Lettuce,
del()accepts multiple keys as separate arguments. - In Glide,
del()requires an array of keys.
Lettuce
Long deleted = syncCommands.del("key1", "key2"); // 2 (number of keys deleted)Glide
Long deleted = client.del(new String[]{"key1", "key2"}).get(); // 2 (number of keys deleted)EXISTS
Section titled “EXISTS”The EXISTS command checks if one or more keys exist in Valkey.
- In Lettuce,
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.
Lettuce
Long count = syncCommands.exists("existKey", "nonExistKey"); // 1 (number of keys that exist)Glide
Long count = client.exists(new String[]{"existKey", "nonExistKey"}).get(); // 1 (number of keys that exist)EXPIRE & TTL
Section titled “EXPIRE & TTL”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 Lettuce,
expire()returns true if successful, false if the key doesn’t exist or couldn’t be expired. - In Glide,
expire()returns 1 if successful, 0 otherwise.
Lettuce
Boolean success = syncCommands.expire("key", 10); // true (success)Long ttl = syncCommands.ttl("key"); // 10 (seconds remaining)Glide
Long success = client.expire("key", 10).get(); // 1 (success)Long ttl = client.ttl("key").get(); // 10 (seconds remaining)KEYS & SCAN
Section titled “KEYS & SCAN”The KEYS command returns all keys matching a pattern, while SCAN iterates through keys in a more efficient way for production use.
KEYSis not recommended for production use as it blocks the server until completion.SCANis the preferred method for iterating through keys in production environments.
Lettuce
// KEYS (not recommended for production)List<String> allKeys = syncCommands.keys("*");
// SCAN (recommended for production)ScanCursor cursor = ScanCursor.INITIAL;ScanIterator<String> iterator = ScanIterator.scan(syncCommands, cursor);
while (iterator.hasNext()) { String key = iterator.next(); System.out.println("SCAN iteration: " + key);}Glide
// KEYS (not recommended for production)String[] allKeys = client.keys("*").get();
// SCAN (recommended for production)String cursor = "0";Object[] result;do { result = client.scan(cursor).get(); cursor = result[0].toString();
Object[] keys = (Object[]) result[1]; if (keys.length > 0) { System.out.println("SCAN iteration: " + Arrays.toString(keys)); }} while (!cursor.equals("0"));RENAME & RENAMENX
Section titled “RENAME & RENAMENX”The RENAME command renames a key, while RENAMENX renames a key only if the new key does not already exist.
- In Lettuce,
renamenx()returns true if successful, false if the target key already exists. - In Glide,
renameNx()returns 1 if successful, 0 if the target key already exists.
Lettuce
syncCommands.set("oldkey", "value");String result = syncCommands.rename("oldkey", "newkey"); // "OK"
syncCommands.set("key1", "value1");Boolean success = syncCommands.renamenx("key1", "key2"); // true (success)Glide
client.set("oldkey", "value");String result = client.rename("oldkey", "newkey").get(); // "OK"
client.set("key1", "value1");Long success = client.renameNx("key1", "key2").get(); // 1 (success)Hash Operations
Section titled “Hash Operations”HSET & HGET
Section titled “HSET & HGET”The HSET command sets field-value pairs in a hash stored at a key, while HGET retrieves the value of a specific field.
- In Lettuce,
hset()accepts field-value pairs as separate arguments or as a Map. - In Glide,
hset()accepts a Map with field-value pairs.
Lettuce
// Set multiple fieldsMap<String, String> map = new HashMap<>();map.put("key1", "1");map.put("key2", "2");Long added = syncCommands.hset("hash", map); // 2 (fields added)
// Get a single fieldString value = syncCommands.hget("hash", "key1"); // "1"Glide
// Set multiple fieldsMap<String, String> map = new HashMap<>();map.put("key1", "1");map.put("key2", "2");Long added = client.hset("hash", map).get(); // 2 (fields added)
// Get a single fieldString value = client.hget("hash", "key1").get(); // "1"HMSET & HMGET
Section titled “HMSET & HMGET”The HMSET command sets multiple field-value pairs in a hash, while HMGET retrieves values for multiple fields.
- In Lettuce,
hmset()accepts a Map of field-value pairs. - In Glide, there is no separate
hmset()method; instead,hset()is used for setting multiple fields. - For
hmget(), Lettuce accepts multiple fields as arguments, while Glide requires an array of fields.
Lettuce
// Set multiple fieldsMap<String, String> map = new HashMap<>();map.put("key1", "1");map.put("key2", "2");String result = syncCommands.hmset("hash", map); // "OK"
// Get multiple fieldsList<KeyValue<String, String>> values = syncCommands.hmget("hash", "key1", "key2"); // [KeyValue[key1, 1], KeyValue[key2, 2]]Glide
// Set multiple fields (same as hset in Glide)Map<String, String> map = new HashMap<>();map.put("key1", "1");map.put("key2", "2");Long added = client.hset("hash", map).get(); // 2 (fields added)
// Get multiple fieldsString[] values = client.hmget("hash", new String[]{"key1", "key2"}).get(); // ["1", "2"]HGETALL
Section titled “HGETALL”The HGETALL command retrieves all field-value pairs from a hash.
- In Lettuce, it returns a Map with field names as keys and their values.
- In Glide, it also returns a Map with field names as keys and their values.
Lettuce
Map<String, String> map = new HashMap<>();map.put("name", "John");map.put("age", "30");syncCommands.hset("user", map);
Map<String, String> user = syncCommands.hgetall("user"); // {name=John, age=30}Glide
Map<String, String> map = new HashMap<>();map.put("name", "John");map.put("age", "30");client.hset("user", map);
Map<String, String> user = client.hgetall("user").get(); // {name=John, age=30}HDEL & HEXISTS
Section titled “HDEL & HEXISTS”The HDEL command removes one or more fields from a hash, while HEXISTS checks if a field exists in a hash.
- In Lettuce,
hdel()accepts multiple fields as separate arguments and returns the number of fields removed. - In Glide,
hdel()requires an array of fields. - For
hexists(), Lettuce returns true if the field exists, false if it doesn’t, while Glide returns 1 or 0.
Lettuce
Map<String, String> map = new HashMap<>();map.put("key1", "1");map.put("key2", "2");map.put("key3", "3");syncCommands.hset("hash", map);
Long deleted = syncCommands.hdel("hash", "key1", "key2"); // 2 (fields deleted)
Boolean exists = syncCommands.hexists("hash", "key3"); // true (exists)Boolean notExists = syncCommands.hexists("hash", "key1"); // false (doesn't exist)Glide
Map<String, String> map = new HashMap<>();map.put("key1", "1");map.put("key2", "2");map.put("key3", "3");client.hset("hash", map);
Long deleted = client.hdel("hash", new String[]{"key1", "key2"}).get(); // 2 (fields deleted)
Long exists = client.hexists("hash", "key3").get(); // 1 (exists)Long notExists = client.hexists("hash", "key1").get(); // 0 (doesn't exist)List Operations
Section titled “List Operations”LPUSH & RPUSH
Section titled “LPUSH & RPUSH”The LPUSH command adds elements to the beginning of a list, while RPUSH adds elements to the end of a list.
- In Lettuce, 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.
Lettuce
Long lengthOfList = syncCommands.lpush("list", "a", "b", "c"); // lengthOfList = 3lengthOfList = syncCommands.rpush("list", "d", "e"); // lengthOfList = 5Glide
Long lengthOfList = client.lpush("list", new String[]{"a", "b", "c"}).get(); // lengthOfList = 3lengthOfList = client.rpush("list", new String[]{"d", "e"}).get(); // lengthOfList = 5LPOP & RPOP
Section titled “LPOP & RPOP”The LPOP command removes and returns the first element of a list, while RPOP removes and returns the last element.
- Both Lettuce and Glide support these commands in the same way.
- Returns null if the list doesn’t exist or is empty.
Lettuce
syncCommands.rpush("list", "a", "b", "c");String first = syncCommands.lpop("list"); // "a"String last = syncCommands.rpop("list"); // "c"Glide
client.rpush("list", new String[]{"a", "b", "c"});String first = client.lpop("list").get(); // "a"String last = client.rpop("list").get(); // "c"LRANGE
Section titled “LRANGE”The LRANGE command retrieves a range of elements from a list.
- Both Lettuce 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.
Lettuce
syncCommands.rpush("list", "a", "b", "c", "d", "e");List<String> elements = syncCommands.lrange("list", 0, 2); // ["a", "b", "c"]Glide
client.rpush("list", new String[]{"a", "b", "c", "d", "e"});String[] elements = client.lrange("list", 0, 2).get(); // ["a", "b", "c"]Set Operations
Section titled “Set Operations”SADD & SMEMBERS
Section titled “SADD & SMEMBERS”The SADD command adds one or more members to a set, while SMEMBERS returns all members of a set.
- In Lettuce,
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).
Lettuce
Long added = syncCommands.sadd("set", "a", "b", "c"); // 3 (members added)Set<String> members = syncCommands.smembers("set"); // ["a", "b", "c"]Glide
Long added = client.sadd("set", new String[]{"a", "b", "c"}).get(); // 3 (members added)String[] members = client.smembers("set").get(); // ["a", "b", "c"]SREM & SISMEMBER
Section titled “SREM & SISMEMBER”The SREM command removes one or more members from a set, while SISMEMBER checks if a value is a member of a set.
- In Lettuce,
srem()accepts multiple members as separate arguments and returns the number of members removed. - In Glide,
srem()requires an array of members. - For
sismember(), Lettuce returns true if the member exists, false if it doesn’t, while Glide returns 1 or 0.
Lettuce
syncCommands.sadd("set", "a", "b", "c");Long removed = syncCommands.srem("set", "a", "b"); // 2 (members removed)
Boolean isMember = syncCommands.sismember("set", "c"); // true (is member)Boolean notMember = syncCommands.sismember("set", "a"); // false (not member)Glide
client.sadd("set", new String[]{"a", "b", "c"});Long removed = client.srem("set", new String[]{"a", "b"}).get(); // 2 (members removed)
Long isMember = client.sismember("set", "c").get(); // 1 (is member)Long notMember = client.sismember("set", "a").get(); // 0 (not member)Sorted Set Operations
Section titled “Sorted Set Operations”ZADD & ZRANGE
Section titled “ZADD & ZRANGE”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 Lettuce,
zadd()accepts score-member pairs as separate arguments or as a Map. - In Glide,
zadd()requires an array of objects with score and member properties. - For
zrange()with scores, Lettuce uses a boolean parameter, while Glide uses an options object.
Lettuce
Map<String, Double> scoreMembers = new HashMap<>();scoreMembers.put("one", 1.0);scoreMembers.put("two", 2.0);scoreMembers.put("three", 3.0);Long added = syncCommands.zadd("sortedSet", scoreMembers); // 3 (members added)
List<String> members = syncCommands.zrange("sortedSet", 0, -1); // ["one", "two", "three"]
// With scoresList<ScoredValue<String>> withScores = syncCommands.zrangeWithScores("sortedSet", 0, -1);// [ScoredValue[score=1.0, value=one], ScoredValue[score=2.0, value=two], ScoredValue[score=3.0, value=three]]Glide
// Glide requires an array of objects with score and member propertiesObject[] scoreMembers = new Object[] { new Object[] { 1.0, "one" }, new Object[] { 2.0, "two" }, new Object[] { 3.0, "three" }};Long added = client.zadd("sortedSet", scoreMembers).get(); // 3 (members added)
String[] members = client.zrange("sortedSet", 0, -1).get(); // ["one", "two", "three"]
// With scoresObject[] withScores = client.zrange("sortedSet", 0, -1, "WITHSCORES").get();// ["one", "1", "two", "2", "three", "3"]ZREM & ZSCORE
Section titled “ZREM & ZSCORE”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 Lettuce,
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.
Lettuce
Map<String, Double> scoreMembers = new HashMap<>();scoreMembers.put("one", 1.0);scoreMembers.put("two", 2.0);scoreMembers.put("three", 3.0);syncCommands.zadd("sortedSet", scoreMembers);
Long removed = syncCommands.zrem("sortedSet", "one", "two"); // 2 (members removed)
Double score = syncCommands.zscore("sortedSet", "three"); // 3.0Glide
Object[] scoreMembers = new Object[] { new Object[] { 1.0, "one" }, new Object[] { 2.0, "two" }, new Object[] { 3.0, "three" }};client.zadd("sortedSet", scoreMembers);
Long removed = client.zrem("sortedSet", new String[]{"one", "two"}).get(); // 2 (members removed)
String score = client.zscore("sortedSet", "three").get(); // "3"ZRANK & ZREVRANK
Section titled “ZRANK & ZREVRANK”The ZRANK command returns the rank (position) of a member in a sorted set, while ZREVRANK returns the rank in reverse order.
- Both Lettuce and Glide support these commands in the same way.
- Ranks are 0-based, meaning the member with the lowest score has rank 0.
ZREVRANKreturns the rank in descending order, where the member with the highest score has rank 0.
Lettuce
Map<String, Double> scoreMembers = new HashMap<>();scoreMembers.put("one", 1.0);scoreMembers.put("two", 2.0);scoreMembers.put("three", 3.0);syncCommands.zadd("sortedSet", scoreMembers);
Long rank = syncCommands.zrank("sortedSet", "two"); // 1 (0-based index)Long revRank = syncCommands.zrevrank("sortedSet", "two"); // 1 (0-based index from end)Glide
Object[] scoreMembers = new Object[] { new Object[] { 1.0, "one" }, new Object[] { 2.0, "two" }, new Object[] { 3.0, "three" }};client.zadd("sortedSet", scoreMembers);
Long rank = client.zrank("sortedSet", "two").get(); // 1 (0-based index)Long revRank = client.zrevrank("sortedSet", "two").get(); // 1 (0-based index from end)Transactions
Section titled “Transactions”Transactions (MULTI / EXEC)
Section titled “Transactions (MULTI / EXEC)”The MULTI command starts a transaction block, while EXEC executes all commands issued after MULTI.
- In Lettuce, transactions are created using
syncCommands.multi()and executed withexec(). - In Glide, transactions are created using the
Transactionclass and executed withclient.exec(). - The result format differs: Lettuce returns a list of results, while Glide returns an array of results.
Lettuce
syncCommands.multi();syncCommands.set("key", "value");syncCommands.get("key");TransactionResult result = syncCommands.exec();System.out.println(result.get(0)); // "OK"System.out.println(result.get(1)); // "value"Glide
Transaction transaction = new Transaction();transaction.set("key", "value");transaction.get("key");Object[] result = client.exec(transaction).get();System.out.println(result[0]); // "OK"System.out.println(result[1]); // "value"Lua Scripts
Section titled “Lua Scripts”EVAL / EVALSHA
Section titled “EVAL / EVALSHA”The EVAL command executes a Lua script on the server, while EVALSHA executes a script cached on the server using its SHA1 hash.
- In Lettuce, these commands require specifying the number of keys and passing keys and arguments separately.
- In Glide, scripts are created using the
Scriptclass and executed withinvokeScript(), with keys and arguments passed in a single options object. - Glide automatically handles script caching, so there’s no need for separate
EVALSHAhandling.
Lettuce
// EVALString luaScript = "return { KEYS[1], ARGV[1] }";List<String> keys = Collections.singletonList("foo");List<String> args = Collections.singletonList("bar");
Object result = syncCommands.eval(luaScript, ScriptOutputType.MULTI, keys.toArray(new String[0]), args.toArray(new String[0]));System.out.println(result); // [foo, bar]
// EVALSHAString sha = syncCommands.scriptLoad(luaScript);Object shaResult = syncCommands.evalsha(sha, ScriptOutputType.MULTI, keys.toArray(new String[0]), args.toArray(new String[0]));System.out.println(shaResult); // [foo, bar]Glide
import glide.api.models.Script;import glide.api.models.ScriptOptions;
String luaScript = "return { KEYS[1], ARGV[1] }";Script script = new Script(luaScript, false);ScriptOptions options = ScriptOptions.builder() .key("foo") .arg("bar") .build();
Object result = client.invokeScript(script, options).get();System.out.println(Arrays.toString((Object[]) result)); // [foo, bar]Authentication
Section titled “Authentication”The AUTH command authenticates a client connection to the Valkey server.
- In Lettuce, authentication is done using the
auth()method. - In Glide, authentication is handled using
updateConnectionPassword().
Lettuce
String result = syncCommands.auth("mypass"); // OKGlide
String result = client.updateConnectionPassword("mypass", true).get(); // OKCustom Commands
Section titled “Custom Commands”Custom Commands
Section titled “Custom Commands”Both Lettuce and Glide provide ways to execute custom commands.
- In Lettuce, you can execute raw commands using
dispatch()or create custom commands using Lua scripts. - In Glide, you can execute raw commands using
customCommand()or use theScriptclass for Lua scripts.
Lettuce
// Execute a raw commandObject rawResult = syncCommands.dispatch(CommandType.SET, new StatusOutput<>(StringCodec.UTF8), new CommandArgs<>(StringCodec.UTF8) .addKey("key") .addValue("value"));System.out.println(rawResult); // "OK"Glide
// Execute a raw commandString rawResult = client.customCommand(new String[]{"SET", "key", "value"}).get();System.out.println(rawResult); // "OK"Connection Management
Section titled “Connection Management”Close / Disconnect
Section titled “Close / Disconnect”Properly closing connections is important to free up resources and avoid connection leaks.
- In Lettuce, you need to close both the connection and shut down the client.
- In Glide, you only need to call
close()on the client.
Lettuce
// Close connection and shutdown clientconnection.close();client.shutdown();
// For cluster connectionsclusterConnection.close();clusterClient.shutdown();Glide
// Close client (works for both standalone and cluster)client.close();