Skip to content

refactor(@angular/build): add composite index on last_accessed in sqlite cache store - #33995

Open
clydin wants to merge 2 commits into
angular:mainfrom
clydin:perf/sqlite-cache-index
Open

refactor(@angular/build): add composite index on last_accessed in sqlite cache store#33995
clydin wants to merge 2 commits into
angular:mainfrom
clydin:perf/sqlite-cache-index

Conversation

@clydin

@clydin clydin commented Sep 2, 2026

Copy link
Copy Markdown
Member

Previously, the SQLite cache table had no secondary index on last_accessed. Cache eviction routines during close() required full table scans for both TTL-based pruning and LRU size-based pruning. Specifically, calculating running sizes using a window function ordered by last_accessed DESC, key DESC required SQLite to materialize and sort the entire table in temporary memory on every cache close.

In large persistent caches, these full scans and temporary sorts introduced unnecessary CPU and I/O overhead on shutdown.

A composite index idx_cache_accessed on (last_accessed DESC, key DESC) is now created on the cache table. This enables SQLite to directly seek entries older than the TTL limit using an indexed binary search and stream rows in descending access order for the window aggregate calculation without requiring an in-memory sort pass.

@clydin clydin added the target: minor This PR is targeted for the next minor release label Sep 2, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a database index (idx_cache_accessed) on the SQLite cache store to optimize queries on last_accessed and key, along with a corresponding unit test to verify its creation. The review feedback suggests wrapping the test's database operations in a try...finally block to ensure the SQLite database connection is safely closed even if an error occurs, preventing potential file locking issues.

Comment thread packages/angular/build/src/tools/esbuild/sqlite-cache-store_spec.ts Outdated
…ite cache store

Previously, the SQLite cache table had no secondary index on `last_accessed`. Cache eviction routines during `close()` required full table scans for both TTL-based pruning and LRU size-based pruning. Specifically, calculating running sizes using a window function ordered by `last_accessed DESC, key DESC` required SQLite to materialize and sort the entire table in temporary memory on every cache close.

In large persistent caches, these full scans and temporary sorts introduced unnecessary CPU and I/O overhead on shutdown.

A composite index `idx_cache_accessed` on `(last_accessed DESC, key DESC)` is now created on the cache table. This enables SQLite to directly seek entries older than the TTL limit using an indexed binary search and stream rows in descending access order for the window aggregate calculation without requiring an in-memory sort pass.
@clydin
clydin force-pushed the perf/sqlite-cache-index branch from 41b8750 to 29b9bff Compare September 2, 2026 17:22
Previously, cache eviction routines during close executed as independent autocommit transactions. In addition, the LRU size pruning query calculated running payload sizes with a window function across the entire cache table on every build, even when total database size was well below maxPayloadSize.

Pruning operations in close are now wrapped in an immediate transaction to ensure atomicity and reduce transaction commit overhead. Furthermore, total database size is checked using SQLite page pragmas prior to size-based pruning, allowing the expensive window aggregate query to be skipped when the total cache size is already within limits.
@clydin clydin added the action: review The PR is still awaiting reviews from at least one requested reviewer label Sep 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action: review The PR is still awaiting reviews from at least one requested reviewer area: @angular/build target: minor This PR is targeted for the next minor release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant