Sui.

Post

Share your knowledge.

Big Mike.
Sep 04, 2025
Expert Q&A

Leveraging Sui’s Object-Centric Model for Scalable dApp Development

How can I use Sui’s object-centric data model to improve scalability and parallel execution compared to traditional account-based models, and what design considerations should I keep in mind when building dApps that rely on owned vs. shared objects?

  • Sui
  • Architecture
  • SDKs and Developer Tools
  • Security Protocols
1
2
Share
Comments
.

Answers

2
theking.
Sep 4 2025, 08:59

You scale on Sui by modeling most state as owned or immutable objects so your transactions can run in parallel without coordination, and you touch shared objects only at the narrow points where global agreement is truly required; in practice you design per-user “position” or “ticket” objects (owned) for hot paths, batch independent mutations in one transaction block to exploit parallel execution, and isolate shared-object logic behind small, idempotent, capability-checked entry points that minimize writes and contention while relying on version checks to safely retry on conflicts; you also shard any unavoidable shared state (e.g., AMM liquidity) into multiple shared partitions, aggregate off-chain when possible, and keep object graphs shallow to reduce cross-object dependencies; here’s a compact pattern that keeps the fast path owned and the slow path minimal:

module dapp::positions {
    use sui::tx_context::TxContext;
    use sui::object::{Self, UID};
    use sui::coin::{Self as coin, Coin};
    use sui::sui::SUI;

    struct Position has key { id: UID, owner: address, stake: u64 }
    struct Pool has key { id: UID, total: u64 } // shared object, single write hotspot

    public entry fun open_position(owner: &signer, stake: Coin<SUI>, ctx: &mut TxContext) {
        let amt = coin::value(&stake);
        let pos = Position { id: object::new(ctx), owner: signer::address_of(owner), stake: amt };
        // keep coin in caller’s wallet; just record metadata to avoid shared writes
        object::transfer(pos, signer::address_of(owner));
    }

    public entry fun commit_to_pool(mut p: &mut Pool, _cap: &AdminCap, delta: u64) { // tiny shared write
        p.total = p.total + delta; // minimal mutation, easy to shard across multiple pools
    }
}
// Transaction block showing parallel-friendly ops (two owned objects), then a tiny shared write
import { Transaction } from '@mysten/sui.js/transactions';
const tx = new Transaction();
const myPos1 = '0x...pos1';         // owned object
const myPos2 = '0x...pos2';         // owned object
const poolId = '0x...pool';         // shared object
tx.moveCall({ target: 'dapp::positions::update_pos', arguments: [tx.object(myPos1), tx.pure.u64(100)] }); // parallel-safe
tx.moveCall({ target: 'dapp::positions::update_pos', arguments: [tx.object(myPos2), tx.pure.u64(200)] }); // parallel-safe
tx.moveCall({ target: 'dapp::positions::commit_to_pool', arguments: [tx.object(poolId), tx.object('0x...cap'), tx.pure.u64(300)] }); // serialized, small
// client.signAndExecuteTransaction({ transaction: tx })
3
Comments
.
Thorfin.
Sep 4 2025, 07:52

Sui’s object-centric model scales because transactions only lock the exact objects they touch. If two transactions involve different objects, they can run in parallel, unlike account-based chains where every balance update goes through the same account state.

For dApp design:

  • Owned objects (like a user’s inventory, position, or profile) scale best, since each user updates their own state without contention.
  • Shared objects (like an AMM pool or game room) are needed for coordination, but keep them small and localized to avoid bottlenecks.
  • Immutable objects work well for configs or metadata that never change.

The key is to push most logic into owned objects, minimize writes to shared ones, and rely on events/indexers for discovery. This way your dApp taps into Sui’s parallel execution without running into hotspots.

0
Comments
.

Do you know the answer?

Please log in and share it.