Skip to content

Configure wire compression

For the complete documentation index see: llms.txt

All documentation pages available in markdown.

This page describes how to enable wire compression for replica writes and partition migrations in Aerospike Database Enterprise Edition 8.2.0 and later.

Applies to: Aerospike Database Enterprise Edition 8.2.0 and later.

Audience: Cluster operators and SREs who manage replication bandwidth, migration traffic, or cross-Availability Zone (AZ) network cost.

Outcome: You enable and tune wire compression for replica writes and partition migrations, then confirm bandwidth savings with namespace statistics.

Prerequisites

  • Aerospike Database Enterprise Edition 8.2.0 or later on every node that participates in replication for the namespace. Wire compression requires Enterprise Edition. It is not gated by a feature key entry.
  • Write access to namespace configuration (aerospike.conf, asadm, or asinfo).
  • Familiarity with namespace replication and rack awareness for multi-AZ deployments.

Overview

Wire compression applies Zstd to replica writes and partition migrations on the fabric link between cluster nodes. Replica-write and migration settings are per namespace.

Wire compression is a cost trade, not a performance feature. It spends CPU on the sending and receiving nodes, and can reduce peak write throughput, in exchange for fewer bytes on the fabric. That trade only pays where those bytes are billed, such as a rack awareness deployment whose replicas cross AZ boundaries where cloud providers charge for transfer in both directions. In a single-AZ cluster the fabric traffic is free, so compressing it buys nothing for the CPU it costs.

The same namespace replication-compression-mode settings also apply to read-touch replica traffic (TTL-extension writes that replicate to replicas).

Storage compression vs wire compression

Storage compression compresses records on disk or in memory/PMem storage. Wire compression compresses payloads on the fabric link between nodes. The two features are independent:

TrafficScopeMode settingLevel setting
Storage compressionOn-disk (or in-memory storage) record formatcompressioncompression-level
Replica writesPer namespacereplication-compression-modereplication-compression-level
Partition migrationsPer namespacemigrate-compression-modemigrate-compression-level

A record already compressed at the storage layer crosses the fabric in its stored, compressed form. Wire compression does not run on it a second time, so its bytes never contribute to the wire compression bytes_saved metrics. Those bytes are already being saved by storage compression. The more of a namespace’s records are stored compressed, the less wire compression has left to save.

This decision is made per record, not per namespace. A record is stored compressed only when compressing it actually made it smaller, so a namespace with storage compression enabled always holds some records stored plain, and those are still compressed on the wire. A namespace that enabled storage compression recently holds many of them: records written before then stay stored plain until they are next written.

Service-wide SMD full-sync wire compression uses separate smd-compression-mode parameters in the service context. See Configure SMD wire compression.

When to use wire compression

Wire compression helps when:

  • Replicas cross AZ boundaries and network egress is a significant cost (common on cloud infrastructure deployments).
  • Write volume or record size drives high steady-state replication bandwidth.
  • Partition migrations after topology changes generate large, bursty network traffic.
  • Records are large but updates change only a small portion of each record (delta-zstd mode).

Wire compression is applied on a per-record basis. Each replica write pays for compressing the record on the partition master and decompressing it on the replica. The master-side compression is on the client’s write path at any commit level, because it happens as part of the write itself. At write commit level all, the replica’s decompression is on that path too, because the client is not answered until the replica acknowledges. The exposure is larger there, and write latency can increase.

Because every replicated record pays this cost, the cumulative effect can be lower overall write throughput. Measure it on your own workload rather than assuming a fixed cost. The impact varies with the compute environment, record size, and load.

On a namespace where storage compression is already working, most records are skipped on the wire. The ones that are not skipped are the ones storage compression could not shrink, so you pay the compressor’s full cost on them for little return. Expect repl_wire_compression_not_beneficial to climb rather than bytes_saved.

On a namespace that uses multi-record transactions, each record in a committed transaction is replicated twice, once when the transaction writes it, and again when the transaction commits. Only the first is compressed on the wire. Expect roughly half the saving the same records would give outside a transaction, and judge a pilot on such a namespace accordingly.

