[turbopack] Unify Cell Storage#92974
Merged
lukesandberg merged 9 commits intocanaryfrom Apr 21, 2026
Merged
Conversation
Add new serializability options. The key thing we want to distinguish is 'this cell is not serializable and it is important' vs this cell isn't _worth_ serializing Currently there isn't a reason to distinguish, but with eviction there is. In theory we should implement a priority system * unevictable (e.g. DiskFileSystemInner). not serialiable fundamentally, evicting this breaks the watcher * expensive (e.g. the WorkerThreadPool). not serializable fundamentally, evicting this would be a perf hit * cheaply derivable: (e.g. EcmascriptChunkItemContent). serializable, but not worth it * regular: everthing else But for now there are just two levels unevictable and everything else, if some of the 'everything else' isn't serializable that is fine.
Merging this PR will not alter performance
Comparing Footnotes
|
lukesandberg
commented
Apr 18, 2026
lukesandberg
commented
Apr 18, 2026
Contributor
Stats from current PR✅ No significant changes detected📊 All Metrics📖 Metrics GlossaryDev Server Metrics:
Build Metrics:
Change Thresholds:
⚡ Dev Server
📦 Dev Server (Webpack) (Legacy)📦 Dev Server (Webpack)
⚡ Production Builds
📦 Production Builds (Webpack) (Legacy)📦 Production Builds (Webpack)
📦 Bundle SizesBundle Sizes⚡ TurbopackClient Main Bundles
Server Middleware
Build DetailsBuild Manifests
📦 WebpackClient Main Bundles
Polyfills
Pages
Server Edge SSR
Middleware
Build DetailsBuild Manifests
Build Cache
🔄 Shared (bundler-independent)Runtimes
📝 Changed Files (2 files)Files with changes:
View diffspages-api.runtime.dev.jsDiff too large to display pages.runtime.dev.jsDiff too large to display 📎 Tarball URL |
lukesandberg
commented
Apr 18, 2026
sokra
reviewed
Apr 19, 2026
lukesandberg
commented
Apr 19, 2026
Contributor
Author
|
Discussed with nicholas lets split this into 2 keys serialization="auto,hash,custom,none" this will be a bit more intuitive but it does introduce the issue of having some 'meaningless combinations' for now we can just ban unsupported combinations |
sokra
approved these changes
Apr 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

What
Tightens the value-type persistence API and sets the table for a future eviction policy. Two user-visible changes on the
#[turbo_tasks::value(...)]macro:serialization = "none"→serialization = "skip"— imperative ("skip persisting") instead of descriptive. Making it clear that it isn't that we are missing a feature but rather that we are choosing to not persist (of course persisting might be impossible but that is generally rare)evict = "always" | "last" | "never"attribute — replaces the old overloaded"none"semantic. Only valid withserialization = "skip". Defaults to"always".Internally this collapses
persistent_cell_data+transient_cell_datainto onecell_datamap and replaces the oldbincode: Option<(enc, dec)>field with a four-variantValueTypePersistenceenum. Eviction machinery itself is a follow-up PR; this PR just gives each value type a precise, queryable persistence/eviction descriptor.Why break out a new parameter?
serialization = "none"on canary conflated three different intents:Ropes) — fine to evict, recompute is cheap.State<>cells,Arc<Mutex<_>>dedup histories) — can't be recomputed without losing accumulated mutations.They all produced identical runtime behavior (stored in transient_cell_data), so eviction can't tell them apart. The fix is two orthogonal attributes:
The macro rejects
evicton any otherserializationmode.ValueTypePersistenceenumReplaces
ValueType.bincode: Option<(enc, dec)>:The existing
"hash"mode gets its ownHashOnlyvariant rather than being folded intoSkipPersist, which lets the backend gate its hash-writing and hash-comparison paths precisely.Unified
cell_datastoragepersistent_cell_data: AutoMap<CellId, TypedSharedReference>+transient_cell_data: AutoMap<CellId, SharedReference>collapse intocell_data: CellData.CellDatais a newtype overAutoMap<CellId, SharedReference>with a custom bincode impl that filters non-Persistableentries at encode time. This removes theis_serializable_cell_content: boolparameter that was threading through ~14 read/write call sites.Uses
SharedReferenceinstead ofTypedSharedReference—CellIdalready carries theValueTypeId.Annotation sweep
All prior
serialization = "none"sites move to eitherserialization = "skip", evict = "never"orserialization = "skip", evict = "last"based on a per-site audit. Summary:evict = "last"(6 sites) — re-derivable but expensive:SwcPluginModule,EvaluatePool,ChildProcessPool,WorkerThreadPool,EffectInstance,Effectsevict = "never"(2 sites) — interior-mutable state accumulated across the session:ConsoleUi(Arc<Mutex<SeenIssues>>),VersionState(State<VersionRef>with HMR invalidators)The distinguishing rule:
evict = "never"only when the value holds interior mutability accumulated across the session. Everything else can be re-derived (possibly expensively) by re-running the producing task.Follow-ups (separate PRs)
ValueTypePersistence— respectsSessionStateful(never evict), prefers cheapSkipPersistoverexpensive: trueones. Either as part of Proof of concept: task eviction after snapshot for turbo-tasks-backend #91790 or afterwards depending on when things land