fix: in-process memoization of collection metadata to reduce CPU overhead (#14420) by Ezeko · Pull Request #14686 · appwrite/appwrite · GitHub
Skip to content

fix: in-process memoization of collection metadata to reduce CPU overhead (#14420) - #14686

Open
Ezeko wants to merge 3 commits into
appwrite:mainfrom
Ezeko:fix-14420-collection-metadata-cache
Open

Ezeko wants to merge 3 commits into
appwrite:mainfrom
Ezeko:fix-14420-collection-metadata-cache

Conversation

@Ezeko

@Ezeko Ezeko commented Oct 19, 2026

Copy link
Copy Markdown

Summary

Fixes #14420

Collection metadata was previously re-fetched and completely rebuilt (toCollection()) on every database call, causing ~20–30% API CPU consumption in long-running Swoole worker processes due to repetitive JSON decoding and object tree allocation.

Solution

Implemented an in-process metadata memoization layer in Appwrite\Utopia\Database\Database:

  • In-process memoization: Resolves and caches collection definitions in memory for $O(1)$ access on repeated calls.
  • Defensive cloning: Returns shallow-cloned instances so caller mutations cannot corrupt the memoized definition.
  • Multi-node coherence: Uses a 2.0s validation window backed by Redis generation token checks (getGeneration()) so cross-node updates invalidate stale local entries.
  • Synchronous eviction: Overrode purgeCachedDocumentInternal() and purgeCachedCollection() to invalidate local memo entries when metadata is modified.
  • Transaction isolation: Automatically bypasses the in-process memo during active transactions.
  • Factory integration: Updated Appwrite\Database\Factory to provision Appwrite\Utopia\Database\Database.

Testing

  • Added comprehensive unit tests in tests/unit/Database/CollectionMetadataCacheTest.php.
  • Ran full unit test suite via appwrite/base:2.2.3:
    • OK (20 tests, 59 assertions)
  • PSR-12 code style verified with Pint:
    • PASS (3 files)

Ezeko added 2 commits October 19, 2026 17:15
…head (appwrite#14420)

Collection metadata was previously re-fetched from cache/storage and reconstructed via toCollection() on every database operation, incurring substantial CPU overhead in JSON/array unpacking and object graph construction.

This introduces Appwrite\Utopia\Database\Database wrapping Utopia\Database\Database with:
- In-process collection memoization within a configurable validation window
- Generation token checks to maintain cross-process / cross-node cache coherence
- Defensively cloned returns to prevent callers from corrupting the memoized definition
- Synchronous local eviction on metadata purge or collection mutation
- Transparent bypass during active transactions
@hansi-codes

hansi-codes Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

hansi-codes[bot]
hansi-codes Bot previously requested changes Oct 19, 2026

@hansi-codes hansi-codes Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Tier B · 2 blocking findings to address. Summary

Comment thread src/Appwrite/Utopia/Database/Database.php Outdated
Comment thread src/Appwrite/Utopia/Database/Database.php Outdated
…eneration around reads

- Include adapter hostname in process collection memo key to prevent collisions across multiple database hosts
- Capture generation token before metadata read and verify it remains stable after read to guard against race conditions

@hansi-codes hansi-codes Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Tier S · Looks good to merge. Summary

@hansi-codes
hansi-codes Bot dismissed their stale review October 19, 2026 17:06

The findings that requested changes are resolved. See the summary comment for what is still open.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 Bug Report: Collection metadata is re-read and rebuilt on every database call (~20–30 % of API CPU)

1 participant