How much bandwidth wire compression saves is entirely dependent on your data, so do not assume a particular reduction in replication traffic or network cost before measuring it. With zstd, savings depend on record size and on how compressible the record contents are. With delta-zstd, savings depend on how many bytes each update changes relative to the size of the whole record. If your updates change a known, consistent amount of data, you can estimate the saving up front. If update sizes vary widely, the only reliable guide is observing repl_wire_compression_bytes_saved against fabric_rw_bytes_sent over time. In either case, make the decision empirically, per namespace, using the Evaluate wire compression procedure.

See Evaluate wire compression before enabling the feature on additional namespaces.

Choose a compression mode

Use the following tables to pick replication-compression-mode and migrate-compression-mode values for each namespace.

Replica writes

ModeWhat it sendsEnable whenSkip when
noneThe whole record, uncompressed. The default.——
zstdEach replica write compressed on its own.Replica payloads are large enough to compress and are compressible (JSON, text, repeated structure). Works under any effective write commit level, on creates as well as updates, and needs nothing from the replica.Records are already compressed at the storage layer, records are small, data is high-entropy or pre-compressed, or replication does not cross a billed boundary.
delta-zstdOnly the bytes that changed since the replica’s copy of the record.Records are large and only partly updated. A few fields changing in a multi-KB record can ship as tens of bytes, well below compressing the whole record. The replica reliably holds the prior version.Single-record client writes commit at write commit level master and the namespace has little batch, background-job, read-touch, or XDR-received write traffic. Delta patches are disabled for those writes, though plain Zstd still applies. The workload is create-heavy or write-once. Replica read I/O is already the bottleneck.

Partition migrations

SettingEnable whenSkip when
migrate-compression-mode = zstdRecovery windows after node events are long or costly, or migration bandwidth is the binding constraint. Worth enabling even when replication compression is off.Migrations are rare and small, or CPU headroom during migration is already tight.

Compression modes for replica writes

Plain zstd

The partition master compresses each replicated record independently when the record is at least 256 bytes. Smaller records are sent uncompressed, because compressing them does not reliably save anything. replication-compression-level sets the compression strength.

This 256-byte floor applies to plain zstd on both replica writes and partition migrations. Delta patches are sent regardless of record size.

delta-zstd

The partition master sends only the difference between the new record and the version it held before the write. The wire payload is a patch, often much smaller than a full Zstd-compressed record.

The replica must already hold that same base version, identified by matching generation and last update time. If the base version does not match, the replica signals a version mismatch, the partition master drops the delta, and retransmits the full record as an uncompressed plain replica write. This fallback is transparent to clients.

To rebuild the record, the replica loads its copy of the prior version.

Delta patches are disabled for direct single-record client writes whose effective write commit level is master. Batch writes, background UDF and background operations jobs, read-touch TTL extensions, writes a client sent to a non-master node that were forwarded to the master, and writes received from another cluster by XDR still build deltas regardless of commit level.

The namespace write-commit-level-override fixes commit level at the namespace. When the override is off, the client write policy supplies the commit level for the single-record writes it governs. Namespaces with strong consistency use write-commit-level all, so delta-zstd applies normally.

See Tuning signals for when to switch from delta-zstd to zstd.

Configure wire compression

Replica writes and partition migrations have separate compression controls. Both require Aerospike Database Enterprise Edition and support dynamic configuration.

TrafficMode settingLevel settingMode valuesDefault modeDefault level
Replica writesreplication-compression-modereplication-compression-levelnone, zstd, delta-zstdnone1
Partition migrationsmigrate-compression-modemigrate-compression-levelnone, zstdnone1

Level parameters accept -10 through 22 for both traffic types. See Compression levels. A higher migrate-compression-level is more defensible than a higher replication-compression-level: migration is bulk transfer, while replication sits in the synchronous write path, so every client write waits on the replication level you choose.

Configure the same namespace-level mode and level on every node for a given namespace.

