Skip to content

WASM Procedures: Performance Optimization

Documentation Home > User Guides > Features > Performance Optimization


Overview

This guide covers performance optimization techniques for WASM procedures in HeliosDB, including caching, pooling, compilation strategies, and benchmarking results.

Related Sections:


Performance Optimization

Module Caching

HeliosDB automatically caches compiled WASM modules for faster startup.

Cache Configuration

-- Set cache size (number of modules)
SET heliosdb.wasm_module_cache_size = 1000;
-- Set cache TTL (seconds)
SET heliosdb.wasm_module_cache_ttl = 3600;
-- Enable/disable cache
SET heliosdb.wasm_module_cache_enabled = true;

Precompilation

Force compilation at deployment time:

-- Planned syntax for the upcoming WASM procedures feature; the current server does not accept it.
CREATE PROCEDURE my_procedure(x INT)
LANGUAGE wasm
WITH (precompile = true)
AS '/path/to/procedure.wasm';

View Cache Stats

SELECT * FROM heliosdb_wasm_cache_stats;

Output:

cached_modules | cache_hits | cache_misses | hit_rate | evictions
---------------|------------|--------------|----------|----------
243 | 15234 | 432 | 97.2% | 12

Instance Pooling

Reuse WASM instances instead of creating new ones.

Pool Configuration

-- Set pool size per procedure
SET heliosdb.wasm_instance_pool_size = 10;
-- Set instance max age
SET heliosdb.wasm_instance_max_age_seconds = 300;
-- Set instance max executions
SET heliosdb.wasm_instance_max_executions = 1000;

Pool Statistics

SELECT
procedure_name,
pool_size,
available_instances,
in_use_instances,
total_acquisitions,
avg_acquisition_time_ms
FROM heliosdb_wasm_pool_stats;

Fuel Metering Optimization

Reduce fuel metering overhead for trusted procedures:

-- Planned syntax for the upcoming WASM procedures feature; the current server does not accept it.
-- Disable fuel metering (security trade-off)
ALTER PROCEDURE trusted_procedure
SET fuel_metering = false;
-- Increase fuel limit
ALTER PROCEDURE expensive_procedure
SET fuel_limit = 10000000000; -- 10 billion

Memory Management

Pre-allocate Memory

// Rust: Use with_capacity to pre-allocate
let mut data = Vec::with_capacity(10000);
// Avoid growing allocations
for item in items {
data.push(item); // No reallocation needed
}

Memory Pool Configuration

-- Set memory pool size (MB)
SET heliosdb.wasm_memory_pool_size_mb = 1024;
-- Enable memory pooling
SET heliosdb.wasm_memory_pooling_enabled = true;

Batch Operations

Process multiple items in single procedure call:

#[procedure]
pub fn process_orders_batch(order_ids: Vec<i64>) -> Result<i32, String> {
let tx = begin_transaction()?;
let mut processed = 0;
for order_id in order_ids {
exec_sql(&format!("UPDATE orders SET status = 'processed' WHERE id = {}", order_id))?;
processed += 1;
}
commit_transaction(tx)?;
Ok(processed)
}

Usage:

-- Instead of 100 calls
SELECT process_order(1);
SELECT process_order(2);
...
-- Single batch call
SELECT process_orders_batch(ARRAY[1, 2, 3, ..., 100]);

Performance:

100 individual calls: ~500ms total
1 batch call: ~50ms total (10x faster)

Compilation Tiers

Choose compilation strategy based on workload:

-- Planned syntax for the upcoming WASM procedures feature; the current server does not accept it.
-- Optimizing compiler (default): Slow startup, fast execution
ALTER PROCEDURE hot_path_procedure
SET compilation_tier = 'optimizing';
-- Baseline compiler: Balanced
ALTER PROCEDURE occasional_procedure
SET compilation_tier = 'baseline';
-- Interpreter: Fast startup, slower execution
ALTER PROCEDURE rarely_used_procedure
SET compilation_tier = 'interpreter';

AOT (Ahead-of-Time) Compilation

Ahead-of-time compilation is part of the planned design: procedures would be compiled to native code when they are created, so the first call does not pay the compilation cost. The planned interface is SQL (CREATE PROCEDURE ... LANGUAGE wasm); there is no separate command-line tool for it.

Startup time comparison:

JIT compilation: ~50-100ms
AOT compilation: ~1-2ms (50x faster)

Performance Benchmarks

Indicative figures measured on representative fixtures; reproduce on your own hardware.

Execution Time (Single Call):

Traditional PL/pgSQL: 52ms
WASM (Rust, optimizing): 6ms (8.7x faster)
WASM (JavaScript): 11ms (4.7x faster)
WASM (Python): 14ms (3.7x faster)
WASM (Go): 8ms (6.5x faster)

Throughput (1000 calls):

Traditional PL/pgSQL: 52,000ms
WASM (Rust): 6,200ms (8.4x faster)
WASM (pooled instances): 3,100ms (16.8x faster)

Memory Usage:

PL/pgSQL (1000 instances): ~500 MB
WASM (1000 instances): ~120 MB (4.2x less)
WASM (pooled, 100 instances): ~25 MB (20x less)

Key Takeaways

  1. Module Caching: Dramatically reduces startup time through compiled module reuse
  2. Instance Pooling: Eliminates instantiation overhead with pre-warmed instances
  3. Batch Processing: 10x performance improvement for bulk operations
  4. AOT Compilation: 50x faster startup for production deployments
  5. Compilation Tiers: Balance startup time vs. execution speed based on usage patterns

Best Practices

  • Enable module caching for frequently used procedures
  • Use instance pooling for high-throughput workloads
  • Batch operations when processing multiple items
  • Use AOT compilation for production hot paths
  • Pre-allocate memory in procedures to avoid runtime allocations

Next Steps


Navigation: ← Procedure Management | Index | Monitoring →