Solana Account Model: Technical Guide
Learn how Solana's account model works: data storage, ownership rules, rent exemption, PDAs, and how it enables parallel execution.
This Solana Account Model: Technical Guide explains the runtime fields and access rules that programs rely on, including ownership, executable accounts, token accounts, rent exemption, Program Derived Addresses, Associated Token Accounts, and Cross-Program Invocation.
Implementation details such as rent handling, account size limits, and client APIs can change. Developers should check current Solana documentation and query current network parameters before deploying.
Every transaction on Solana touches an account. Every token you hold, every program you deploy, every NFT you mint: all of it lives in accounts. Before you write a single line of Solana code, understanding how accounts work is not optional background knowledge. It is the prerequisite for everything else.
Think of Solana as a filing cabinet. Each drawer holds a folder, and every folder has a label (its address), contents (its data), a balance stamp, and a department name on the cover indicating which program has authority to edit what is inside. Whether you are a developer migrating from Ethereum, a researcher evaluating Solana's architecture, or a student forming your first mental model of on-chain state management, this guide covers the full picture: account anatomy, account types, ownership rules, rent mechanics, Program Derived Addresses, a side-by-side comparison with Ethereum, and annotated code for building in practice.
Solana Account Model: Technical Guide Overview
The Solana Account Model is the data storage and state management architecture of the Solana blockchain. Every piece of state on Solana, including token balances, program logic, user data, and system configuration, is stored in discrete accounts identified by unique 256-bit public keys. See Solana's official account documentation for the canonical specification.
Every piece of state on Solana lives in an account. Programs do not store their own data; they read and write to accounts passed into them during execution. This single architectural decision separates Solana's design from most other blockchains.
The filing cabinet analogy maps directly to the data structure: the cabinet is the Solana blockchain, the folders are accounts, each folder's label is its public key (the on-chain address), the folder's contents are the data field, the balance stamp is the lamports field, and the department stamp on the cover is the owner field recording which program has write authority. Only the department named on that stamp can alter what is inside.
If you are coming from Ethereum, this distinction matters: Ethereum smart contracts store their own state internally, whereas Solana programs are stateless. The full comparison is in a dedicated section below.
Anatomy of a Solana Account
Every Solana account, whether it stores SOL, program code, or application state, is built from the same five fields.
The Five Fields of Every Solana Account
Every account on Solana holds exactly five fields, each with a distinct function. Understanding these fields in plain terms before examining code makes the technical details far easier to internalize.
lamports: the SOL balance for this account, expressed in Lamports (Solana's smallest denomination, explained in the next section). In the filing cabinet analogy, this is the monetary value stamped on the folder cover.
data: a raw byte array (Vec<u8>) that stores whatever state the owning program needs. For a program account, this field holds compiled BPF bytecode. For a data account, it holds serialized application state. Programs define their own serialization format (commonly Borsh) to read and write structured data to this field. The filing cabinet equivalent is the physical contents inside the folder.
owner: the public key of the program authorized to modify this account's data field. No other program can write to it. This is the department stamp on the folder cover.
executable: a boolean flag. When set to true, the account stores program code and can be executed. When false, the account is a data container.
rent_epoch: a legacy field that previously tracked rent collection timing. This field is being deprecated and carries no operational significance for rent-exempt accounts, which is the production standard.
Each Solana account is identified by a unique 256-bit public key derived from an ed25519 keypair, which serves as both its address and its on-chain identifier. The maximum data field size for a single account is 10 MB as of recent protocol upgrades; verify current limits with Solana's account documentation, as this value has changed over Solana's history.
Lamports: Solana's Smallest Unit
A Lamport is the smallest denomination of SOL: 1 SOL equals 1,000,000,000 Lamports (10⁹). The unit is named after Leslie Lamport, a computer scientist whose work on distributed systems and fault tolerance underlies much of modern distributed computing theory. Lamports exist because all on-chain arithmetic, including rent calculations, transaction fees, and account balances, must use integer arithmetic to avoid floating-point precision errors. Expressing values in Lamports makes every calculation exact.
Is a Solana Account the Same as a Wallet?
A Solana account and a wallet are not the same thing. What you think of as your wallet, the Phantom or Solflare app on your phone, is off-chain software that manages a private key. The on-chain entity is a system account that holds your SOL balance. Your wallet controls a system account; it is not itself an account. Token accounts, program accounts, and data accounts have no wallet equivalent: they are purely on-chain data containers that no consumer wallet application directly represents.
Types of Solana Accounts
Solana accounts fall into four categories, each defined by its owner program and executable flag.
- System Accounts: owned by the System Program; used for SOL storage and user wallets
- Program Accounts: executable accounts storing compiled BPF bytecode
- Data/State Accounts: owned by programs; store application-specific state
- Token Accounts: specialized data accounts owned by the SPL Token Program (with Associated Token Accounts as the canonical subset)
System Accounts
System accounts are owned by the System Program, and user wallets are system accounts. The System Program is Solana's native program responsible for three core operations: creating new accounts (allocating on-chain data space), assigning account ownership (setting the owner field to a specified program), and transferring SOL between accounts. Every new account on Solana starts as a system account owned by the System Program.
The System Program has a well-known address: 11111111111111111111111111111111 (32 ones in base58). See the System Program documentation for its full instruction set. When a developer creates a data account for their program, they invoke the System Program's Create Account instruction, specifying data size, the rent-exempt Lamport deposit, and the new owner program's public key.
Program Accounts
Program accounts store compiled BPF bytecode, not state. The executable flag on these accounts is set to true. Programs are stateless: when a program runs, it receives a list of accounts to read from or write to via the transaction instruction. It does not maintain any internal state between calls. If you are coming from Ethereum, you may know on-chain executable code as smart contracts, but Solana programs work fundamentally differently because they carry no state of their own. Program accounts are owned by the BPF Loader program. Once deployed, a program account is immutable unless an upgrade authority keypair has been designated during deployment.
Data and State Accounts
Data accounts hold the application state that programs read and write during execution. The executable flag on these accounts is false. The data field stores program-defined state serialized with Borsh. Examples include a user's lending position in a DeFi protocol, NFT metadata, or an application counter. The owner program is the only entity that can write to this account's data field, a rule covered in full detail in the ownership section.
Token Accounts and Associated Token Accounts
Token accounts are data accounts owned by the SPL Token Program, each holding a balance of one specific token for one specific wallet. A single wallet address can hold multiple token accounts, one for each token type it holds.
An Associated Token Account (ATA) is the canonical token account for a specific [wallet address, mint address] pair. ATAs are derived deterministically as a Program Derived Address (PDA) using the wallet address and the token mint address as seeds. This ensures each wallet has exactly one "official" account per token type. ATAs are the standard used by wallets like Phantom and Solflare, by exchanges, and by protocols: when you receive a token in your wallet UI, it goes to your ATA for that token.
If an ATA does not exist for a given [wallet, mint] pair, it must be created before tokens can be received, and creation costs a rent-exempt Lamport deposit. This is why some transactions include a small "account creation fee" in wallet UIs. For the full ATA specification, see the SPL Associated Token Account documentation. An ATA is a token account, but not every token account is an ATA, and the distinction matters when debugging token-related programs.
Account Ownership: How Solana Controls Data Access
Account ownership in Solana is a write-authority mechanism, not an asset ownership concept.
The Ownership Rule
Only the account's owner program can modify its data field. No other program can write to it, regardless of what the user authorizes at the transaction level. The owner field in AccountInfo stores the public key of the program that holds this authority. Non-owner programs can read the data field freely, but writing requires being the designated owner.
The System Program assigns ownership during account creation. When a developer creates a data account for their program, the Create Account instruction sets the owner field to their program's public key. Ownership can be re-assigned, but only by the current owner program using the Assign instruction. No external party can transfer ownership unilaterally.
Owner vs. Authority: A Critical Distinction
Owner and authority are two different concepts in Solana account management. The owner is the program recorded in the account's owner field, meaning the program that can write to the data field. The authority (or signer) is the keypair that can sign transactions for the account.
Consider a token account as an example: your wallet's private key signs the transaction (you are the authority), but the SPL Token Program is the owner of your token account and is the only entity that can modify your token balance in the data field. You can authorize a transaction that moves tokens, but the actual write to the data field is performed by the Token Program, not by you directly. Conflating these two concepts produces most account ownership debugging errors for developers new to Solana.
Ownership in Practice: A DEX Example
A DEX program can only write to accounts it owns directly. To transfer tokens from a user's token account (owned by the SPL Token Program, not the DEX), the DEX cannot write to that account directly. Programs can call other programs within the same transaction, a pattern called Cross-Program Invocation (CPI), allowing a DEX to instruct the Token Program to move tokens on a user's behalf. The DEX sends a CPI to the Token Program, providing the user's signed authorization, and the Token Program performs the write to the user's token account data field. This is how the program ownership model extends to inter-program interactions. For a full walkthrough, see the Cross-Program Invocation (CPI) guide for Solana developers.
Account Rent and Rent Exemption
Solana rent is a storage cost mechanism, not a recurring fee.
What Is Rent?
Rent is Solana's mechanism for pricing on-chain storage. Every account must maintain a minimum SOL balance proportional to its data size to remain active on-chain. The correction most competitor content misses: rent is not a recurring fee in practice. The production standard is rent exemption, where depositing enough SOL upfront to cover approximately two years of storage makes an account permanently exempt from any rent deduction. The overwhelming majority of deployed accounts operate under rent exemption.
Rent Exemption: The Practical Standard
Rent exemption is the production standard for all deployed Solana accounts. The minimum balance for rent exemption is approximately 6,960 Lamports multiplied by the account's data size in bytes, plus a base amount of approximately 890,880 Lamports for a zero-byte account.
A worked example: a 100-byte data account requires approximately 890,880 + (6,960 × 100) = 1,586,880 Lamports, or roughly 0.00159 SOL. These figures are approximate and subject to change. Verify current values with the Solana CLI command solana rent <bytes> or the Solana rent documentation. A proposed change to convert rent to a transaction fee model has not been activated as of this writing; consult current documentation for the latest protocol status.
What Happens When an Account Runs Out of SOL?
Current account creation generally requires rent-exempt funding. Developers should query current RPC requirements instead of relying on legacy rent-collection behavior. This is the behavior that prompts concern about accounts being "deleted."
Rent-exempt accounts are never automatically closed by the runtime. Production accounts are always funded to the rent-exempt threshold, so garbage collection does not affect them. Closing accounts intentionally is a separate, deliberate pattern: programs can close data accounts to reclaim the Lamport deposit. In a DeFi protocol, for example, closing a lending position releases the SOL that funded that position's data account back to the user. This is a common protocol design pattern, not an involuntary deletion.
Program Derived Addresses (PDAs) Explained
Program Derived Addresses solve a specific problem: how a program can control an account without anyone holding the corresponding private key.
What Is a Program Derived Address?
A Program Derived Address (PDA) is a deterministically generated account address derived from a program ID and one or more seed values using SHA-256 hashing. PDAs are intentionally placed off the ed25519 elliptic curve, meaning they have no corresponding private key. Only the owning program can sign transactions for accounts at PDA addresses. See Solana's PDA documentation for the full specification.
All regular Solana account addresses sit on the ed25519 elliptic curve. PDAs are intentionally placed off that curve. The off-curve property is not a bug; it is the design mechanism that makes a private key mathematically impossible. No human, no hardware wallet, and no key management system can produce the private key for a PDA because no such key exists on the curve.
Why PDAs Matter: Program-Controlled Custody
The consequence of having no private key is that only the owning program can authorize transactions for a PDA. This enables trustless program-controlled custody: the program holds authority over the account without relying on any human to safeguard a private key.
Compare this to regular keypair accounts, where whoever holds the private key controls the account. If the key is lost, access is gone. If the key is stolen, the account is compromised. PDAs remove this dependency entirely. The program's logic is the custodian, auditable code rather than a person.
Three Real-World PDA Use Cases
PDAs appear in three recurring patterns across Solana programs.
DEX escrow accounts: a decentralized exchange program holds tokens in a PDA until both sides of a swap meet the required conditions. No trusted intermediary holds a private key to the escrow. The program's logic controls release, and no participant can drain the funds outside the protocol's rules.
No individual can "rug pull" the mint authority of an NFT collection. NFT mint authority works by having Metaplex programs control minting via a PDA derived from the mint address. Because no private key exists for this PDA, the collection's minting rules are enforced by program code alone after deployment.
How does a program store per-user data without maintaining a centralized index? Per-user state storage uses a unique PDA derived from [program_id, user_pubkey]. This produces a deterministic, user-specific account address for storing that user's game score, lending position, or staking record. The program always knows where to find each user's data.
The functions findProgramAddress() and createProgramAddressSync() locate valid off-curve addresses by testing candidate addresses with an incrementing bump seed until one falls off the curve.
When Should You Use a PDA?
Use a PDA whenever your program needs to control an account without relying on a human's private key. If the account authority should be program logic rather than a person, use a PDA. This rule covers escrow accounts, protocol vaults, mint authorities, and any state that the program itself must own and manage across multiple users.
Solana vs. Ethereum: How the Account Models Compare
The core difference between Solana's and Ethereum's account models is where state lives.
In Ethereum, smart contracts are stateful: they store their own state internally alongside their code. A Solidity contract keeps its own mappings and state variables within contract storage, managed by the Ethereum Virtual Machine (EVM). In Solana, programs are stateless; all state lives in external accounts that programs read and write during execution. Where Ethereum runs programs in the EVM, Solana uses a BPF-based runtime that executes programs against accounts declared upfront in the transaction.
| Dimension | Solana | Ethereum |
|---|---|---|
| State storage location | External data accounts | Internal contract storage |
| Code/data separation | Enforced: programs are stateless | Not enforced: contracts store own state |
| Account creation | Explicit: developer specifies size, lamports, owner | Implicit: EVM manages storage internally |
| Storage cost model | Rent exemption: SOL deposit proportional to data size | Gas fees: cost per SSTORE operation |
| Execution model | Parallel (Sealevel): non-overlapping accounts run simultaneously | Sequential (EVM): one transaction at a time |
| Developer complexity | Higher: accounts, ownership, rent managed explicitly | Lower: state management handled by EVM |
The tradeoffs run in both directions. Ethereum's stateful model carries a genuine developer experience advantage: simpler mental model, no explicit account management, lower cognitive overhead for many use cases. A developer can write and deploy an ERC-20 contract without thinking about data account sizing, rent-exempt deposits, or PDA derivation.
Solana's stateless model trades that simplicity for execution parallelism and separation of concerns. The account declarations required by every transaction are the input to Sealevel's scheduling algorithm, which executes non-conflicting transactions simultaneously. Other Layer-1 blockchains such as Aptos and Sui adopt their own variants of resource-based state separation, each with different tradeoff profiles. Neither Ethereum's approach nor Solana's is categorically superior; they reflect different design priorities for different workloads.
Why This Architecture Matters: Sealevel and Parallel Execution
Stateless programs are not a design constraint; they are the mechanism that makes parallel execution possible.
The causal chain from account model design to performance works as follows. First, Solana programs are stateless. Second, because programs carry no state, every transaction must declare all accounts it will access, both reads and writes, before execution begins. Third, Solana's parallel execution engine, Sealevel, analyzes these account access lists before scheduling. Fourth, transactions that access non-overlapping sets of accounts have no data dependencies on each other and can execute simultaneously across multiple processor cores. Fifth, the result is a network capable of processing tens of thousands of transactions per second.
Anatoly Yakovenko designed Solana's architecture with parallel transaction processing as an explicit goal, and separating program logic from account state is what makes that possible. The account model works in concert with Solana's other architectural innovations, including Proof of History (PoH), Solana's cryptographic clock mechanism. To understand how PoH contributes to this throughput, see the how Proof of History works in Solana's architecture explainer.
Building with Accounts: Developer Implementation
Every account a Solana program works with must be created, funded, and assigned to an owner before the program can read or write to it.
Creating an Account with the System Program
Solana programs are written in Rust, a systems programming language, and compiled to BPF bytecode before deployment. Creating an account on Solana follows these steps, each corresponding to a parameter in the System Program's Create Account instruction:
from_pubkey: identify the account funding the creation (the payer)new_account_pubkey: specify the address of the new accountlamports: calculate the rent-exempt balance amount based on data sizespace: set the data size in bytes to allocate for the accountowner: specify the program public key that will own and write to this account
// Create a new data account using the System Program
let create_account_ix = system_instruction::create_account(
&payer.pubkey(), // from_pubkey: who funds this account
&new_account.pubkey(), // new_account_pubkey: the account's address
rent_exempt_balance, // lamports: enough to be rent-exempt
data_size as u64, // space: bytes allocated for account data
&program_id, // owner: the program that controls this account
);This instruction establishes account ownership. After it executes, only the program at program_id can write to this account's data field.
Using the Anchor Framework
Many Solana programs are built with the Anchor framework, which provides structured macros for defining account constraints and program instructions. See the Anchor documentation for the full framework reference.
// Anchor: define account constraints using the #[derive(Accounts)] macro
#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(
init, // create this account if it doesn't exist
payer = user, // user pays the rent-exempt deposit
space = 8 + MyData::LEN, // 8-byte discriminator + data size
)]
pub my_account: Account<'info, MyData>, // the new data account
#[account(mut)]
pub user: Signer<'info>, // the transaction signer and payer
pub system_program: Program<'info, System>, // required for account creation
}Anchor handles account validation boilerplate automatically, verifying ownership and signer status before your instruction logic runs. Understanding the underlying account model remains necessary when debugging ownership errors or designing PDA structures, because Anchor's macros are abstractions over the same mechanics described throughout this article.
Related Solana Architecture Resources
Developers looking for a shorter implementation path can use the developer-focused account model guide; token program conventions are covered in the Solana Program Library overview. The SOL price page and SOL/USDT spot market concern market access, not account ownership or program authority.
FAQ: Solana Account Model: Technical Guide
What is an account in Solana?
A Solana account is an on-chain data container identified by a unique 256-bit public key. Every account stores a SOL balance in Lamports, a data field (a byte array holding program state or bytecode), an owner field (the public key of the program authorized to modify the data), and an executable flag indicating whether the account stores program code.
How does Solana's account model differ from Ethereum's?
In Ethereum, smart contracts store their own state internally alongside their code. In Solana, programs are stateless; all state lives in external accounts that programs read and write during execution. This separation allows Solana's Sealevel runtime to detect non-overlapping account access patterns and execute multiple transactions simultaneously, enabling parallel processing at scale.
What is rent in Solana?
All production Solana accounts are funded to the rent-exemption threshold, making them permanently exempt from storage charges. Rent is the underlying mechanism: accounts must maintain a minimum SOL balance proportional to their data size to stay active on-chain. Rent-exempt accounts, those funded above the threshold, are never automatically closed by the runtime.
What is a Program Derived Address (PDA)?
A Program Derived Address (PDA) is a deterministically generated account address derived from a program ID and seed values using SHA-256 hashing. PDAs fall off the ed25519 elliptic curve, so they have no corresponding private key. Only the owning program can sign transactions for accounts at PDA addresses, enabling trustless program-controlled custody for escrow accounts, mint authorities, and per-user state storage.
Can Solana accounts be deleted?
Current account creation generally requires rent-exempt funding. Developers should query current RPC requirements instead of relying on legacy rent-collection behavior. Properly deployed production accounts are always funded to the rent-exempt threshold and are never automatically deleted. Programs can also intentionally close accounts to reclaim the SOL deposit, a common pattern in DeFi protocols.
What are Lamports?
Lamports are the smallest denomination of SOL on the Solana blockchain: 1 SOL equals 1,000,000,000 Lamports (10⁹). Named after Leslie Lamport, a distributed computing pioneer, Lamports are used for all SOL balances, transaction fees, and rent calculations on-chain. Denominating amounts in Lamports avoids floating-point precision errors that would arise from using fractional SOL values in on-chain arithmetic.
What is the System Program in Solana?
The System Program is Solana's native program responsible for three core operations: creating new accounts (allocating on-chain data space), assigning account ownership (setting the owner field to a specified program), and transferring SOL between system accounts. Every new Solana account starts as a system account. Developers invoke the System Program's Create Account instruction to provision data accounts for their programs.
How many types of accounts are there in Solana?
There are three primary types of Solana accounts: (1) System Accounts, owned by the System Program and used for SOL balances and user wallets; (2) Program Accounts, executable accounts storing compiled BPF bytecode; (3) Data/State Accounts, owned by programs and storing application-specific state. Token Accounts are a specialized subset of data accounts owned by the SPL Token Program.
Key Takeaways and Next Steps
The Solana account model requires more upfront thinking than Ethereum's stateful model, but that cognitive investment is what makes parallel execution possible.
- Every piece of state on Solana lives in an account; programs read and write to accounts passed during execution, not internal storage
- Every account has five fields: lamports, data, owner, executable, and the legacy rent_epoch
- Only the owner program can modify an account's data field; this is Solana's primary access control mechanism
- Production accounts are funded to the rent-exempt threshold and are never automatically garbage-collected by the runtime
- Program Derived Addresses enable trustless program-controlled custody by using off-curve addresses that have no private key
- Solana's Sealevel runtime parallelizes transaction execution by analyzing declared account access lists across non-conflicting transactions
Ready to build on this foundation? Continue with:
- How Solana programs work: a developer guide to stateless execution
- Anchor framework guide for building Solana programs
- Cross-Program Invocation (CPI) explained: how Solana programs call each other
- How Proof of History works in Solana's architecture
For the latest protocol specifications on account sizes, rent calculations, and runtime behavior, consult the Solana official account documentation directly.