Pruner Service Settings Reference
Overview
This document provides comprehensive reference for all Pruner service configuration settings in Teranode.
Service Control Settings
startPruner
Type: Boolean
Default: true
Description: Enable or disable the Pruner service
Context-Specific Values:
# Global default
startPruner = true
# Disable for specific nodes in multi-node docker setup
startPruner.docker.host.teranode1.coinbase = false
startPruner.docker.host.teranode2.coinbase = false
startPruner.docker.host.teranode3.coinbase = false
# Development
startPruner.dev = true
# Operator/Kubernetes
startPruner.operator = true
Impact:
true: Pruner service starts and performs UTXO pruningfalse: Pruner service disabled, UTXO database will grow unbounded
When to Disable:
- Testing scenarios requiring full UTXO history
- Debugging transaction issues
- Temporary workaround for pruning errors
Warning: Disabling pruning will cause the UTXO database to grow continuously. Only disable temporarily.
Network Settings
pruner_grpcPort
Type: Integer
Default: 8096
Description: gRPC server port for Pruner service
Example:
PRUNER_GRPC_PORT = 8096
Port Conflicts:
If port 8096 is already in use, change to an available port:
PRUNER_GRPC_PORT = 8097
pruner_grpcAddress = localhost:8097
pruner_grpcListenAddress = :8097
pruner_grpcAddress
Type: String
Default: localhost:8096
Description: gRPC client address for connecting to Pruner service
Context-Specific Values:
# Development (default)
pruner_grpcAddress = localhost:${PRUNER_GRPC_PORT}
# Docker multi-node (single machine)
pruner_grpcAddress.docker.m = pruner:${PRUNER_GRPC_PORT}
# Docker (per-service containers)
pruner_grpcAddress.docker = ${clientName}:${PRUNER_GRPC_PORT}
# Docker host access
pruner_grpcAddress.docker.host = localhost:${PORT_PREFIX}${PRUNER_GRPC_PORT}
# Kubernetes/Operator
pruner_grpcAddress.operator = k8s:///pruner.${clientName}.svc.cluster.local:${PRUNER_GRPC_PORT}
Usage: Other services use this address to connect to Pruner's gRPC API
pruner_grpcListenAddress
Type: String
Default: :8096
Description: gRPC server listen address (bind address)
Context-Specific Values:
# Default (all interfaces)
pruner_grpcListenAddress = :${PRUNER_GRPC_PORT}
# Development (localhost only)
pruner_grpcListenAddress.dev = localhost:${PRUNER_GRPC_PORT}
# Docker host (localhost with port prefix)
pruner_grpcListenAddress.docker.host = localhost:${PORT_PREFIX}${PRUNER_GRPC_PORT}
Bind Addresses:
:8096- Listen on all interfaceslocalhost:8096- Listen only on localhost (more secure)0.0.0.0:8096- Explicitly listen on all IPv4 interfaces
Behavior Control Settings
pruner_skipDuringCatchup
Type: Boolean
Default: false
Environment Variable: pruner_skipDuringCatchup
Description: Skip pruning during blockchain catchup
When enabled, the pruner checks FSM state and skips all deletion operations during catchup. This prevents race conditions where block validation marks transactions as mined faster than the pruner can preserve their parents.
Values:
false(default): Normal pruning during catchup (safe with retention >= 288 blocks)true: Skip all pruning during catchup state
pruner_blockAssemblyWaitTimeout
Type: Duration
Default: 10m
Environment Variable: pruner_blockAssemblyWaitTimeout
Description: Maximum wait for Block Assembly service to be ready before pruning
Sets the maximum time to wait for Block Assembly to be ready before proceeding with pruning operations. Prevents pruning data that could be needed for block construction.
pruner_connectionPoolWarningThreshold
Type: Float64
Default: 0.7
Environment Variable: pruner_connectionPoolWarningThreshold
Description: Connection pool utilization warning threshold (0.0-1.0)
When Aerospike connection pool utilization exceeds this threshold, the pruner auto-reduces chunk group limit to prevent pool exhaustion.
pruner_block_trigger
Type: String
Default: OnBlockPersisted
Environment Variable: pruner_block_trigger
Description: When to trigger pruning operations
Values:
OnBlockPersisted(default): Triggers on BlockPersisted notifications (coordinated with Block Persister)OnBlockMined: Triggers on Block notifications with mined_set=true
pruner_force_ignore_block_persister_height
Type: Boolean
Default: false
Environment Variable: pruner_force_ignore_block_persister_height
Description: Force ignore block persister height tracking
When enabled, uses Block notifications with mined_set=true instead of BlockPersisted notifications from Block Persister for determining safe prune height.
pruner_utxoSetTTL
Type: Boolean
Default: false
Environment Variable: pruner_utxoSetTTL
Description: Use TTL expiration instead of hard delete for UTXO records
When enabled, sets Aerospike record TTL to 1 second instead of hard deleting. This produces optimized tombstones and reduces write amplification.
pruner_skipBlobDeletion
Type: Boolean
Default: false
Environment Variable: pruner_skipBlobDeletion
Description: Skip blob deletion scheduling
When enabled, skips scheduled deletion of blob store data (transactions and subtrees) based on Delete-At-Height values.
pruner_blobDeletionSafetyWindow
Type: uint32
Default: 10
Environment Variable: pruner_blobDeletionSafetyWindow
Description: Number of blocks to wait after Block Persister height before deleting blobs
Provides a safety margin to ensure persisted blocks are stable before deleting their associated blobs.
pruner_blobDeletionBatchSize
Type: Integer
Default: 1000
Environment Variable: pruner_blobDeletionBatchSize
Description: Maximum number of blob deletions to process per pruning trigger
Limits deletions per cycle to prevent overwhelming the blob store. Remaining deletions are processed in subsequent triggers.
pruner_blobDeletionMaxRetries
Type: Integer
Default: 3
Environment Variable: pruner_blobDeletionMaxRetries
Description: Maximum retry attempts for failed blob deletions
pruner_skipPreserveParents
Type: Boolean
Default: false
Environment Variable: pruner_skipPreserveParents
Description: Skip Phase 1 - preserve parents of unmined transactions
When enabled, parent transactions will not be protected from deletion even if they have unmined children.
pruner_skipParentUpdates
Type: Boolean
Default: false
Environment Variable: pruner_skipParentUpdates
Description: Skip parent update operations during pruning
pruner_skipDeletions
Type: Boolean
Default: false
Environment Variable: pruner_skipDeletions
Description: Skip deletion operations during pruning
Operation Timeout Settings
pruner_jobTimeout
Type: Duration
Default: 10m (10 minutes)
Description: Timeout for overall pruning operation completion
Format: Duration string (e.g., 5m, 30s, 1h)
Example:
pruner_jobTimeout = 10m
Behavior:
- Pruning operation runs synchronously up to this timeout
- On timeout: Operation is logged as timed out but continues in background
Tuning Guidelines:
- Small databases:
5mmay be sufficient - Large databases: Increase to
15mor20m - Slow storage: Increase timeout accordingly
- High latency networks: Add buffer for network delays
Impact:
- Too short: Frequent timeouts logged
- Too long: Blocks other operations unnecessarily
Metrics: Monitor pruner_duration_seconds to determine appropriate timeout
UTXO Store Settings
These settings control the pruning behavior at the UTXO store level.
utxostore_unminedTxRetention
Type: uint32 (block height)
Default: globalBlockHeightRetention / 2
Typical Value: ~7200 blocks (≈50 days)
Description: Number of blocks to retain unmined transactions before considering them for parent preservation
Calculation:
globalBlockHeightRetention = 14400 # ~100 days
utxostore_unminedTxRetention = 7200 # 50 days
Purpose:
Unmined transactions older than this are considered "old" and their parent transactions are marked for preservation during Phase 1 pruning.
Tuning:
- Increase: Retain unmined transactions longer, slower pruning
- Decrease: Prune unmined transactions sooner, faster pruning, higher risk
Warning: Setting too low may cause valid resubmitted transactions to fail if their parent UTXOs were already pruned.
utxostore_parentPreservationBlocks
Type: uint32 (block height)
Default: blocksInADayOnAverage * 10
Typical Value: ~14400 blocks (≈100 days, assuming 144 blocks/day)
Description: Number of blocks to preserve parent transactions of old unmined transactions
Calculation:
blocksInADayOnAverage = 144 # Typical Bitcoin block time
utxostore_parentPreservationBlocks = 1440 # 10 days
Purpose:
When Phase 1 preservation runs, parent transactions get their PreserveUntil flag set to:
PreserveUntil = currentHeight + parentPreservationBlocks
This prevents parent UTXOs from being deleted for the specified number of blocks, ensuring resubmitted transactions can validate.
Tuning:
- Increase: Preserve parents longer, safer for resubmissions, slower pruning
- Decrease: Prune parents sooner, faster pruning, higher risk for resubmissions
Recommendation: Keep default value unless specific use case requires change.
utxostore_prunerMaxConcurrentOperations
Type: Integer
Default: UTXO store connection pool size
Description: Maximum number of concurrent pruning operations for Aerospike
Applies To: Aerospike store only (SQL uses fixed worker count)
Example:
utxostore_prunerMaxConcurrentOperations = 8
Impact:
- Higher values: Faster pruning, higher load on database
- Lower values: Slower pruning, lower load on database
Tuning Guidelines:
- Small databases: 4-8 workers sufficient
- Large databases: 8-16 workers for faster pruning
- Limited resources: Reduce to 2-4 workers
- High throughput nodes: Increase to 16-32 workers
Constraint: Limited by Aerospike connection pool size. Exceeding pool size causes contention.
Aerospike Worker Count:
Default: 4 workers (hardcoded in /stores/utxo/aerospike/pruner/pruner_service.go)
To change, modify code:
// In pruner_service.go
workerCount := 4 // Change this value
utxostore_disableDAHCleaner
Type: Boolean
Default: false
Description: Disable Delete-At-Height (DAH) pruning (Phase 2)
Example:
utxostore_disableDAHCleaner = true
Impact:
false: Normal operation, Phase 2 pruning runstrue: Phase 2 disabled, only Phase 1 (parent preservation) runs
When to Enable:
- Testing: Debugging pruning issues
- Investigation: Analyzing DAH pruning behavior
- Temporary workaround: If Phase 2 causing issues
Warning: Enabling this setting prevents UTXO record deletion, causing database growth. Only for testing/debugging.
Aerospike-Specific Settings
pruner_IndexName
Type: String
Default: pruner_dah_index
Description: Name of the Aerospike secondary index on DeleteAtHeight field
Example:
pruner_IndexName = pruner_dah_index
Purpose:
DAH pruning (Phase 2) queries Aerospike using this secondary index for efficient record filtering:
SELECT * FROM utxos WHERE deleteAtHeight <= safeHeight
Index Creation:
- Automatic: Created on service start via index waiter
- Wait Time: Service waits for index to be ready before starting pruning
Manual Index Creation (if needed):
asadm -e "asinfo -v 'sindex-create:ns=teranode;set=utxos;indexname=pruner_dah_index;indextype=NUMERIC;binname=deleteAtHeight'"
Index Verification:
asadm -e "show indexes"
Expected output:
Namespace Set Index Name Bin Name Type
teranode utxos pruner_dah_index deleteAtHeight NUMERIC
Chunk Processing Settings
These settings control parallel processing during UTXO pruning operations.
pruner_utxoChunkSize
Type: Integer
Default: 1000
Description: Number of records to process in each parallel chunk during pruning
Controls the granularity of parallel processing. Records are accumulated into chunks of this size, then processed in parallel.
Example:
pruner_utxoChunkSize = 1000
Tuning:
- Higher values: Fewer chunks, less parallelism overhead, more memory per chunk
- Lower values: More chunks, better parallelism, more overhead
Recommendation: Default value works well for most deployments.
pruner_utxoChunkGroupLimit
Type: Integer
Default: 10
Description: Maximum number of chunks to process in parallel
Limits concurrent chunk processing to prevent overwhelming Aerospike or exhausting system resources.
Example:
pruner_utxoChunkGroupLimit = 10
Tuning:
- Higher values: More parallelism, faster pruning, higher resource usage
- Lower values: Less parallelism, slower pruning, lower resource usage
Constraint: Limited by Aerospike connection pool size. Setting too high causes connection contention.
pruner_utxoProgressLogInterval
Type: Duration
Default: 30s
Description: Interval for logging progress during long-running pruning operations
When set, the pruner logs periodic progress updates showing records pruned and elapsed time.
Example:
pruner_utxoProgressLogInterval = 30s
Values:
0: Disable progress logging30s: Log every 30 seconds (default)1m: Log every minute
Use Case: Monitor progress during large pruning operations or troubleshoot slow pruning.
pruner_utxoPartitionQueries
Type: Integer
Default: 0 (auto-detect based on CPU cores)
Environment Variable: pruner_utxoPartitionQueries
Description: Number of parallel Aerospike partition queries for scanning prunable records
Aerospike's keyspace is divided into 4096 partitions. This setting controls how many workers scan partitions in parallel. Each worker processes a range of partitions independently, achieving up to 100x performance improvement over sequential queries.
Values:
0(default): Auto-detect based on CPU cores and Aerospike query-threads-limitN > 0: Fixed number of partition workers (capped at 4096)
Tuning:
- Higher values: Faster scanning, more Aerospike load and connections
- Lower values: Reduced cluster pressure, slower pruning
Recommendation: Use default (0) for automatic scaling. Set explicitly to match your Aerospike cluster's capacity.
Defensive Mode Settings
These settings control the defensive pruning mode, which adds safety checks before deleting parent transactions.
pruner_utxoDefensiveEnabled
Type: Boolean
Default: false
Description: Enable defensive child verification before parent deletion
When enabled, the pruner verifies that ALL spending children of a parent transaction are mined and stable (for at least blockHeightRetention blocks) before deleting the parent. This prevents orphaning children during chain reorganizations.
Example:
pruner_utxoDefensiveEnabled = true
Impact:
true: Safer pruning with child verification, slightly slower due to batch verificationfalse: Faster pruning, relies on retention period alone for safety
When to Enable:
- Production environments with high transaction resubmission rates
- Environments experiencing frequent chain reorganizations
- When data integrity is critical
Trade-off: Enabling adds Aerospike batch read operations to verify children, which increases pruning time but provides stronger safety guarantees.
pruner_utxoDefensiveBatchReadSize
Type: Integer
Default: 10000
Description: Batch size for defensive child verification queries
Controls how many child transactions are verified in a single Aerospike BatchGet call when defensive mode is enabled.
Example:
pruner_utxoDefensiveBatchReadSize = 10000
Tuning:
- Higher values: Fewer Aerospike round trips, more memory per batch
- Lower values: More round trips, less memory per batch
Applies To: Only used when pruner_utxoDefensiveEnabled = true
Context-Specific Configuration
Development Context
[dev]
startPruner = true
pruner_grpcAddress = localhost:8096
pruner_grpcListenAddress = localhost:8096
pruner_jobTimeout = 10m
Docker Context (Single Machine, Multi-Node)
[docker.m]
startPruner = true
pruner_grpcAddress = pruner:8096
pruner_grpcListenAddress = :8096
pruner_jobTimeout = 10m
Docker Context (Per-Service Containers)
[docker]
startPruner = true
pruner_grpcAddress = ${clientName}:8096
pruner_grpcListenAddress = :8096
pruner_jobTimeout = 10m
Docker Host Context (Access from Host)
[docker.host]
startPruner = true
pruner_grpcAddress = localhost:${PORT_PREFIX}8096
pruner_grpcListenAddress = localhost:${PORT_PREFIX}8096
pruner_jobTimeout = 10m
# Disable pruner for specific nodes
startPruner.teranode1.coinbase = false
startPruner.teranode2.coinbase = false
Kubernetes/Operator Context
[operator]
startPruner = true
pruner_grpcAddress = k8s:///pruner.${clientName}.svc.cluster.local:8096
pruner_grpcListenAddress = :8096
pruner_jobTimeout = 15m # Increase for distributed environments
Configuration Examples
Minimal Configuration (Defaults)
# settings.conf
startPruner = true
All other settings use defaults.
High-Performance Configuration
# settings.conf
startPruner = true
pruner_jobTimeout = 5m # Shorter timeout
pruner_utxoChunkSize = 2000 # Larger chunks
pruner_utxoChunkGroupLimit = 20 # More parallel chunks
utxostore_unminedTxRetention = 5000 # Prune sooner
utxostore_parentPreservationBlocks = 10000 # Shorter preservation
Use Case: High-throughput nodes with fast storage
Conservative Configuration
# settings.conf
startPruner = true
pruner_jobTimeout = 20m # Longer timeout
pruner_utxoChunkGroupLimit = 5 # Fewer parallel chunks
pruner_utxoDefensiveEnabled = true # Enable safety checks
utxostore_unminedTxRetention = 10000 # Retain longer
utxostore_parentPreservationBlocks = 20000 # Longer preservation
Use Case: Production nodes prioritizing data safety over performance
Testing Configuration
# settings_local.conf
startPruner = false # Disable pruning for testing
Use Case: Local testing requiring full UTXO history
Multi-Node Setup (Some Nodes Pruning)
# settings.conf
startPruner = true
# Disable for coinbase nodes (they don't need pruning)
startPruner.docker.host.teranode1.coinbase = false
startPruner.docker.host.teranode2.coinbase = false
# Enable for main processing node
startPruner.docker.host.teranode3 = true
Use Case: Multi-node setup where only certain nodes perform pruning
Environment Variable Overrides
Settings can be overridden via environment variables using uppercase names with underscores:
# Override pruner enable/disable
export STARTPRUNER=false
# Override gRPC port
export PRUNER_GRPCPORT=8097
# Override job timeout
export PRUNER_JOBTIMEOUT=15m
# Override UTXO settings
export UTXOSTORE_UNMINEDTXRETENTION=10000
export UTXOSTORE_PARENTPRESERVATIONBLOCKS=20000
Monitoring Settings
While not configuration settings, these Prometheus metrics should be monitored:
pruner_duration_seconds: AdjustjobTimeoutif consistently near timeoutpruner_skipped_total{reason="not_running"}: Indicates Block Assembly issuespruner_errors_total: Indicates database or connectivity issuesutxo_cleanup_batch_duration_seconds: Indicates Aerospike performance
Troubleshooting Configuration Issues
Pruner Not Starting
Check:
- Verify
startPruner = true - Check port 8096 availability:
lsof -i :8096 - Review logs:
grep "\[Pruner\]" teranode.log
Port Conflicts
Solution:
PRUNER_GRPC_PORT = 8097
pruner_grpcAddress = localhost:8097
pruner_grpcListenAddress = :8097
Frequent Timeouts
Symptoms: WARN [Pruner] Job timeout reached
Solution: Increase pruner_jobTimeout:
pruner_jobTimeout = 20m # or higher
Slow Pruning
Symptoms: High pruner_duration_seconds values
Solutions:
-
Increase parallel chunk processing:
pruner_utxoChunkGroupLimit = 20 # Process more chunks in parallel pruner_utxoChunkSize = 2000 # Larger chunks -
Verify Aerospike index exists:
asadm -e "show indexes" | grep pruner_dah_index -
Check database performance
-
If defensive mode is enabled and slowing pruning:
pruner_utxoDefensiveEnabled = false # Disable if safety checks not needed
Database Growth
Symptoms: UTXO database growing despite pruning enabled
Check:
-
Verify pruner running:
curl http://localhost:8096/metrics | grep pruner_processed_total -
Check
pruner_skipped_totalreasons:curl http://localhost:8096/metrics | grep pruner_skipped_total -
Verify Block Assembly in RUNNING state