Redis 7.0 makes Functions deployable and Pub/Sub shard-aware
Redis 7.0 reaches general availability with a stable Functions interface and shard-scoped publication. These features make server-side code and message routing explicit parts of application deployment.
Redis 7.0 adds new ways to place application work near its data. Functions give server-side code a named library lifecycle. Sharded Pub/Sub limits message distribution to the nodes serving a shard. Both changes require an application to describe its intent more explicitly than simply sending a command to any available Redis connection.
The 7.0.0 release notes date general availability to April 27. The release includes the features introduced through the candidates, along with fixes and interface changes made during that sequence. Using the stable tag matters because some candidate interfaces changed before this release, including the syntax used to load a Function library.
I value Redis's direct command model. These additions are useful where they make the application's placement decisions visible, but they also give client code and deployment tooling more responsibilities. A named function must exist before it can be called, and a shard channel needs the routing expected by its command family.
A Function library identifies itself in its source
The stable Functions interface puts the engine and library name in the source header. The release notes describe removing the separate engine and name arguments that appeared in RC1. A separate library description argument also disappears. An example copied from that candidate therefore needs more than a change to the server binary.
The 7.0.0 Functions tests show a source header followed by function registration. A minimal Lua library can use this form.
#!lua name=greeting
redis.register_function('hello', function(keys, args)
return 'hello'
end)
FUNCTION LOAD receives the full library source as its argument. Once loaded, the registered function can be invoked with FCALL hello 0. The zero supplies the number of keys in this call. The library's name identifies the loaded collection of code, while the registered function name identifies the callable entry point.
Moving identifying information into the source makes the source artifact more self-describing. A deployment transporting the library does not need to keep separate positional arguments synchronized with a name stored elsewhere. The code itself declares the engine and library name that the loader must interpret.
The tests exercise loading and replacement failures as well as successful calls. A deployment needs to handle that lifecycle rather than assuming that a connection implies a function exists. Function registration is shared server state with consequences for every caller of that name.
Server-side code still follows cluster key constraints
The stable release explicitly prevents cross-slot operations in Functions and scripts with a shebang. Placing code on the server does not grant it permission to ignore the cluster's key distribution. The operation still needs a key-access pattern that the execution path supports.
That distinction matters to the design of a library. A function can combine several Redis commands without making arbitrary distributed coordination available inside the function body. Its declared keys and the slots they occupy remain part of the contract between caller and server.
The stable release also removes access to Lua's print function. This is another example of server-side Lua being an execution environment defined by Redis, not a general-purpose process with every familiar facility available. Library authors need to use the facilities that the particular Redis version provides.
The release includes security fixes to the Lua environment as well. Its notes identify a crafted-script crash and a weakness allowing code to execute with another user's privileges. These are separate from the new library interface, but they reinforce why the execution environment and its authorization behavior need attention alongside convenient function calls.
Sharded Pub/Sub changes message propagation
The Pub/Sub implementation uses a common publication wrapper with an explicit sharded flag. Ordinary PUBLISH supplies false, while SPUBLISH supplies true. Local delivery and cluster propagation both receive that distinction.
The cluster propagation code then takes different paths. Ordinary publication calls the broadcast form of clusterSendPublish. Sharded publication obtains the nodes serving the current shard's slots and sends a shard publication message to those peers. The difference is visible in the destination set, not merely in a command's spelling.
Subscriptions also have separate bookkeeping. SSUBSCRIBE adds shard-channel subscriptions and records their relationship to slots when needed. SUNSUBSCRIBE removes them. The server maintains a separate shard-channel dictionary for introspection, with PUBSUB SHARDCHANNELS and PUBSUB SHARDNUMSUB operating on that dictionary.
The following commands illustrate the separate command family. Subscription and publication need separate client connections, and a cluster deployment must direct them to the appropriate shard.
SSUBSCRIBE notifications
SPUBLISH notifications update-ready
The second command is for the publishing connection. The example does not imply that placing both commands sequentially on one subscribed connection is the correct client workflow. A subscriber receives messages, while a publisher issues the publication operation.
The two Pub/Sub paths are distinct interfaces
An application adopting sharded publication needs its clients to use the corresponding subscription commands. The implementation's separate dictionaries make that distinction concrete. A subscription recorded in the ordinary channel map is not the same object as a shard subscription using the same channel text.
That affects migration of an existing messaging pattern. Changing only the publisher's command would change the path used to find recipients. The subscriber side and routing behavior need to agree with that choice. The server cannot infer the intended transition from the channel name alone.
The narrower destination set also explains the scaling motivation. A shard-scoped message does not require the same cluster-wide propagation path as ordinary publication. That is useful when messages belong to a distributed subset of the application. It is still an application decision to identify the correct scope for a channel.
Publication's reply should also be interpreted through the implementation. The wrapper obtains the receiver count from local publication, then separately sends the cluster message. The count is not a distributed acknowledgement that every remote application processed the message. Treating it as such would attribute a completion guarantee that the code path does not provide.
Authorization includes channel access
Redis 7.0 also changes the default Pub/Sub permissions for new ACL users. The stable configuration documents resetchannels as the default for acl-pubsub-default. That differs from granting access to every channel. A role can have command permissions without the intended channel permissions.
This makes channel authorization part of introducing the new command family. An application receiving an authorization failure needs to distinguish permission to execute the command from permission to use the selected channel. The configuration describes these separately because a shared server may have different users with different messaging responsibilities.
I prefer explicit channel scope and permissions in a deployment that relies on Pub/Sub. The additional configuration is justified when it prevents one application's messaging access from becoming an accidental default for every user. The release's command and channel distinctions give the operator a more precise description of that access.
The stable configuration also supplies maxmemory-clients to cap aggregate memory held by normal and Pub/Sub client connections. When the limit is reached, Redis drops connections, attempting to free memory by selecting the largest consumers first. The feature is disabled by default. This is a separate control from choosing how far a message propagates through the cluster.
A narrower propagation path can reduce distribution work without bounding the memory retained by a slow receiving client. Client eviction addresses that different resource problem. Together the settings let a deployment distinguish message scope from connection resource policy, instead of expecting sharding alone to define every aspect of subscriber behavior.
Persistence remains a separate upgrade boundary
The stable release retains multipart AOF and RDB version 10. Its cumulative notes warn that the RDB format is incompatible with older Redis versions. The append-only layout stores multiple files in a dedicated directory. New client features therefore arrive alongside changes to recovery artifacts.
A successful function call or message subscription does not validate those artifacts. The application interface and the recovery interface have different consumers. The server must load its persisted state, while clients must use the command syntax and routing that the stable release supports.
Redis 7.0 provides defined interfaces for both kinds of work. Function source now carries its identifying header, and sharded publication follows an explicit propagation path. Applications can use those facilities while retaining a precise account of the loaded code, channel scope, and persistence format on which their deployment depends.