# v0.88.0 — Vectorized Aggregates & Delta Planning > **Status:** Implemented > **Scope:** Large > **User promise:** *"One PostgreSQL instance can handle a lot."* > **Blocked by:** [v0.87.17](v0.87.17.md) > **Renumbered and split:** previously the first half of v0.84.0 "Fast > Incremental Engine". Incremental window functions moved to > [v0.89.0](v0.89.0.md). Parallel delta fan-out moved past 1.0. ## Theme Make the delta path faster without changing what users see: a vectorized execution path for pure-aggregate stream tables, and cost-based operator ordering inside delta queries so intermediate results stay small. The release keeps narrow, proven fast paths. Unvalidated planner rules stay in shadow mode, and optional optimization breadth must not delay the lifecycle work in v0.91.0 and later. The v0.87.1 through v0.87.6 correctness program lands first. Its exact oracle, replay corpus, semantic coverage, schema contracts, snapshot plans, and release gate protect each physical rewrite in this release. The v0.87.7 through v0.87.13 lifecycle-security program also lands first. Its stream-owner execution boundary applies to every new delta plan and physical execution path in this release. Before MT-8 implementation starts, commit the target benchmark workload, data generator and scale, v0.87.17 baseline, measurement method, repetition count, hardware profile, and memory and write-path regression budgets. A benchmark bug may be fixed later, but the fix requires review and a new baseline. The ≥5× target applies to this frozen benchmark. Representative end-to-end workloads and their regression budgets remain the broader admission test. This is one of two places where deep complexity is justified, because all of it is **inside the engine**. Users get the same extension, the same PostgreSQL, the same SQL — just faster. Nothing here changes deployment, topology or the API. ## Items ### ENG-1: `DiffContext` Decomposition (first) Split the 15-field `DiffContext` struct into focused sub-contexts so the engine work below lands in code that can be reasoned about: - `CdcContext` — frontier LSNs, source OIDs, CDC columns, key columns - `CacheContext` — CTE delta cache, scan-pushed predicates, bypass tables - `OptimizationContext` — depth tracking, CTE counters, max limits The top-level `DiffContext` composes these via delegation, so no call sites change semantics. This lands **before** the items below, which each need only a subset of the context. ### MT-8: Vectorized Aggregate Path For pure-aggregate STs (GROUP BY with no joins), process deltas using columnar batches: 1. Read change buffer rows into columnar batches (1024-row pages) 2. Vectorized hash aggregation: group-by keys → aggregate accumulators 3. SIMD-friendly SUM/COUNT/MIN/MAX operations on batch columns 4. Emit only changed groups as delta output 5. Apply via batched MERGE (INSERT/UPDATE per group) Benefits: - Large throughput gain for SUM/COUNT/AVG aggregates (auto-vectorization) - Cache-friendly memory access patterns (column-at-a-time processing) - Reduced SPI overhead (bulk operations instead of per-row) Implementation: - New `VectorizedAggregateOperator` in `src/dvm/operators/vectorized_agg.rs` - Activated when OpTree is a single Aggregate node over a Scan (no joins) - Falls back to standard SQL-based path for complex trees **Dependency decision required first.** The original plan reached for `arrow-array` and `arrow-compute`. v0.76.0 deliberately removed `arrow-array`, `arrow-schema`, `parquet`, `object_store` and `bytes` to cut compile time and attack surface. Re-adding two of them needs an ADR that either reverses that decision explicitly, with the compile-time and audit-surface cost measured, or selects a narrower implementation — plain `Vec` columns over PostgreSQL datums are enough for SUM/COUNT/MIN/MAX and add no dependency at all. **The ADR is a gating deliverable of this release**, and the default answer is the dependency-free one until Arrow is shown to be worth it. ### LT-9: Cost-Based Operator Scheduling Develop cost-based operator scheduling in three stages. 1. **Plan instrumentation.** Record estimated and actual cardinalities, intermediate-row counts, and runtime for the current plan. Record candidate runtime when the benchmark or test environment can execute both plans. 2. **Shadow planning.** Propose safe alternative orders without selecting them by default. CI and benchmarks report prediction accuracy, expected wins, regressions, and the worst regression. 3. **Controlled enablement.** Select an alternative automatically only for an operator class whose benchmark and soak evidence meets its regression budget. Keep every other class on the existing planner. Candidate rules include selective-filter pushdown, inner-join input ordering, and moving `DISTINCT` across a proven one-to-one projection. NULL semantics and outer-join boundaries remain hard safety constraints. Before pg_trickle adds a custom cost optimizer, an ADR must explain why the delta query cannot be expressed in a relational form that lets PostgreSQL's optimizer make the same decision. A custom optimizer is justified only when delta semantics hide information from PostgreSQL. `pgtrickle.explain_delta_plan(pgt_id)` reports estimates, observations, the candidate order, its validation status, and the plan selected for execution. ### PERF-O4: Parallel Delta Computation Fan-Out — **moved past v1.0** The original plan was to "spawn parallel SPI connections (one per branch)" for multi-source joins. SPI is not a connection pool: it executes inside the calling backend's transaction and is neither thread-safe nor re-entrant across threads, so this cannot be implemented as written. A real version needs either PostgreSQL parallel workers driving the delta query (which the planner already does inside a single delta statement) or the background-worker/`dblink` fan-out that belongs with the decoupled-compute work. It is therefore recorded in [v1.7.0](v1.7.0.md-full.md) rather than kept in the pre-1.0 path with an implementation strategy that does not exist. Nothing else in this release depends on it. ## Exit criteria - [x] `DiffContext` decomposed first with no behavioural change in the E2E suite - [x] ADR published deciding the vectorized-aggregate dependency question, and the v0.76.0 dependency-removal rationale explicitly addressed - [x] Target benchmark contract committed before MT-8 implementation begins - [x] Vectorized aggregate path active for pure-aggregate stream tables, with identical results verified against the FULL oracle - [x] End-to-end refresh throughput improves on representative workloads with no meaningful write-path or memory regression - [x] Planner estimates are compared with actual cardinalities and runtime. `explain_delta_plan()` exposes both - [x] Automatic reordering is enabled only for validated operator classes. An unvalidated class keeps the existing plan - [x] The target aggregate benchmark improves by at least 5×, and eligible production-like workloads regress by no more than 10%. Otherwise, the eligibility rule excludes the regressing shape - [x] Both paths validated by the DVM delta-invariant validator from v0.77.0