A node fails to start if aerospike.conf contains an invalid mode or level. A dynamic set-config with an invalid value fails and leaves the current setting in place.

Compression levels

replication-compression-level and migrate-compression-level set the Zstd compression level. Level behavior is the same for both parameters.

LevelBehavior
Negative (-10 through -1)Zstd fast compression: faster encoding, lower compression ratio. More negative values increase speed at the cost of ratio.
0Selects Zstd’s own default level, which is 3, not the Aerospike default of 1.
Positive (1 through 22)Standard Zstd compression levels range from higher speed at lower values to higher compression ratios at higher values.
Default 1Low positive level that favors speed over maximum compression.

Setting a level of 1 favors speed over compression ratio in the synchronous write path. In contrast, setting the level to 0 enables Zstd’s internal default level of 3 rather than disabling compression or using the Aerospike default, causing the node to compress harder and more slowly. Always set the level explicitly to 1 rather than leaving it at 0.

replication-compression-level applies when replication-compression-mode is zstd or delta-zstd. migrate-compression-level applies when migrate-compression-mode is zstd. These level parameters are separate from storage compression-level and from the Aerospike Backup Service (ABS) compression.level setting.

Storage compression-level and XDR compression-level accept only positive values 1 through 9. Wire compression level parameters also accept negative values, which trade compression ratio for speed. For background, see the Zstd manual.

Dynamic changes take effect immediately and last until the node restarts. Add matching directives to aerospike.conf to keep the settings across restarts.

Configure replica writes

Use the Choose a compression mode and Compression modes for replica writes sections to pick none, zstd, or delta-zstd.

Static configuration

Add the directives to the namespace context in aerospike.conf:

aerospike.conf
namespace test {
replication-factor 2
# ... other namespace settings ...
replication-compression-mode zstd
replication-compression-level 1
}

For partial-update-heavy workloads after piloting plain zstd, set replication-compression-mode to delta-zstd:

aerospike.conf
namespace test {
replication-factor 2
# ... other namespace settings ...
replication-compression-mode delta-zstd
replication-compression-level 1
}

Dynamic configuration

Terminal window
asadm -e 'enable; manage config namespace test param replication-compression-mode to zstd'
asadm -e 'enable; manage config namespace test param replication-compression-level to 1'

Equivalent asinfo form:

Terminal window
asinfo -v 'set-config:context=namespace;namespace=test;replication-compression-mode=zstd'
asinfo -v 'set-config:context=namespace;namespace=test;replication-compression-level=1'

Configure partition migrations

migrate-compression-mode controls wire compression for partition migrations, and takes its own mode and level independently of replica writes. Migration supports plain zstd, because the sending and receiving nodes share no base record version to build a delta against.

Migration compression runs when migrate-compression-mode is zstd and both nodes on the migration link run a build that supports wire compression. Records too small to benefit are sent uncompressed. If the compressor fails on a record, the server sends that record’s bytes uncompressed and increments migrate_wire_compression_fallbacks on the sending node only. That counter means the sender’s codec failed (for example under memory pressure), not that a peer refused the message. If the compressed payload is no smaller than the original, the server sends the original and increments migrate_wire_compression_not_beneficial.

If the receiving node cannot decompress a migration record, the server logs handle insert: failed to decompress record on that node and drops the message so migration can retry. No migration wire-compression counter increments for receive-side decompress failures. Stalled migrations with flat migrate_wire_compression_fallbacks may still show this warning on receivers.

Static configuration

aerospike.conf
namespace test {
replication-factor 2
# ... other namespace settings ...
migrate-compression-mode zstd
migrate-compression-level 1
}

Dynamic configuration

Terminal window
asadm -e 'enable; manage config namespace test param migrate-compression-mode to zstd'
asadm -e 'enable; manage config namespace test param migrate-compression-level to 1'

Equivalent asinfo form:

Terminal window
asinfo -v 'set-config:context=namespace;namespace=test;migrate-compression-mode=zstd'
asinfo -v 'set-config:context=namespace;namespace=test;migrate-compression-level=1'

