risingwavelabs/risingwave · error · BatchError

Not enough memory to run this query, batch memory limit is {

Error message

Not enough memory to run this query, batch memory limit is {0} bytes

What it means

BatchError::OutOfMemory is thrown when a batch query cannot proceed because the memory manager denies allocation: the query would exceed the configured per-query batch memory limit. The error carries the limit in bytes so developers can compare it against the workload's needs. It is a deliberate guard to protect the node from OOM, not an unexpected fault.

Source

Thrown at src/batch/src/error.rs:143

    Shared(
        #[from]
        #[backtrace]
        Arc<Self>,
    ),

    #[error("Empty workers found")]
    EmptyWorkerNodes,

    #[error("Serving vnode mapping not found for fragment {0}")]
    ServingVnodeMappingNotFound(FragmentId),

    #[error("Streaming vnode mapping has not been initialized")]
    StreamingVnodeMappingNotInitialized,

    #[error("Streaming vnode mapping not found for fragment {0}")]
    StreamingVnodeMappingNotFound(FragmentId),

    #[error("Not enough memory to run this query, batch memory limit is {0} bytes")]
    OutOfMemory(u64),

    #[error("Failed to spill out to disk")]
    Spill(
        #[from]
        #[backtrace]
        opendal::Error,
    ),

    #[error("Failed to execute time travel query")]
    TimeTravel(
        #[source]
        #[backtrace]
        anyhow::Error,
    ),
}

// Serialize/deserialize error.

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Reduce the query's memory footprint (add LIMIT, filters, or break it into smaller queries).
  2. Increase the batch memory limit in the RisingWave configuration (memory management settings) or the node's memory resources.
  3. Enable/configure spill-to-disk so operators can evict data instead of failing.
  4. Check `EXPLAIN` and the query plan for unbounded operators (large hash builds / sorts) and tune accordingly.

Example fix

// before (risingwave.toml)
[developer]
batch_memory_limit_mb = 0  # tiny limit causes OOM for big queries

// after
[developer]
batch_memory_limit_mb = 2048  # raise limit and rely on spill for larger workloads
Defensive patterns

Strategy: try-catch

Validate before calling

// Rust: estimate query memory needs against the configured limit before running
// (pseudo) if est_bytes > batch_memory_limit { spill_plan or split_query }

Try / catch

match result {
    Err(BatchError::OutOfMemory(limit)) => {
        // fall back: enable spill or rewrite query with LIMIT/filter, then retry
    }
    other => other?,
}

Prevention

When it happens

Trigger: Executing a batch query (e.g. SELECT over a large materialized view) whose operator working set exceeds the batch memory limit (developer.batch_spill_by_mem_limit / batch memory context); the memory manager refuses an allocation during executors like sort/hash-agg/hash-join and the executor maps this to BatchError::OutOfMemory.

Common situations: Large ad-hoc analytical queries over big MVs, low memory limit configured on small dev instances or in k8s with small resource requests, missing spill configuration so the query must hold everything in memory.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/3b6ff052bc5ce96d. Report an issue: GitHub.