AXIS Docs

DevelopersSmart contract

Resource limits and costs

What AXIS operations consume under Soroban's per-transaction limits, which limit binds first, and what each operation costs in fees and rent.

Note

Network limits and fee rates on this page are a snapshot of Stellar mainnet in September 2026 (protocol 23 or later). The measurements come from the contract's test host (contract v0.6.0, soroban-sdk 28), not from sampled network transactions. Validators retune network limits through Stellar Limits Proposals (SLPs), so read the live values before relying on them.

Network limits#

Limit per transaction Value What it means for AXIS
Contract events and return value 16,384 B Binds first: 20 fills or about 110 order updates per call
Read-write ledger entries 200 4 per fill plus 5 per trade, so about 48 fills if events did not bind first
Footprint entries 400 Counts every declared entry once, read-write ones included (the Reads column below), so about 97 fills. The read-write cap binds first.
CPU instructions 400,000,000 About 1M to 1.5M per fill, growing with the number of fills, far from binding
Write bytes 132,096 B A 20-fill trade writes about 15.8 KB
Disk-read entries 200 Classic-account makers add two trustline reads each

Per ledger the network allows 1,000 written entries and 286,720 written bytes. Persistent entries are created with a minimum TTL of 2,073,600 ledgers (about 120 days) on mainnet and 120,960 ledgers (7 days) on Testnet, and no entry can live more than 3,110,400 ledgers (about 180 days) ahead.

Fee component Rate
Instructions 7 stroops per 10,000
Write ledger entry 2,500 stroops per entry
Write bytes 875 stroops per KB
Rent 1,000 stroops per KB at the floor, rising toward 10,000 as live state grows
Disk read (classic or archived entries only) 1,563 stroops per entry plus 447 per KB
Contract events 5,000 stroops per KB
Transaction size About 4.4 stroops per byte

Reading live state is free. A key declared read-write pays the write-entry fee even if the call never writes it, so the read-write declarations the JS client adds cost something for unmatched orders too.

Measured operation shapes#

The contract's resource tests (src/tests/lib/resources.rs) measure one call per shape in the test host. Instructions are a lower bound (no Wasm overhead), makers are contract addresses (no classic disk reads), and writes include the 72-byte authorization nonce. "Created" is the size of new persistent entries, the basis of rent.

Operation Reads Writes Write B Event B Instructions Created B
trade Limit, order stored, no fills 13 2 320 268 0.34M 247
trade Fill, 1 order 14 9 1,776 1,028 1.09M 671
trade Fill, 8 orders of 8 makers 42 37 6,956 6,572 7.97M 2,239
trade Fill, 8 orders of 1 maker 21 16 1,776 3,268 1.54M 671
trade Fill, 20 orders of 20 makers 90 85 15,836 16,076 25.4M 4,927
trade Fill, 20 orders plus 3 skipped makers 102 85 15,836 16,328 27.7M 4,927
trade Fill, 21 orders of 21 makers 94 89 16,576 16,868, over the cap 27.2M 5,151
trade Limit, 8 fills plus a stored remainder 46 38 7,204 6,840 8.33M 2,487
trade Fill over 8 unbacked orders, all skipped 38 1 72 672 1.88M 0
update removing 1 order 5 2 72 148 0.09M 0
update changing 1 order 13 2 320 148 0.34M 0
update changing 8 orders 20 9 2,056 1,184 1.62M 0
swap Sell, 2 hops of 1 order 20 14 2,740 2,056 2.62M 1,119
swap Sell, 3 hops of 1 order 26 19 3,704 2,848 3.90M 1,567
swap Sell, 2 hops of 4 orders 44 38 7,180 6,808 10.9M 2,463
crossfill, 8 maker orders 44 38 6,956 6,892 8.59M 2,239
subsidize, new market 12 6 2,524 536 1.21M 464
requote, two price fetches 8 3 1,536 152 0.60M 0

Buy trades and swaps measure like their Sell rows, except that a Buy swap needs fewer instructions because it skips the forward planning pass (2.22M for 2 hops of 1 order). The created bytes of fills are first-time token balances of the test accounts. They include the contract's own balance of each asset a trade buys, an entry that only the first trade buying that asset creates.

Per-fill formulas#

With N fills from distinct makers:

Operation Reads Writes Write bytes Event bytes
trade Fill, N fills plus S skipped makers 4N + 4S + 10 4N + 5 1,036 + 740N 236 + 792N + 84S
trade Fill, N fills of one maker N + 13 N + 8 About 1,780 708 + 320N
trade Limit, N fills plus a remainder 4N + 14 4N + 6 1,284 + 740N 504 + 792N
update removing N orders of one owner N + 4 N + 1 72 148N
update changing N orders selling one asset N + 12 N + 1 72 + 248N 148N
swap, H hops of K orders 8 + H(4K + 2) 4 + H(4K + 1) 812 + 740HK + 224H 472 + 792HK
crossfill, N maker orders 4N + 12 4N + 6 About 1,040 + 740N 556 + 792N

A fill against a distinct maker writes 4 entries: the maker's order, both of the maker's balances and the maker's allowance. Its 792 event bytes are one trade event (about 320 B) and the two transfer events of the legs (about 236 B each). One maker's orders share one transfer per leg, hence 320 B per extra fill in the single-maker row. On top of the fills, every trade forwards what the makers delivered from the contract to the trader in one transfer (236 B), which also writes the contract's balance of the bought asset. Every swap hop writes the contract's balance of the asset it buys, and the swap ends with the same forward plus its own swap event. Other events: new 268 B, mod 148 B, skip 84 B, refresh 152 B, swap 236 B. A crossfill pays the taker order's owner instead of forwarding, and a surplus adds one transfer event to its row.

Which cap binds first#

Cap per transaction Value Fills per trade Orders per update
Contract events 16,384 B 20 About 110
Read-write entries 200 48 199
Footprint entries 400 About 97 About 388 changes or 396 removals
Write bytes 132,096 B About 177 About 530 changes, removals unbounded
Instructions, lower bound 400M About 115 About 700 removals or 2,000 changes

Event bytes bind first, by a factor of about 2.4. The constants routers must respect:

  • MAX_FILLS = 20 per trade. The resource tests pin it: 20 fills from distinct makers fit, 21 do not.
  • The skip budget. 20 fills use 16,076 B, leaving room for 3 skip events (252 B), not 4, so routers budget listed orders, not only fills. Silent skips cost no event bytes.
  • About 110 orders per update, changed or removed. AxisAccount sends batches of 90, while AxisContractClient.update and cancel send the whole list in one transaction.
  • 20 fills per swap across all hops, since the swap event and the forward to the trader add 472 B.
  • 19 maker fills per crossfill, derived from its formula: the taker order's own trade event and the payouts add up to 792 B with a surplus.

The two transfer events per fill (472 B) are 60% of a fill's event budget and come from the token, so the AXIS contract cannot lower them.

Fee estimates#

Execution fees at the snapshot rates, without rent and transaction size:

Operation Execution fee About Plus
trade storing an order, no fills ~6,900 stroops 0.0007 XLM 0.041 XLM order rent
update removing 1 order ~5,900 stroops 0.0006 XLM
update changing 1 order ~6,300 stroops 0.0006 XLM
update changing 8 orders ~31,400 stroops 0.0031 XLM
trade Fill, 1 order ~30,000 stroops 0.003 XLM New balances
trade Fill, 8 orders of 8 makers ~137,000 stroops 0.014 XLM New balances
trade Fill, 20 orders ~324,200 stroops 0.032 XLM New balances
swap, 2 hops of 1 order ~49,500 stroops 0.005 XLM New balances
crossfill, 8 maker orders ~141,500 stroops 0.014 XLM New balances
ExtendFootprintTTL of the contract instance and code (not a contract call) ~0 ~0 XLM Rent of the extension: about 67 XLM from 3 to 30 days on Testnet, see Running a keeper

"New balances" is the rent of first-time token balances, if the call creates any. About two thirds of a multi-fill trade's fee is the write-entry fee (4 entries per maker at 2,500 stroops), and about a quarter the event fee. Not included: transaction size (several KB for a 20-fill envelope), read-write entries declared for orders that end up unmatched, resource safety margins and the inclusion fee, which the JS client bids up to 100,000 stroops by default (see Contract client).

Rent at the floor rate is about 1,667 stroops per byte for 120 days: about 0.041 XLM for an order entry, and about 0.037 XLM for the first token balance of a contract address. Order lifecycle and rent covers who pays which rent.

Requote economics#

Only new entries pay rent. A maker who refreshes quotes by removing orders and creating new ones pays about 0.042 XLM per order each time. update rewrites the same entries in place and pays the execution fee, plus a small TTL extension proportional to the time since the last update.

Refreshing a 40-order ladder Per refresh Per day, every minute Per day, every hour
Remove and recreate About 1.7 XLM About 2,400 XLM About 40 XLM
update in place About 0.016 XLM About 23 XLM About 0.4 XLM

A 40-order update stays well within the event cap and keeps its orders from archiving. See Market making.

Adapting to limit changes#

The contract stores no caps: every loop it runs is bounded by a list the client passes. When an SLP changes a limit, nothing changes on-chain, and clients adapt:

  • Read live limits. Take the per-transaction limits from the network configuration over RPC instead of hard-coding MAX_FILLS, and derive the fill budget from the event cap, the 792 B per fill and the 236 B forward per trade.
  • Chunk large sweeps into several transactions, each racing the book on its own.
  • Expect the effects. A higher event cap raises fills per transaction until the read-write cap takes over near 48, while a higher read-write cap alone changes nothing. A higher rent rate makes new orders dearer but barely affects update, which pays only a small extension.

Concurrency#

Since protocol 23, transactions that write no common ledger entry can execute in parallel.

  • A trade writes the orders it fills, each maker's balances and allowance, the taker's balances and allowance, the taker's authorization nonce, and the AXIS contract's own balance of the asset it buys. It writes no instance entry or counter. Trades that buy the same asset share that contract balance entry and serialize, whatever their pair or makers. Trades that buy different assets from disjoint makers are independent.
  • An update writes only the owner's orders, plus the owner's allowances when it grants approvals.
  • swap and crossfill route tokens through the AXIS contract's own balance in every hop asset or the bought asset, the same entry the trades buying that asset write.
  • requote and subsidize write the market and the price cache only when something changed, so a refresh with nothing new does not serialize with the trades and updates that read them.