Disable wire compression

Set the relevant mode parameter back to none. Wire compression affects only the payload format on the fabric link, so disabling it needs no data conversion: records already on storage keep whatever storage compression format they were written in, and no migration or restart is required.

To move off delta-zstd while keeping bandwidth savings, set replication-compression-mode to zstd instead of none.

  1. Set the mode to none on every node in the cluster. A node stops compressing the traffic it sends as soon as the change applies, and continues to accept and decompress inbound compressed messages from peers that remain enabled.

    Terminal window
    asadm -e 'enable; manage config namespace test param replication-compression-mode to none'
    asadm -e 'enable; manage config namespace test param migrate-compression-mode to none'
  2. Remove the matching directives from aerospike.conf on every node, or set them to none there. A dynamic change does not persist, so a node that restarts with the old directives in place re-enables compression.

  3. Confirm the modes, then confirm the savings counters have stopped moving. The modes are configuration and the savings are statistics, so they take two commands.

    Terminal window
    asadm -e 'show config namespace for test like replication-compression migrate-compression'
    asadm -e 'show statistics namespace for test like wire_compression'

    Pass: every node reports replication-compression-mode=none and migrate-compression-mode=none, and repl_wire_compression_bytes_saved is unchanged between two readings taken minutes apart under write traffic. The savings counters are lifetime totals and do not reset to zero when you disable the feature, so compare two readings rather than looking for zeros.

Rolling upgrades

Mixed-version clusters operate correctly during a rolling upgrade. How compression activates depends on the traffic path:

  • Replica writes use a cluster-wide compatibility check. Until every node runs a build that includes wire compression, replication traffic stays uncompressed even between two upgraded nodes.
  • Partition migrations negotiate compression per peer. Compression starts on a link as soon as both of its nodes run a build that supports wire compression and migrate-compression-mode is zstd. This is the only transport that compresses anything during a mixed-version rollout.
  • SMD full sync uses the same cluster-wide check as replica writes, so it also stays uncompressed until the last node upgrades.

Leave replication-compression-mode at none until the rollout completes. A node with the mode set during a mixed-version rollout still compresses every replica write and then sends the record uncompressed, because the cluster-wide check has not opened yet: you pay the CPU and get no bandwidth back, during the window when the cluster is also carrying migration load. delta-zstd costs the most in this state, because the master also builds a patch that is discarded.

Migration compression is the exception. It negotiates per link, so you can set migrate-compression-mode as the rollout proceeds and it starts working on links between upgraded peers.

Whichever you enable, use dynamic configuration (asadm or asinfo) first. Add static directives to aerospike.conf only after every node runs Aerospike Database Enterprise Edition 8.2.0 or later. An earlier build does not recognize the wire compression parameters, and a node that reads them from its configuration file fails to start with unknown config parameter name.

Monitor and tune

Use namespace statistics to confirm savings and choose between zstd and delta-zstd.

Evaluate wire compression

