Skip to content

Morsel-Driven Parallelism

QueryParallelismPerformance
Opt-in Implemented · off by default — enable with enable_parallel = true

Classical databases were built around a one-query-one-thread model. On a 128-core server, a single big SELECT runs on one core while the rest sit idle. With morsel parallelism enabled, AetheriusDB takes the opposite approach: an analytical query is split into many small units of work — morsels — and every available CPU core grabs morsels until the work is done.

Each morsel is a self-contained chunk of the table that one worker processes end-to-end. Workers don’t coordinate on the hot path: when a worker finishes a morsel, it pulls the next one. When there are no morsels left, the query is done.

Morsel granularity is what lets a query scale roughly linearly with the number of cores. There’s no central scheduler and no per-row coordination, so there are no lock-acquire bottlenecks and no global mutex to serialise on.

  • Full CPU saturation — a single big aggregate uses every core, not just one.
  • NUMA-friendly — workers prefer morsels whose memory lives on their own socket, avoiding cross-socket bus traffic.
  • Self-balancing — a slow morsel doesn’t stall the query; other workers keep taking the rest.
flowchart TB
  classDef src fill:#1f2640,stroke:#7c5cff,color:#e8eaf0
  classDef q   fill:#1f2640,stroke:#00d4ff,color:#e8eaf0
  classDef w   fill:#1f2640,stroke:#4ade80,color:#4ade80

  T[10 TB table<br/>split into many chunks]:::src --> Q[Shared morsel queue]:::q

  Q --> W1[Core 0 worker]:::w
  Q --> W2[Core 1 worker]:::w
  Q --> W3[Core 64 worker]:::w
  Q --> W4[Core 65 worker]:::w

  W1 --> M[Final merged result]:::w
  W2 --> M
  W3 --> M
  W4 --> M

Set enable_parallel = true on the server. After that, any analytical query that touches more than one chunk of the table is parallelised automatically. Observe what the planner picked with EXPLAIN (ANALYZE), and tune the worker pool at startup if you need to.

-- A query that will fan across cores once parallelism is enabled.
SELECT region, COUNT(*) AS n, AVG(price) AS avg_price
FROM sales
GROUP BY region;
-- See how many workers and morsels the planner picked:
EXPLAIN (ANALYZE) SELECT * FROM sales WHERE price > 100;
-- Tune the worker pool at server start:
-- aetheriusd --query-workers 64

The default worker count matches the number of physical cores. In most deployments you don’t need to touch it — leaving it alone gives the best results for mixed workloads.

TermWhat it means
MorselA unit of parallel work — a chunk of the table a single worker processes end-to-end.
Work stealingWhen a worker finishes its morsel, it pulls the next from the shared queue rather than waiting.
NUMA-awareWork runs on the CPU closest to the data it touches, so large multi-socket servers avoid cross-socket memory latency.
Local aggregationDuring GROUP BY, workers aggregate into thread-local maps and merge only at the end.