Post
Share your knowledge.

🔄 Shared vs. Owned Objects: Choosing the Right Concurrency Pattern on Sui
🚨 Problem this solves: Many teams default to shared objects for everything that multiple users touch. The result? ❌ Contention, ❌ failed transactions, and ❌ confusing errors. Others overuse address-owned objects and suddenly can’t coordinate multi-party actions.
👉 What you really need is a clear decision framework for when to use address-owned, shared, or immutable — while still keeping throughput high and invariants tight.
🧭 1) The Decision Tree
Ask yourself these 3 quick questions:
1️⃣ Does only one address mutate it? → ✅ Address-owned (fast, parallel, no consensus overhead).
2️⃣ Do many addresses need to mutate the same record? → ✅ Shared (design carefully to reduce contention).
3️⃣ Is it reference data that never changes? → ✅ Immutable (publish once, reuse forever).
👤 2) Address-Owned Patterns
💡 Best for: wallets, inventories, positions, drafts, personal settings.
Why use it? ✨ No global contention — runs in parallel. ✨ Only the owner can fail their own tx (cleaner UX).
Step-by-step 👇
- Create a per-user root object (e.g.,
Profile,Inventory). - Use dynamic fields for lists (items, positions) → avoids vector growth issues.
- For peer-to-peer actions → move objects between owners instead of touching a shared registry.
⚠️ Pitfall: Using a shared “Registry” for user lookups. ✅ Fix: Derive deterministic IDs or store a one-time mapping at signup. From then on → interact directly with each user’s object.
🤝 3) Shared Patterns (Safely!)
💡 Best for: order books, game rooms, auctions, governance pools.
The Risk: contention + version conflicts if everyone writes to the same object.
Partitioning Strategies 🪄
- Spatial → one shared object per room/level/map.
- Temporal → rotate objects per epoch/round.
- Hash-based → bucket by
hash(key) % N. - Semantic → split by category, price range, queue, etc.
Marketplace Example 🛒
Collection(shared) → represents creator scope.OrderBookShard(shared) → per price bucket.Listing(address-owned) → lives with seller until matched.- Matchmaking → only touches the shard for the relevant price bucket.
- Settlement → moves
Listingto buyer + updates shard counters.
✨ Invariant Rules:
- Only touch the shard you need.
- Don’t store global aggregates → compute off-chain or lazily.
📜 4) Immutable Patterns
💡 Best for: templates, schemas, metadata, descriptors.
Step-by-step:
- Publish immutable object with constant fields.
- Store its
ObjectIDin owned/shared objects. - For upgrades → publish a new immutable object and let consumers opt-in.
⚠️ Pitfall: Putting live counters or user-specific data in immutable objects. ✅ Fix: Keep dynamic state in owned/shared, constants in immutable.
🔗 5) Handling Cross-Object Actions
When an action spans multiple objects:
- Consume only what you need.
- Re-emit derived objects instead of mutating massive shared state.
- Keep the cut set (touched objects) minimal.
Conflict Checklist ✅
- Writing only one shard?
- Can independent actions commit without colliding?
- On conflict, can the client retry with just one fresh read?
📊 6) Audit with Counters
Add simple diagnostic counters (e.g., “writes per shard per minute”) in testnet. 🔎 If one shard is too hot → increase bucket count or rethink your partition key.
🎯 Outcome
By consciously using the right object type for the right scenario:
- 👤 Owned objects → smooth per-user flows.
- 🔄 Shared objects → only for true coordination.
- 📜 Immutable objects → reference data only.
👉 You’ll keep contention low, parallelism high, and user experience 🚀 seamless.
- Architecture
Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.
- How to Maximize Profit Holding SUI: Sui Staking vs Liquid Staking616
- Why does BCS require exact field order for deserialization when Move structs have named fields?65
- Multiple Source Verification Errors" in Sui Move Module Publications - Automated Error Resolution55
- Sui Move Error - Unable to process transaction No valid gas coins found for the transaction419
- Sui Transaction Failing: Objects Reserved for Another Transaction410