Scarf tracking pixel
Blog

Aerospike Database 8.1: New expression indexes allow developers to simplify code and reduce memory overhead for data-intensive applications

Cut code complexity, reduce RAM use, and speed up queries for massive datasets in AdTech, finance, and retail.

August 13, 2025 | 3 min read
brian-porter
Brian Porter
Principal Product Manager - Database

Today, we proudly unveil expression indexes in Aerospike Database 8.1, a powerful new feature that transforms how developers and data architects manage and query petabyte-scale datasets. Traditional indexing methods index every record and force filter logic into client code. This creates complexity across the code base, increases memory usage, and harms operational costs and query speeds. Aerospike’s expression indexes reduce the RAM footprint and accelerate query performance by indexing only relevant computed data, offering businesses a smarter, faster, and more efficient way to leverage billions of records.

Here are some ways teams can put expression indexes to work:

  • AdTech platforms: Selectively index only a consistent representative cohort from the user profile stores to calculate campaign reach against

  • Financial services: Index only high-value transactions for fraud detection

  • E-commerce: Create specialized indexes for product recommendations based on computed relevance scores

Skip to the Quickstart guide to start applying expression indexes to your own workloads. Otherwise, let’s dig into a concrete example of how this feature delivers value.

Simplify application logic

Expression indexes let you push conditional logic into the index itself. That means no more duplicating filter logic across clients or writing extra fields (we call them “bins”) just to index derived values.

Let’s look at an example that segments customers into loyalty tiers (Gold, Silver, Bronze) based on their spend and number of years.

Before: Forced to write computed values into records manually

// Step 1: Compute the loyalty tier
int spend = record.getInt("spend");
int years = record.getInt("years");
String tier = (spend * years > 10000) ? "gold" :
              (spend * years > 5000)  ? "silver" :
              (spend * years > 0) ? "bronze" : "free";

// Step 2: Write the computed tier into the record
client.put(null, key, new Bin("tier", tier));

// Step 3 (one-time setup): Create a secondary index on the 'tier' bin
asadm -e "enable; manage sindex create string tier_idx ns test set customers bin tier"

After: Embed logic directly in the index

// No need to compute the tier app-side and store it in a bin

// Step 1 (one-time setup): Create a base64 encoding of your expression
Expression tierExpr = Exp.build(Exp.cond(
    Exp.gt(Exp.mul(Exp.intBin("spend"), Exp.intBin("years")), Exp.val(10000)), Exp.val("gold"),
    Exp.gt(Exp.mul(Exp.intBin("spend"), Exp.intBin("years")), Exp.val(5000)), Exp.val("silver"),
    Exp.gt(Exp.mul(Exp.intBin("spend"), Exp.intBin("years")), Exp.val(0)), Exp.val("bronze"),
    Exp.unknown() // skip records with zero total spend
));
System.out.println(tierExpr.getBase64());

// Step 2 (one-time setup): Create the expression index using the base64 encoding
asadm -e "enable; manage sindex create string loyalty_tier_idx ns test set customers exp_base64 <base64-encoded-expression>"

Benefits:

  • No need to write or store computed bins

  • Logic is centralized and consistent

  • Index includes only relevant, matching records

  • We are able to skip indexing customers in the free tier

Improved performance and total cost of ownership

Expression indexes let you define which records get indexed using expressions. The result is a leaner index structure: the in-memory footprint shrinks in proportion to the records you exclude, producing smaller indexes and faster queries. Less RAM also means less cost.

Let’s look at our example again. Let’s assume that only 60% of the data has total_spend information used to calculate the loyalty tiers.

# Records
[
  { "user_id": "001", "spend": 12000, "years": 2 },
  { "user_id": "002", "spend": 3500, "years": 2 },
  { "user_id": "003", "spend": 0, "years": 2 },
  { "user_id": "004", "spend": 3000, "years": 1 },
  { "user_id": "005", "spend": 0, "years": 4 }
]

# Records by tier 
[
  { "user_id": "001", "tier": "gold" },
  { "user_id": "002", "tier": "silver" },
  { "user_id": "003", "tier": "free" },
  { "user_id": "004", "tier": "bronze" },
  { "user_id": "005", "tier": "free" }
]

Index entries:

  • "gold" → [001]

  • "silver" → [002]

  • "bronze" → [004]

“free” → [003, 005] (40% wasted index space!)

That means less memory consumed, fewer records to scan, and faster queries. This is without writing a single extra bin or maintaining logic across multiple clients. As memory reliance is dropped, so too will infrastructure costs.

Getting started with expression indexes

Just update to Server 8.1.0 and the latest version of your preferred client. Go to the Quickstart for step-by-step instructions on how to get started. Curious about the other improvements offered with 8.1.0? View the full list in the release notes.

Champions of Scale nominations

Recognize the engineers and teams building internet-scale data infrastructure, the kind that drives unstoppable growth and flawless customer experiences without breaking the bank!