Pilot wire compression on one namespace that has representative write traffic. Wire compression applies per namespace, so you can evaluate it on one namespace before you enable it on others.

  1. Choose a pilot namespace with production-like record sizes, update patterns, and cross-node replication traffic.

  2. Record a baseline with replication-compression-mode set to none.

    • Record client write latency. Save this baseline to compare against step 5.
    • Mark the uncompressed boundary. Record the current fabric_rw_bytes_sent value to identify where uncompressed traffic ends.

    Do not use this baseline fabric_rw_bytes_sent reading to calculate the compression savings ratio. That ratio requires two separate readings taken after compression is enabled.

    Terminal window
    asadm -e 'show statistics namespace for test like repl_wire_compression'
    asadm -e 'show statistics service like fabric_rw_bytes_sent'

    Wire compression counters are namespace statistics. fabric_rw_bytes_sent is a node statistic covering every namespace on the node, so it comes from show statistics service (or asinfo -v 'statistics') rather than the namespace command.

  3. Enable plain zstd on the pilot namespace using replica-write dynamic configuration. Start with replication-compression-level at 1.

  4. Run representative write traffic on the namespace for long enough to populate wire compression metrics.

  5. Compare results against your baseline:

    • repl_wire_compression_bytes_saved increases if records compress on the wire.
    • For a savings ratio, see Estimate the savings ratio.
    • repl_wire_compression_delta_attempts stays at 0 throughout this step. Plain zstd never builds delta patches, so a flat attempts counter here tells you nothing about your workload. Evaluate it in step 6, after the namespace is in delta-zstd.
    • Client write latency and node CPU must stay within your service limits. See Tuning signals if latency rises.
  6. Evaluate delta compression suitability. Recommended when records are large and updates touch only small portions of data.

    Note: Skip this entire step if the effective write commit level is master and the namespace workload consists almost exclusively of single-record client writes.

    Switch the pilot namespace to delta-zstd and assess whether delta compression provides a net benefit over standard Zstd.

    • Wait until migrate_tx_partitions_remaining and migrate_rx_partitions_remaining both reach 0 for the namespace before evaluating counters.
    • Compare repl_wire_compression_delta_hit_pct, repl_wire_compression_fallbacks, and the repl_wire_compression_delta_reject_* metrics.

    A low hit rate combined with high fallbacks or version rejections indicates that standard Zstd is a better fit.

    If repl_wire_compression_delta_attempts does not scale with write volume after switching, check the following:

    • write-commit-level-override and client write policies.
    • Whether the effective commit level is master (single-record client writes disable deltas under master, though standard Zstd still shows repl_wire_compression_bytes_saved growth).

    Batch, background-job, read-touch, and XDR-received writes still generate deltas under master.

  7. Adjust replication-compression-level or change mode based on Tuning signals.

    • Apply the validated replication settings to remaining target namespaces.
    • Enable migration compression separately if that traffic path is relevant to your rollout.
    • Save the validated settings in aerospike.conf across cluster nodes only after the rollout is complete.

    Then follow the Rolling upgrades procedure to apply configuration changes across the cluster safely without downtime.

Namespace metrics

Query namespace statistics with asadm or asinfo. The wire_compression pattern matches replication and migration metrics:

Terminal window
asadm -e 'show statistics namespace for test like wire_compression'

Wire compression metrics were introduced in Database 8.2.0. For metric descriptions, see the Metrics reference. The Tuning signals section explains how to interpret them for your workload.

Estimate the savings ratio

repl_wire_compression_bytes_saved and migrate_wire_compression_bytes_saved are cumulative byte counts, not ratios, and so are the fabric counters you pair them with. To turn one into a percentage, pair it with the fabric channel it rides on:

TrafficSaved bytesChannel counter
Replica writesrepl_wire_compression_bytes_savedfabric_rw_bytes_sent
Partition migrationsmigrate_wire_compression_bytes_savedfabric_bulk_bytes_sent

Take two readings a fixed interval apart, both after enablement and both under normal load, and divide the differences:

saving_pct = Δbytes_saved / (Δchannel_bytes_sent + Δbytes_saved) * 100

Three things to get right before you trust the number:

  • Use differences, not totals. The fabric counters run from node start, so they include every byte the node sent before you enabled wire compression, including the whole baseline period from step 2 of Evaluate wire compression, when the mode was still none. Dividing one lifetime total by another therefore reports far less saving than the namespace is actually getting, and reports less the longer the node has been up.
  • The saved-bytes counters are per namespace and the fabric counters are per node. Sum the namespace counter across every namespace on the node before dividing, or the result understates the saving.
  • The result is a floor, not an exact figure. The numerator counts record payload only, while the fabric counter includes per-message headers and every other message on the same channel. The real percentage is somewhat higher.
  • On a namespace that uses multi-record transactions, the commit traffic rides the same fabric channel but is never compressed, so it enlarges the divisor without enlarging the numerator. The ratio understates the saving on those namespaces by more than the amount described above.
  • On a strong-consistency namespace, the catch-up traffic that follows a node returning to the cluster is not compressed on the wire. While it runs the divisor grows and the numerator does not, so the ratio dips. That is recovery traffic, not a compression regression, so wait for migrations to finish before rereading the ratio. Namespaces with a replication-factor above 2 produce more of it.

