How is Sui different from Aptos?
October 28, 2026
Sui and Aptos both come out of Meta's Diem project and both use Move, but they use it differently. Aptos keeps core Move's global storage: resources live under account addresses and you reach them with borrow_global and move_to. Sui drops global storage. Every piece of state is an object with a UID and an explicit owner. That one choice shapes how you write contracts, how transactions run in parallel and how clients build transactions.
Storage model
On Aptos, state is organized as resources and modules stored in accounts. Aptos has also added its own object model (AIP-10) for grouping resources at one address.
On Sui, a struct with the key ability is an object. It's created with object::new(ctx), and it's address-owned, shared, immutable or wrapped inside another object. Sui Move has no borrow_global or move_to. A function can only touch objects that were passed into the transaction.
module example::counter;
public struct Counter has key {
id: UID,
value: u64,
}
public fun create(ctx: &mut TxContext) {
// Shared: anyone can pass it into a transaction
transfer::share_object(Counter { id: object::new(ctx), value: 0 });
}
public fun increment(c: &mut Counter) {
c.value = c.value + 1;
}For the language-level differences (abilities, entry functions, init, one-time witnesses) see Sui Move vs Aptos Move.
Parallel execution
Aptos runs transactions in parallel with Block-STM, which works out conflicts at runtime without the user declaring anything. On Sui, every transaction lists its input objects upfront. Transactions on different objects don't conflict, and those that write to the same shared object are ordered by consensus. On Sui you get parallelism by designing your objects so that unrelated users don't touch the same shared object.
Transactions
Aptos accounts use sequence numbers (or orderless nonces) for replay protection, and a transaction usually calls one entry function or runs a Move script. Sui has no account sequence numbers: replay protection comes from object versions. A Sui transaction is a programmable transaction block that chains up to 1,024 commands. Those can be Move calls, coin splits and merges, or transfers, all composed client-side.
import { Transaction } from '@mysten/sui/transactions';
const tx = new Transaction();
const [coin] = tx.splitCoins(tx.gas, [1_000_000]);
tx.moveCall({ target: `${PACKAGE_ID}::counter::increment`, arguments: [tx.object(COUNTER_ID)] });
tx.transferObjects([coin], RECIPIENT);Consensus
Sui uses Mysticeti, a DAG-based protocol where validators propose blocks in parallel and commit in three message rounds. Aptos uses its own leader-based BFT line: Jolteon with Quorum Store, and from June 2025 the first stage of Raptr ("Baby Raptr"). Both chains reconfigure validators at epoch boundaries.
Accounts and keys
Both chains support Ed25519, and both have keyless or zk-based login (Sui's is zkLogin). Account models differ, though. Aptos has on-chain account resources with rotatable authentication keys. On Sui, an address is a hash of a public key (or of multisig or zkLogin inputs). Sui has no on-chain account object that stores your state.
Which one to learn
Move skills carry over, but code doesn't port directly. Moving from Aptos to Sui means replacing global storage with objects and passing those objects into functions explicitly. To try Sui, get testnet SUI and run a transaction in the playground.
Sources
- Move on Aptos, Aptos documentation
- Sui Move concepts, Sui documentation
- Consensus, Sui documentation
- Accounts, Aptos documentation
- Baby Raptr lands on mainnet, Aptos Foundation