Aerospike Database 8.2.0: The expression language becomes part of the database
Aerospike Database 8.2.0 moves the expression language, query planning, and error reporting into the server, cuts what a multi-availability-zone cluster pays in cross-zone networking, and brings planned node restarts back warm.
Ronen Botzer Director of Product Published September 30, 2026 Read time 13 min read
For the past year, most of Aerospike's developer-facing work has happened outside the database. New Java and Python SDKs replaced verbose builder code with a fluent API. Aerospike Voyager gave developers a way to browse a cluster and compose a query without writing a program first. Path expressions, generally available in 8.1.2, made nested documents queryable in place. Aerospike Database 8.2.0 is where the database itself catches up.
This release lands in three parts. The largest is developer experience: expression parsing, query optimization, string manipulation, and error detail all move into the server. The second is cost, where compression on cross-zone traffic reduces what a multi-availability-zone cluster costs to run. The third is operator experience, where a planned node restart now comes back warm instead of rebuilding its primary index from storage. A smaller change outside those three moves every Aerospike command-line tool to signed Debian and RPM packages.
Developer experience: The expression language moves into the server
A growing share of application code is drafted by AI coding agents and reviewed by the developer who owns it, and that changes the characteristics of a good API. Agents fail at the same things developers fail at, only faster and with more confidence. An API that depends on non-obvious patterns produces plausible code that does not run. An error code with no details gives an agent nothing to correct against, so it guesses again. An infix notation expression is easier for a model to generate correctly on the first attempt, and easier for a human developer to understand during the review phase. A structured error with a clear message and a source span is something either one can act on.
Aerospike Expression Language (AEL): Write what you mean
Aerospike expressions are the equivalent of a WHERE clause, plus projection and conditional write logic. Expressions power filters on single-record, batch, and query commands, computed bins on reads and writes, Cross Datacenter Replication (XDR) filters, and secondary index definitions. Until now, the only way to author a filter expression was to write Polish-notation builder classes inside a native client, as seen below:
That works, and it will keep working. But it reads nothing like the predicate it expresses, and it carries a second cost that is easy to miss: every surface that wants to accept a textual query has had to build its own parser.
With AEL, the server accepts that predicate as text as an alternative to a compiled filter expression:
session.update(key) .bin("status").setTo("COMPLETE") .where("$.balance > 500 and $.status == 'ACTIVE'") .execute();
AEL text and builder bytecode compile to the same runtime expression. There is one parser, one evaluator, and one behavior to test and document, no matter how the expression arrived, and the per-library translators go away with it. XDR filters, connectors, tools, and frameworks send the same text the SDKs send.
$.age > 21 and $.address.city == 'NY'$.status == "gold" and $.ttl() >= 3600 and $.cart.count() > 0
AEL treats the whole record as the document. $ is the record itself, not one map bin inside it, and the path notation is influenced by JSONPath, reading much the same way: a dot descends into map keys, brackets index into lists, * iterates children, and [?(...)] filters them. Those combine in a single path:
$.orders.[0].items.*[?(@.price > 100.0)].sku
Brackets index into the orders list, a dot walks into the items map, * iterates its children, [?(...)] keeps the ones priced above 100, and a final dot projects one field from each match. Inside a filter predicate, @ refers to the element currently being iterated. The same path becomes a predicate by ending it with a terminal that returns a boolean:
$.orders.[0].items.*[?(@.price > 100.0)].exists()
AEL diverges from JSONPath where the Aerospike data model does. Aerospike maps are a superset of JSON objects, because keys can be integers or blobs as well as strings, and collections carry an order, so elements are addressable by value and by rank as well as by key and index. Where JSONPath only reads, an AEL path can modify or remove what it matches, which is what puts a filter and an update in the same request.
New Java and Python SDKs, and Rust client 3.0, now generally available
AEL is available today in the new Java SDK, the new Python SDK, and version 3.0 of the Rust client, all three of which reach general availability alongside this release. The established clients (Java, Python, Go, C#, Node.js, C) continue to author expressions with Exp.* builders and ship compiled bytecode, exactly as before. The server remains fully backwards compatible with that path, and there is no pressure to migrate.
The server picks the index
Until now, a developer had to supply an explicit secondary index to use with a query, either by naming an index outright or by attaching a predicate that matched one. Application code therefore had to know the cluster's index topology, and it broke when that topology changed: a query against a dropped index failed, and so did one against an index that was still building.
In Database 8.2.0, you send the query filter expression as one line of text instead of a tree of builder objects, and the server decides which index to use and how to run the query. Query execution splits into two phases. The client asks a cluster node for a plan, then launches the query with the selected index against every node. Given $.age > 21 and $.address.city == 'NY', the query optimizer considers every index that could serve the query, compares them on live statistics, and chooses whichever is most selective. Paginated queries reuse the plan.
The practical effect is that developers and SREs stop blocking each other. An SRE can add an index and existing queries get faster with no code change and no redeploy. An SRE can drop an unused index without breaking an application that named it. Developers describe what they want, and operators manage how it is served.
String operations where the data lives
Aerospike has had server-side operation libraries for integers, lists, maps, HLLs, and blob data for years. Strings had append() and prepend(). Anything else, whether search, slice, normalize, or transform, meant reading the record, changing it on the client, and writing it back, with the same logic duplicated in every language your applications are written in.
Database 8.2.0 adds 37 string functions, available through both the operation API and the expression API. They cover what you would otherwise be doing on the client: searching, slicing, splitting, inserting, replacing (including ICU regex replace), normalizing case and Unicode, trimming and padding, and converting a bin value to a string without the caller knowing its type. Each client exposes them under idiomatic names.
Index positions count codepoints rather than bytes, so slicing a string containing emoji or accented characters does what you expect. Matching operations compare under canonical equivalence, so a precomposed é matches a decomposed e plus combining accent, and the answer does not depend on which form the caller happened to supply.
Two older paths are deprecated in favor of these: the regexCompare expression, which uses POSIX regex and is not Unicode-compliant, and top-level string append and prepend writes. Both still work and now emit a rate-limited deprecation warning.
Errors you can act on
When the server rejected a request, it returned one of 255 numeric error codes and nothing else. The detail existed, but it went into the server log, which most application developers cannot read in production. The codes are also overloaded, so ERR_PARAMETER vaguely states that something about the request was wrong.
In Database 8.2.0, a client can ask for more error details, per request. Set error_detail_verbosity and the server returns a stable numeric subcode, a human-readable message authored at the point of failure and, at the highest level, a trace locating the failing point inside an expression.
AerospikeException: Error 4 · parameter error
After, at verbosity 2:
Error 4,10: string_regex_replace: (?P<name>...) is not valid ICU regex syntax - use (?<name>...)getSubCode() → SubCode.PARAM_STRING_REGEX_INVALID (10)
The feature is off by default, and operators can cap how much detail clients are allowed to request. Subcode values are stable once published. Coverage spans the paths developers work in most, including single-record operations, the operate API, expression building and evaluation, and per-row batch errors. It reaches both the new SDKs and the established clients, and it will widen in future releases.
Where AEL shows up: Aerospike Voyager, the SDKs, and agent tooling
The same expression language works across Aerospike's tools. Aerospike Voyager has let developers query with AEL since it entered Preview in April, and it reaches general availability later this year. Build a filter in the visual Filters tab or type it in the Expression tab; either way Voyager produces the same AEL string, and that string pastes literally into a .where(...) in your application. Voyager's embedded MCP server puts Claude Code, Cursor, or any other MCP client on the same cluster, writing queries in the same language, with a read-only profile by default so exploration cannot mutate anything. Because the server now owns the parser and the error details, AEL tab-completion and in-editor query debugging are next, so a malformed expression will explain itself as you are writing it.
Rust client 3.0 also adds server-side index selection, string operations, and structured error details on top of the distributed transactions and strong consistency support it gained earlier.
Two resources back this up. aerospike/agent-skills covers getting started, application development, and data modeling. Install it into Claude Code, Cursor, Copilot, or the Gemini CLI, and your agent stops guessing at Aerospike specifics. aerospike/data-modeling-guide handles the design-time question that comes first: deriving a schema from access patterns when none exists yet, including the failure modes that relational and document habits might produce in Aerospike.
Cost of operation: Multi-AZ without the network bill setting the limits
Running distributed databases across multiple availability zones generally comes with operational costs as cloud providers bill for every byte that crosses a zone boundary, in both directions. For many Aerospike customer workloads, zone-failure tolerance is a hard requirement. By reducing a meaningful share of that traffic, Database 8.2.0 takes the network bill out of the decision about how much data to replicate and how widely.
In a multi-AZ cluster, replica writes are the largest ongoing item on that bill, and partition migrations add to it in bursts after every cluster resizing event, compressing both of those paths. Typical replica payloads shrink and nothing about the application changes: replication-compression-mode is a per-namespace dynamic setting, and the savings show up on the next bill. Update-heavy workloads can do better still. Because in most cases the receiving node already holds the previous version of the record, delta replication mode ships only the bytes that changed, which suits workloads where writes modify a small part of a larger record. On the migration side, the benefit is time as much as money, since less data on the wire means a node restart resolves faster.
How much you gain depends on how compressible your records are. Text shrinks well; high-entropy or already-compressed data will not, so it is worth measuring rather than assuming. Per-namespace statistics report what is actually being saved, and because each path is configured dynamically, you can enable one namespace, watch it, and roll back without a restart. Anything that fails to compress is sent exactly as-is.
Wire compression pays off where traffic crosses a billed zone boundary, which means multi-AZ deployments. Wire compression is an Enterprise feature, and nothing compresses until every node is on a compatible build, so it is safe to enable during a rolling upgrade.
Operator experience: Planned restarts come back warm
When Aerospike shuts down cleanly, it leaves its indexes in shared memory and reattaches to them on the next start. That is a warm restart, and it takes a fraction of the time of a cold restart, which has to scan every storage device to rebuild the primary index from scratch. The catch is that shared memory does not survive a host reboot or a pod replacement, so teams that reboot the cluster nodes on a mandated cadence, such as applying kernel security patches every two weeks, have been absorbing a full cold restart every time. On a large primary index, that can mean hours per node.
The index checkpoint moves the copy inside the database. A single checkpoint-save info command initiates the cluster node’s graceful shutdown, writes a compressed, integrity-checked copy of its shared-memory state to persistent storage, and then parks the node so an orchestrator can confirm before reaping it. The next start hydrates from that checkpoint automatically and comes up with warm-restart equivalent in a fraction of the time it takes to cold restart a node, even in a brand-new container.
Preserving the index also preserves each record's replication state, which a cold restart would otherwise lose. For strong consistency namespaces, that makes the cluster measurably more resilient during routine restarts. Index checkpoint is an Enterprise feature, gated by a --preview index-checkpoint flag.
Installing tools with a package manager
A smaller change affects automation rather than application code. Every Aerospike command-line tool is now available as an individually signed Debian and RPM package on Aerospike's public artifact repository, along with an aerospike-tools bundle package containing all of them. Configure the repository once, import the GPG key, and apt, dnf, and yum manage installs, version pinning, and upgrades the way you do for everything else on the host machine. APT covers Debian and Ubuntu; DNF and YUM cover RHEL, Rocky Linux, AlmaLinux, and Amazon Linux 2023, on both x86_64 and aarch64 (ARM).
Packages are named for what they contain, so aerospike-asadm installs asadm, asinfo and nothing else. Install only the tools you actually need on the host. Full setup instructions are in Install tools on Linux with a package manager.
The standalone tools tarball archive is deprecated and will stop being produced in Aerospike Database 9.0.0.
Try Aerospike Database 8.2.0
A developer starting a new application wants to ship something today, using familiar tools, without first becoming an expert in the database underneath. Businesses need something different from the same system: response times that stay tightly bounded as data grows, and a cost per transaction that does not climb with scale. Aerospike delivers the developer experience that makes that performance reachable for modern applications.
Consult the platform compatibility page and the minimum usable client versions table before upgrading. For full detail, read the Database 8.2.0 release notes. Download Aerospike Enterprise Edition and run it in a single-node evaluation, get started with a 60-day multi-node trial, or use Community Edition, which is free and requires no sign-up.
Try Aerospike Cloud
Break through barriers with the lightning-fast, scalable, yet affordable Aerospike distributed NoSQL database. With this fully managed DBaaS, you can go from start to scale in minutes.