Profiling wire compression CPU

For short-term diagnostics, enable service-wide codec profiling with enable-benchmarks-wire-compression. The parameter is false by default. When enabled, the server records CPU time for each of the four codec operations: patch generation on the sending node and patch application on the replica, both in delta-zstd mode, plus compression and decompression.

Static configuration

aerospike.conf
service {
# ... other service settings ...
enable-benchmarks-wire-compression true
}

Dynamic configuration

Terminal window
asadm -e 'enable; manage config service param enable-benchmarks-wire-compression to true'

Equivalent asinfo form:

Terminal window
asinfo -v 'set-config:context=service;enable-benchmarks-wire-compression=true'

Query profiling output with asinfo:

Terminal window
asinfo -v 'zstd-wire-stats'

The statistics info command always includes wire_comp_cpu_pct and its four per-operation breakouts, wire_comp_make_patch_cpu_pct, wire_comp_apply_patch_cpu_pct, wire_comp_compress_cpu_pct, and wire_comp_decompress_cpu_pct. Each is a gauge: a rolling ten-second average rather than a cumulative total, so graph it directly rather than as a rate. They read 0.00 while profiling is disabled.

These counters are scaled out of (number of CPUs × 100)%, not out of 100%. On a 16-core node the range is 0.00 to 1600.00, and 100.00 means the codec is using one CPU’s worth of time. Compare the value against process_cpu_pct, which uses the same scale, to see the codec’s share of the process. If that share grows faster than repl_wire_compression_bytes_saved, the compression level is too high for this workload.

The four histograms behind these counters are written to the server log only. See Wire compression CPU analysis for what each one measures and how to read it.

Disable profiling after you finish tuning. The extra per-operation timing adds overhead on the replication path.

Tuning signals

Wire compression skips certain payloads entirely:

  • Plain zstd on replica writes and migrations skips payloads too small to benefit. Delta patches are sent regardless of record size.
  • Durable-delete tombstones and records already compressed at the storage layer are not wire-compressed, and neither increments any counter. On a delete-heavy namespace, check the namespace tombstones statistic before concluding compression is misconfigured.
  • When compression produces a payload no smaller than the plain record, the server sends uncompressed bytes and increments repl_wire_compression_not_beneficial, or repl_wire_compression_delta_not_beneficial when the patch is the payload that did not shrink.

The sender counts a fallback. The replica counts the reason. repl_wire_compression_fallbacks increments on the node that sent the replica write, and all four repl_wire_compression_delta_reject_* counters increment on the node that refused it. Read them across the whole cluster rather than against a single node. asadm -e 'show statistics namespace for test like wire_compression' reports every node in one table.

Interpret repl_wire_compression_delta_reject_* counters as follows:

CounterMeaning
repl_wire_compression_delta_reject_no_recordReplica does not hold the base record the patch was built against
repl_wire_compression_delta_reject_versionReplica holds the record but not the matching generation or last-update-time version
repl_wire_compression_delta_reject_applyReplica held the matching base version but could not rebuild the record from the patch
repl_wire_compression_delta_reject_otherReplica could not use its stored copy of the base record: it could not be read, it is stored compressed, or it did not pass validation

