How many addresses fit into a Cell?

Published: (January 16, 2026 at 01:15 PM EST)
2 min read
Source: Dev.to

Source: Dev.to

Introduction

While developing a smart contract I needed to store several addresses in persistent storage.
Because TON storage is measured in bits and cells, and both storage and message‑forwarding cost gas, knowing exactly how many addresses fit into a single cell is important. To answer this we must look at how addresses are defined and serialized at the TL‑B level.

TL‑B address definitions

addr_none$00 = MsgAddressExt;

addr_extern$01 len:(## 9) external_address:(bits len)
    = MsgAddressExt;

anycast_info$_ depth:(#= 1 }
    rewrite_pfx:(bits depth) = Anycast;

addr_std$10 anycast:(Maybe Anycast)
    workchain_id:int8 address:bits256 = MsgAddressInt;

addr_var$11 anycast:(Maybe Anycast) addr_len:(## 9)
    workchain_id:int32 address:(bits addr_len) = MsgAddressInt;

_ _:MsgAddressInt = MsgAddress;
_ _:MsgAddressExt = MsgAddress;

There are exactly four address constructors:

  • addr_none
  • addr_extern
  • addr_std
  • addr_var

The following sections calculate the exact bit sizes for each constructor based strictly on the TL‑B definitions.

Address constructors size analysis

addr_none

  • Constructor tag $002 bits

Exact size: 2 bits.

addr_extern

  • Constructor tag $01 → 2 bits
  • len:(## 9) → 9 bits (the length field)
  • external_address:(bits len)len bits, where len ∈ [0, 511]

Exact size formula: 2 + 9 + len = 11 + len bits

  • Minimum size (len = 0): 11 bits
  • Maximum size (len = 511): 522 bits

addr_std

  • Constructor tag $10 → 2 bits
  • anycast:(Maybe Anycast) → presence flag 1 bit
    • If present: depth:(#<=30) → 5 bits, rewrite_pfx:(bits depth)depth bits (depth ∈ [1, 30])
  • workchain_id:int8 → 8 bits
  • address:bits256 → 256 bits

Exact size formula:

2 + 1 + (anycast ? (5 + depth) : 0) + 8 + 256
  • Without anycast (presence = 0): 267 bits
  • With anycast, maximum depth = 30: 302 bits

addr_var

  • Constructor tag $11 → 2 bits
  • anycast:(Maybe Anycast) → presence flag 1 bit
    • If present: depth:(#<=30) → 5 bits, rewrite_pfx:(bits depth)depth bits
  • addr_len:(## 9) → 9 bits (length of the address field)
  • workchain_id:int32 → 32 bits
  • address:(bits addr_len)addr_len bits, where addr_len ∈ [0, 511]

Exact size formula:

2 + 1 + (anycast ? (5 + depth) : 0) + 9 + 32 + addr_len
  • Without anycast, maximum address length (addr_len = 511): 555 bits
  • With anycast, maximum depth = 30 and maximum address length: 590 bits

Practical considerations (TVM ≥ 10)

  • Since TVM version 10, anycast addresses are not allowed as message destinations, in account addresses, nor are they supported by address‑parsing and rewrite instructions. Consequently, the Maybe Anycast flag is always 0, and the anycast payload never appears.
  • addr_var is defined for future extensions but is not used in real contracts today.
  • Currently active workchains (masterchain and basechain) use addr_std with:
    • 256‑bit account IDs
    • Small workchain IDs

Real‑world address size on mainnet

  • Anycast is unused.
  • addr_var is unused.
  • All internal addresses are addr_std.

Therefore the practical internal address size is fixed at 267 bits.

Knowing this exact value is essential when designing compact storage layouts, estimating gas costs, and deciding how many addresses can fit into a single cell.

Back to Blog

Related posts

Read more »