Market Capacity#
Trader-ledger sizing, seat tiers, and the ledger-allocation prelude.
What capacity is#
Each market has a trader_ledger PDA with a fixed number of seats — the
maximum number of distinct traders who can hold a position. The seat count is
chosen at creation via the num_seats field of CreateMarket and cannot be
changed afterward.
Seat tiers#
num_seats must be one of nine on-chain values (TRADER_LEDGER_SEAT_OPTIONS):
| Tier (UI) | num_seats | Ledger size (bytes) | Refundable rent (≈) |
|---|---|---|---|
| Small (default) | 128 | 9,272 | ~0.065 SOL |
| Standard | 1,025 | 73,856 | ~0.515 SOL |
| — | 1,153 | 83,072 | ~0.58 SOL |
| — | 2,049 | 147,584 | ~1.03 SOL |
| — | 2,177 | 156,800 | ~1.09 SOL |
| Large | 4,097 | 295,040 | ~2.054 SOL |
| — | 4,225 | 304,256 | ~2.11 SOL |
| — | 8,193 | 589,952 | ~4.10 SOL |
| Max | 8,321 | 599,168 | ~4.171 SOL |
Ledger size = 56 + num_seats * 72 bytes. Rent ≈ (128 + size) * 3480 * 2
lamports (Solana rent-exempt minimum). Web/mobile expose the three named tiers:
Small, Standard, and Large.
Single-transaction helpers cap num_seats at the packet-safe 4,225 upper
bound. Split-capable flows can send allocation preludes across multiple
transactions before submitting CreateMarket last. The Pyth Pull
transaction-builder path supports every on-chain seat count, including 8,193
and 8,321, and every deep-orderbook tier (64 through 4,096).
Launch seat policy#
For first-party launch catalogs, choose seat tiers from expected audience size instead of defaulting every market to maximum capacity:
| Catalog tier | Default num_seats | Use when |
|---|---|---|
| Small | 128 | Experimental feeds, long-tail markets, first run of a new cadence |
| Standard | 1,025 | Featured recurring markets with expected organic traffic |
| Large | 4,097 | Flagship markets with staged liquidity, marketing, or partner traffic |
Do not use 8,193 or 8,321 for first-party launch markets without explicit
operator signoff covering rent float, packet splitting, occupancy monitoring,
and close/reclaim load. Those tiers remain available for permissionless or
special-purpose creation flows, but they are not default product tiers.
Monitor trader-ledger occupancy by market and alert before the ledger reaches 90% occupied. A market whose ledger fills can still make forward progress through competitive eviction and settlement, but the UX degrades: a new trader may fail to acquire a seat until an inactive or expired slot can be reclaimed. User-facing surfaces should describe this as market capacity being full, not as lost funds. Existing balances remain governed by the normal settlement, withdrawal, cancel, reduce, reclaim, and redemption paths.
Refundable rent#
The creator pre-pays the ledger rent. When the market is closed after
resolution (CloseMarket), the trader_ledger rent (along with the market,
orderbook, and vault rent) is returned to the creator.
Allocation preludes#
Solana caps account growth at MAX_PERMITTED_DATA_INCREASE (10,240 bytes) per
top-level instruction, so a ledger larger than ~141 seats cannot be allocated
in one shot. Before CreateMarket, callers must invoke
EnsureTraderLedgerSpace (0x2E) ceil(target_size / 10240) times to grow the
PDA in chunks, where target_size = 56 + num_seats * 72. The instruction is
idempotent and a no-op once the PDA is at target size. CreateMarket rejects a
ledger that is not fully pre-grown.
Deep orderbooks use the same pattern. Callers must invoke
EnsureDeepOrderbookSpace (0x33) ceil(deep_orderbook_size / 10240) times,
where deep_orderbook_size = 192 + capacity * 224 and capacity is one of
64, 128, 256, 512, 1024, 2048, 4096. Large tiers can require many prelude
instructions, so split them across transactions before the final CreateMarket.
The TypeScript (@seesaw/core), Rust (sdk-rust), and Python (sdk-python)
SDKs bundle these preludes automatically — see the
SDK create-market example.
CU launch-tier evidence#
Before a release-candidate signoff can raise the first-party launch tier above
the documented launch policy, operators must attach a STRAT-4 CU launch-tier
artifact and point SEESAW_CU_LAUNCH_TIER_EVIDENCE_FILE at it when running
RELEASE_CANDIDATE=1 scripts/production-readiness-check.sh.
The measurement command must be the release BPF CU regression gate:
BPF_OUT_DIR=target/deploy cargo test --release --test cu_regression --features test-sbf
The artifact is JSON with this shape:
{
"releaseCommit": "0123456789abcdef0123456789abcdef01234567",
"generatedAt": "2026-07-04T00:00:00Z",
"command": "BPF_OUT_DIR=target/deploy cargo test --release --test cu_regression --features test-sbf",
"maxLaunchDeepOrderbookCapacity": 1024,
"deepOrderbookTierMeasurements": [
{ "capacity": 64, "measuredCu": 123456, "sampleCount": 3, "status": "pass" },
{ "capacity": 128, "measuredCu": 123456, "sampleCount": 3, "status": "pass" },
{ "capacity": 256, "measuredCu": 123456, "sampleCount": 3, "status": "pass" },
{ "capacity": 512, "measuredCu": 123456, "sampleCount": 3, "status": "pass" },
{ "capacity": 1024, "measuredCu": 123456, "sampleCount": 3, "status": "pass" },
{ "capacity": 2048, "measuredCu": 123456, "sampleCount": 3, "status": "pass" },
{ "capacity": 4096, "measuredCu": 123456, "sampleCount": 3, "status": "pass" }
]
}
Validate the artifact offline before release signoff:
node scripts/security/validate_cu_launch_tier_evidence.mjs <artifact.json>