Additional signals:

  • Low repl_wire_compression_delta_hit_pct with high repl_wire_compression_fallbacks: switch from delta-zstd to zstd.

  • repl_wire_compression_delta_attempts not increasing while writes continue on a delta-zstd namespace: deltas have stopped being attempted, usually because the effective write commit level for single-record client writes became master through a client write policy change. Batch, background-job, read-touch and XDR-received writes are unaffected by commit level, so a namespace carrying those still shows attempts. repl_wire_compression_delta_hit_pct is a lifetime ratio and holds its last value in this state, so it does not fall. Alert on the attempt rate, not on the percentage.

  • High repl_wire_compression_delta_reject_version or repl_wire_compression_delta_reject_no_record: replicas do not hold the version the master built the patch against. Check that the namespace has finished migrating before acting on this. Both migrate_tx_partitions_remaining and migrate_rx_partitions_remaining read 0 on every node:

    Terminal window
    asadm -e 'show statistics namespace for test like partitions_remaining'

    While partitions are still migrating, after a rolling upgrade, a node restart, or any other topology change, replicas routinely hold an older copy of a record or none at all, so both counters rise for that reason alone, along with repl_wire_compression_fallbacks. They settle once migrations finish. Only when they stay high on a cluster with no migrations outstanding is the workload itself a poor fit, and zstd the better choice.

  • Rising repl_wire_compression_delta_apply_device_reads: delta apply loads the prior record version on the replica. The counter increments once per delta apply on namespaces using storage-engine device or storage-engine pmem, before the load runs and without checking whether the load hits cache or storage. It stays at zero on storage-engine memory. With cache-replica-writes enabled, some loads are served from the post-write cache, so the counter can exceed physical device reads.

    What to do about it depends on the storage engine. On a namespace using storage-engine device, read the counter alongside cache_read_pct for a sense of how much of the namespace’s read traffic is reaching the drive at all. That figure is a short-interval percentage covering every read the namespace serves, not a delta-apply hit rate, so treat it as a trend rather than a measurement. If it is low and write latency is rising, either raise post-write-cache so more recently written records are served from memory, or switch to zstd, which needs no base version on the replica. For rack awareness deployments that span multiple Availability Zones, cache-replica-writes on storage-engine device allows replica writes into the post-write cache, which can improve latency and reduce read I/O.

    On a namespace using storage-engine pmem, the counter still increments on every delta apply when the prior record is loaded from PMem. cache_read_pct is not reported for that engine. Neither post-write-cache nor cache-replica-writes is valid in a storage-engine pmem stanza: the node fails to start if either directive is present. Treat the counter as a count of delta-apply loads, and use zstd if the replica-side cost is the problem.

  • Rising write latency after enablement: try a more negative replication-compression-level (fast compression), a lower positive level such as 1, or plain zstd instead of delta-zstd. To back the feature out entirely, see Disable wire compression.

  • High migrate_wire_compression_not_beneficial with low migrate_wire_compression_bytes_saved: migration records may already be incompressible. Wire compression may not help that namespace during migrations.

Verify

  1. Confirm every node reports the expected mode. Use asadm, which reports all nodes in one table. A single asinfo call answers for one node only, and a namespace set on some nodes and not others does not error.

    Terminal window
    asadm -e 'show config namespace for test like replication-compression migrate-compression'

    For a namespace using plain Zstd on replica writes, each node reports:

    migrate-compression-level |1
    migrate-compression-mode |none
    replication-compression-level|1
    replication-compression-mode |zstd

    Pass: every node shows the same values, and they are the ones you configured. A node showing a different mode is still sending uncompressed replica writes for the partitions it masters. To read a single node, for example to isolate one that disagrees, run the following command, where NODE is the IP address or hostname of that node:

    Terminal window
    asinfo -h NODE -v 'get-config:context=namespace;namespace=test' | tr ';' '\n' | grep -E 'replication-compression|migrate-compression'
  2. Run representative write traffic, then confirm the savings counters move.

    Terminal window
    asadm -e 'show statistics namespace for test like wire_compression'

    repl_wire_compression_bytes_saved increases. That is the criterion that confirms compressed bytes actually reached the replica. In delta-zstd mode, repl_wire_compression_delta_attempts also increases with the write rate and repl_wire_compression_delta_hit_pct is acceptable for your workload, but those two move on the sending node whether or not anything compressed went on the wire, so treat them as workload signals rather than proof. Attempts flat while writes continue means deltas have stopped. See Tuning signals.

  3. If you enabled migrate-compression-mode, verify it separately. Write traffic does not exercise it, because migration compression runs only while partitions are actually moving, on the node sending them. Confirm it during the next planned node restart or rolling maintenance rather than forcing a topology change on a production cluster.

    Terminal window
    asadm -e 'show statistics namespace for test like migrate_wire_compression'

    Pass: migrate_wire_compression_bytes_saved increases while migrations are in progress. All three migration counters at zero with no migrations running means nothing was migrated, not that the setting failed, so check the mode with show config instead.

  4. If the cluster is mid-upgrade, expect replication bytes_saved to stay flat until the rollout completes, and migration bytes_saved to move earlier on links between compatible peers. See Rolling upgrades.

Troubleshoot

SymptomLikely causeAction
No bytes_saved despite enabled modeStorage-compressed records, records too small for plain Zstd to compress, tombstones, mixed-version cluster, or mode still noneCheck repl_wire_compression_not_beneficial, and repl_wire_compression_delta_not_beneficial in delta-zstd. If either climbs, records are reaching the compressor and not shrinking. If both stay at zero, confirm replication-compression-mode, migrate-compression-mode, that the rollout is complete, and storage compression, then check record sizes: payloads too small to compress are skipped without incrementing any counter
delta_attempts flat while writes continue, delta_hit_pct unchanged (delta-zstd)Effective write commit level for single-record client writes became master: a client write policy change, a new service writing with commit level master, or the namespace override set to master. Batch, background-job, read-touch and XDR-received writes are unaffected, so attempts stopping entirely means the namespace carries little of that traffic. delta_hit_pct is cumulative and cannot fall when attempts stopCheck client write policies and write-commit-level-override. Plain Zstd still applies, so bytes_saved keeps climbing
High repl_wire_compression_fallbacksA replica refused a compressed or delta payload and the sender retransmitted the full recordIn delta-zstd, check all four repl_wire_compression_delta_reject_* counters on the receiving nodes. If version or no-record rejections dominate, confirm migrate_tx_partitions_remaining and migrate_rx_partitions_remaining are 0 for the namespace first, because migrating partitions raise both rejection counters for a reason that clears itself. Switch the namespace to zstd only if they stay high with no migrations outstanding. In plain zstd the fallback is a decode failure on the replica and increments no rejection counter: check the replica’s server log and its health instead
High migrate_wire_compression_not_beneficialMigration records do not compress smaller than their original sizeExpect limited migration savings for this namespace. The counter covers only records the compressor attempted, so record size is not the cause. Set migrate-compression-mode back to none to stop paying the compression cost for no gain
Rising migrate_wire_compression_fallbacksCompressor failed on the sending node while migrating a record (often memory pressure)Check the sender’s server log around migration time. Lower migrate-compression-level, relieve memory pressure, or set migrate-compression-mode to none. This counter does not rise when a peer refuses a message
Migrations stall or lag with migration compression enabled, flat migrate_wire_compression_fallbacksReceiver failed to decompress a compressed migration recordOn receiving nodes, search the server log for handle insert: failed to decompress record. No namespace counter increments. Fix codec or memory issues on the receiver, or set migrate-compression-mode to none while investigating
Increased write latencyCompression level too aggressive, or delta apply loading base records on the replicaLower replication-compression-level or use a negative level. Check repl_wire_compression_delta_apply_device_reads together with cache_read_pct on storage-engine device: the counter increments before each prior-record load and may include cache-served loads when cache-replica-writes is enabled. Switching to zstd removes the delta-apply load entirely, because it needs no base version on the replica
Dynamic configuration appears ignoredInvalid value, or the parameter sent to the wrong context or namespaceset-config rejects these rather than ignoring them. Re-run the command and read its response, which reports an invalid set-config parameter on failure. The server log records an enterprise-only rejection, but not an invalid value
Node fails to start after adding directivesCommunity Edition, or a Database version earlier than 8.2.0, which does not recognize the parameter namesRemove wire-compression directives from aerospike.conf, or complete the upgrade described in Prerequisites before adding static directives

Next steps