What is Celestia Fibre?

Celestia Fibre is a second way to publish blobs on Celestia, added in celestia-app v10: the blob's bytes are stored and served by Fibre servers that the validators run, and do not go into Celestia blocks. The chain only records that the blob was published, who endorsed it, and that it was paid for.

This page explains how it works; for how this site derives its numbers, see Methodology.

What Fibre is

A second blob path: the data stays off-block; payment and signatures go on chain

The regular blob path (MsgPayForBlobs) stays as it is. Publishers choose a path for each blob. On this network, Fibre is active from block 15,116,659.

Why a second path

Regular blobs are stored inside the block itself, so every byte competes for block space. Fibre keeps the payload outside the block and puts only a commitment to it on chain. That allows more data to be published without making blocks larger.

What goes on chain

  • A MsgPayForFibre transaction (a PFF). It carries the publisher's payment promise and the signatures of the validators that stored and checked their part of the blob.
  • A small blob in the publisher's namespace, created by the chain. It holds the Fibre blob version, the 32-byte commitment, and the address of the account that submitted the PFF.
  • The payment, taken from the publisher's prepaid escrow account.

The blob's data itself never enters a block.

Fibre is not long-term storage. Fibre servers keep their part of a blob for at least 4 hours after the payment promise was created (the shard_retention parameter), or until the promise expires if that is later. On this network that is 4 hours. This is how the Fibre server software behaves; the chain does not enforce it. After that the rows may be deleted. Publishers and readers should keep their own copy.

Fibre compared with regular blobs

PropertyRegular blobsFibre
Where the data livesIn the blockOn validators' Fibre servers, cut into rows. Only a commitment goes in the block
Largest blobThe whole transaction must fit in 8 MiB134,217,723 bytes of data (128 MiB with the 5-byte header)
How it is paidTransaction fee. The blob adds 8 gas for every byte of the 512-byte shares it fills, padding included, on top of the transaction's other gas. The fee is the gas times the gas priceA fixed amount per blob, by its billed size (formula), taken from a prepaid escrow. The transaction fee is paid separately
What shows the data was availableConsensus on the block, and light nodes sampling itSignatures from validators holding at least 2/3 of the stake, each given after storing and checking its rows
Light-node samplingLight nodes sample the block, which holds the blobFor this blob, the block holds only the PFF and the commitment blob, so that is all light nodes can sample. The blob's data is not in it
How it is fetchedBy height, namespace and commitmentBy its 33-byte blob ID
Sources

CIP-51; celestia-app v10.4.0: specs/src/fibre_encoding.md, x/fibre/README.md, fibre/protocol_params.go, fibre/blob.go, fibre/blob_id.go, fibre/validator/signature_set.go, x/blob/keeper/keeper.go and x/blob/types/payforblob.go (regular blob gas), pkg/appconsts/app_consts.go, specs/src/parameters_v10.md; Celestia docs: Fibre guide (written for Mocha), Data availability FAQ; live shard_retention from this site's parameters.

How a blob is split into rows

Each blob is cut into 4,096 rows plus 12,288 parity rows; any 4,096 rebuild it

Before upload, the blob is cut into 4,096 equal slices called rows. Every blob has 4,096 data rows, whatever its size; a bigger blob has wider rows. The encoder then computes 12,288 parity rows from them, so each blob becomes 16,384 rows of the same width. Any 4,096 of the 16,384 rows are enough to rebuild the blob.

4,096 data rows12,288 parity rows
Each stripe stands for 256 rows. Outlined: one example of 4,096 rows (any mix of data and parity) that is enough to rebuild the blob.
BlobWidth of each rowBilled size (4,096 rows)
300 bytes64 bytes, the minimum256 KiB, mostly padding
10 MiB2,624 bytes10,747,904 bytes
134,217,723 bytes (largest)32 KiB128 MiB

The width is the blob plus its 5-byte header, divided by 4,096 and rounded up to a multiple of 64 bytes. That rounding is why the smallest billed size is 4,096 × 64 bytes = 256 KiB.

The rows form a grid only while the blob is encoded: the parity rows are computed down the columns of that grid. After that, each row is a separate numbered piece. It comes with a proof that it belongs to the blob's commitment, so it can be checked on its own. Validators are assigned rows roughly in proportion to their stake (exact rule under Endorsements and security), store them, and serve them to readers, who collect any 4,096 different rows.

See real rows of a 300-byte blob

Output of celestia-app's own encoder for a 300-byte sample text. Each row is 64 bytes, shown as hex with the readable characters on the right.

Row 0: 5-byte header (blob version 0, data size 300), then the text
00  00 00 00 01 2c 46 69 62 72 65 20 6b 65 65 70 73  |....,Fibre keeps|
10  20 62 6c 6f 62 20 64 61 74 61 20 6f 6e 20 76 61  | blob data on va|
20  6c 69 64 61 74 6f 72 73 2e 20 46 69 62 72 65 20  |lidators. Fibre |
30  6b 65 65 70 73 20 62 6c 6f 62 20 64 61 74 61 20  |keeps blob data |
Row 4: the text ends, the rest of the row is zero padding
00  64 61 74 6f 72 73 2e 20 46 69 62 72 65 20 6b 65  |dators. Fibre ke|
10  65 70 73 20 62 6c 6f 62 20 64 61 74 61 20 6f 6e  |eps blob data on|
20  20 76 61 6c 69 64 61 74 6f 72 73 2e 20 46 69 62  | validators. Fib|
30  72 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |r...............|
Row 5: rows 5 to 4,095 are all padding
00  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|
10  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|
20  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|
30  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|
Row 4,096: the first parity row, computed from all data rows
00  46 6d e8 61 c5 0f ce 6a a9 8a 36 4e fb b3 6c 8d  |Fm.a...j..6N..l.|
10  e8 4c c1 61 b1 12 a4 17 92 d0 31 03 22 6f 47 c5  |.L.a......1."oG.|
20  94 62 2c 6a c1 4c 04 95 a6 02 18 d8 41 0e d8 c6  |.b,j.L......A...|
30  0a 79 5f b7 c7 47 5e 25 e9 e6 85 7a 95 74 ed 50  |.y_..G^%...z.t.P|
Sources

celestia-app v10.4.0: fibre/protocol_params.go (row count, row width), fibre/blob.go (header), pkg/rsema1d/README.md and pkg/rsema1d/SPEC.md (parity computed down columns, any 4,096 rows rebuild, per-row proofs), specs/src/fibre_client.md (assignment, download). Example rows produced with fibre.NewBlob from that version.

Blob lifecycle

Fund escrow → promise → upload → validators sign → PFF settles → retrieve

A Fibre blob goes through these steps, from funding to retrieval.

  1. 1Fund escrow
  2. 2Encode and promise
  3. 3Upload rows
  4. 4Check, store, sign
  5. 5Settle at ≥ 2/3 stake
  6. 6Retrieve any 4,096 rows
  1. Fund the escrow. The publisher deposits TIA into a Fibre escrow account (MsgDepositToEscrow). Fibre payments are taken from this account, not from the publisher's regular balance. A withdrawal is paid out only 1 day after it is requested, so the publisher cannot promise a payment and then empty the escrow before it settles.
  2. Encode and promise. The publisher's client cuts the blob into rows, adds the parity rows, and computes a 32-byte commitment to them. It signs a payment promise naming the chain, the namespace, the billed size, the commitment, the creation time and the height of the current validator set.
  3. Upload. Each validator is assigned a set of rows, roughly in proportion to its stake. The assignment follows from the commitment and the validator set at the promise's height. The client sends each validator its rows, with proofs and the promise, to the Fibre server host the validator registered on chain.
  4. Check, store, sign. Each Fibre server checks the promise (owner signature, freshness, and that the escrow covers the payment), checks that it received exactly its assigned rows, and checks each row against the commitment. It stores the rows first, then signs the promise.
  5. Settle. Once the signatures cover at least 2/3 of the stake, a MsgPayForFibre carrying the promise and the signatures is submitted. Anyone may submit it. The Fibre client's Put helper submits it itself; the x/fibre README notes it is typically one of the endorsing validators. It must be included less than 1 hour after the promise was created, and at most 1,000 blocks after the promise's height. The chain then takes the payment from the escrow, adds the small commitment blob to the block, and records the promise as processed, so it cannot be paid twice.

    If it never settles. When 1 hour has passed without a PFF, anyone can submit MsgPaymentPromiseTimeout, until 1 day after the promise was created. The escrow is charged the same amount, but no commitment blob is added. This is how a promise that was handed out but never settled still gets paid for, if someone submits the timeout in that window.

  6. Retrieve. Anyone with the 33-byte blob ID can download the blob. The client asks validators for their rows in a random order weighted by stake, so higher-stake validators tend to be tried first, and checks each row against the commitment. Any 4,096 rows are enough to rebuild the blob. This only works while Fibre servers still hold the rows: on this network at least 4 hours after the promise was created.

Payments, settled or timed out, go to the fee collector and are distributed to validators and delegators like regular transaction fees. The amount does not depend on which validators signed, and it is not sent to them directly.

See it live: the latest blobs (each blob page shows which validators signed, by stake), validators' signing records, and what a blob costs.

Sources

CIP-51; celestia-app v10.4.0: specs/src/fibre_client.md (upload and download flows), specs/src/fibre_server.md (UploadShard flow), specs/src/fibre_module.md, x/fibre/README.md, x/fibre/keeper/keeper.go (promise validation), x/fibre/keeper/msg_server.go (settlement, timeout, fee collector), fibre/validator/set.go (download order), x/valaddr/README.md, pkg/rsema1d/README.md; live parameters from this site.

Endorsements and security

A blob settles at 2/3 of stake; what a signature proves and what it does not

What a validator signature means

CIP-51: “A validator signature means the validator accepted and stored its assigned shard.” Before signing, the validator's Fibre server has checked that:

  • the payment promise is signed by the escrow owner, is still fresh, and the escrow can pay it;
  • the rows it received are exactly the rows assigned to it;
  • each row belongs to the blob's commitment.

What a signature does not guarantee

  • That the data will be served later. CIP-51: if too many assigned validators are “unavailable, pruning early, misconfigured, or unreachable, readers may fail to reconstruct the blob even though the on-chain commitment exists.”
  • That the data is kept beyond the retention period. Fibre servers may delete rows once shard_retention has passed and the promise has expired (see Parameters).
  • That the blob was encoded correctly. A publisher could build the commitment from wrongly encoded rows that still pass each row's check. Readers can detect and skip such rows, but, as the client specification notes, this “does not prevent a bad commitment from being accepted on-chain if enough validators sign it”.
  • That the content is meaningful. CIP-51: “The Fibre commitment binds bytes, not application meaning.” Applications check namespace, signer and validity themselves.

The two thresholds

ThresholdWhere it is usedRule in the code
2/3 of stakeSettling a PFFSigned stake must reach total stake × 2 / 3, rounded down. Exactly two thirds is enough. Stake is taken from the validator set at the promise's height
1/3 of stakeAssigning rowsA validator gets ⌈4,096 × 3 × its stake ÷ total stake⌉ rows, raised to a minimum and capped at 4,096. So any group of validators with at least 1/3 of the stake is assigned at least 4,096 rows, the number needed to rebuild a blob

Rows are dealt out from a shuffled list, and once the list runs out it starts again from the top. A row can therefore be assigned to more than one validator, so the number of rows assigned to a group is not always the number of different rows it holds.

Who checks the signatures

The chain checks the signatures when it accepts a PFF, but only until the 2/3 threshold is reached; later signatures in the same PFF are not checked on chain. This site checks every signature itself and counts only valid ones as endorsements (see Methodology).

Sources

CIP-51 (Security Considerations); celestia-app v10.4.0: specs/src/fibre_server.md, specs/src/fibre_client.md (download flow, assignment), fibre/validator/signature_set.go (threshold), fibre/validator/set.go (assignment), x/fibre/keeper/msg_server.go (validateValidatorSignatures), fibre/protocol_params.go.

Parameters

Current x/fibre values on this network; rows are kept for at least 4 hours

These x/fibre parameters can be changed by governance. The values below are the current ones on this network, in effect from block 15,116,659. Past values are on the Parameters page.

ParameterCurrent valueMeaningAllowed range
shard_retention4 hoursMinimum time a Fibre server keeps a blob's rows after the payment promise was created. Rows are also kept until the promise expires, if that is later10 minutes to 7 days
payment_promise_timeout1 hourHow long a promise can be settled with a PFF. After it, the promise can only be charged as a timeout10 minutes to 12 hours
payment_promise_height_window1,000 blocksHow many blocks after the promise's height a PFF can still be includedAt least 1 block
withdrawal_delay1 dayTime between an escrow withdrawal request and its payout. It is also the maximum age of a payment promise: older promises can no longer be settled, not even as a timeout12 hours 10 minutes to 7 days
full_stake_storage_budget2.00 TiB (2,199,023,255,552 bytes)Storage cap per validator over one retention window, for a validator assigned the maximum 4,096 rows. Others get it in proportion to their rows. A Fibre server refuses uploads beyond its capAny positive number of bytes

Fixed by the protocol

These values are set in code and change only with a new celestia-app version.

Rows per blob4,096 data rows plus 12,288 parity rows (16,384 in total). Any 4,096 rebuild the blob
Largest blob134,217,723 bytes of data (128 MiB with the 5-byte header)
Row widthRounded up to a multiple of 64 bytes, so the smallest billed size is 4,096 × 64 bytes = 256 KiB
Payment per blob650,000 utia plus 45,000 utia per started 256 KiB of billed size. A 300-byte blob costs 695,000 utia; a 128 MiB blob costs 23,690,000 utia
PFFs per blockAt most 200
Promise clock skewA promise's creation time may be at most 10 minutes ahead of block time
Replay protectionA settled promise is remembered for withdrawal_delay plus 10 minutes. Older promises are rejected as too old
Blob ID33 bytes: 1 version byte and the 32-byte commitment
Sources

celestia-app v10.4.0: x/fibre/types/params.go (defaults and ranges), fibre/protocol_params.go, fibre/blob_id.go, pkg/appconsts/fibre_consts.go, pkg/appconsts/fibre_gas_consts.go, x/fibre/types/gas.go, x/fibre/keeper/keeper.go, fibre/server.go and fibre/server_upload.go (storage cap); CIP-51 (parameter table); Celestia docs: Fibre guide (written for Mocha) (example charges); current values read from chain by this site.

Glossary

The terms used on this site: rows, shards, promises, escrow, PFF and more
Blob
Data published to Celestia under a namespace. With Fibre, its bytes stay on validators' Fibre servers.
Namespace
A 29-byte identifier every blob is published under. Fibre adds the commitment blob to the publisher's namespace.
Fibre server
The service a validator runs to receive, store and serve Fibre rows. Its host is registered on chain.
Provider registry
The on-chain list (x/valaddr) mapping each validator to its Fibre server host. A validator that is not registered receives no Fibre traffic.
Row
One of the 4,096 equal slices a blob is cut into, or one of the parity rows computed from them. Rows are as wide as the blob needs: 64 bytes to 32 KiB.
Parity rows
The 12,288 rows computed from the 4,096 data rows. Any 4,096 of the 16,384 rows rebuild the blob.
Shard
The rows assigned to one validator for one blob, sent and stored with their proofs.
Commitment
A 32-byte value that binds all rows of a blob. Each row is checked against it on upload and download.
Blob ID
33 bytes: the blob version followed by the commitment. Used to download a blob.
Blob version
The encoding format of a Fibre blob. Version 0 is the only one in use.
Billed size
The size a Fibre blob is charged for and that the payment promise records: row width × 4,096, padding included. The code calls it the upload size (blob_size).
Payment promise
A message signed by the escrow owner promising to pay for one blob. Validators sign the same message after storing their rows.
Escrow account
Prepaid funds held by the Fibre module, from which payments are taken.
Escrow owner
The account whose key signed the payment promise and whose escrow pays. It can differ from the account that submits the PFF.
PFF (MsgPayForFibre)
The transaction that settles a payment promise, carrying the validator signatures.
Endorsement
A validator's signature on a payment promise, given after it stored its rows.
Stake (voting power)
The tokens bonded to a validator, which give it voting power. Row assignment and the 2/3 threshold use each validator's share in the validator set at the promise's height.
Promise height
The block height named in the promise. Its validator set decides row assignment and whose signatures count.
Timeout settlement
Charging an unsettled promise after payment_promise_timeout, via MsgPaymentPromiseTimeout. No validator signatures are needed.
TIA, utia
Celestia's token. 1 TIA = 1,000,000 utia; amounts on this site are exact utia.
Gas
The unit a transaction's work is measured in. A transaction fee is its gas times the gas price. Fibre payments are a fixed 1 utia per gas.
Light node
A Celestia node that checks that block data is available by sampling small random pieces of each block.
Governance
On-chain proposals and votes by stakers. The x/fibre parameters can only be changed this way.
Fee collector
The account that receives transaction fees and Fibre payments before they are distributed to validators and delegators.
Consensus address (valcons)
The address of a validator's consensus key, used on validator pages. The provider registry is keyed by it.
Operator address (valoper)
The address that identifies a validator in staking, used on validator pages. It is the signer named when a validator registers its Fibre server host.
Sources

celestia-app v10.4.0: specs/src/fibre_client.md (glossary), specs/src/fibre_module.md, specs/src/fibre_encoding.md, x/valaddr/README.md, fibre/blob_id.go, x/fibre/keeper/msg_server.go; CIP-51.

Sources and verification

What every statement was checked against, and where the sources disagree

Every statement on this page was checked against these sources on 2026-10-19, in this order of authority:

  1. celestia-app source code at v10.4.0, the version this site decodes this network with, including its specifications and module READMEs.
  2. CIP-51, the Fibre protocol proposal (status: Implemented).
  3. Celestia's documentation: Fibre guide (written for Mocha) and the Data availability FAQ (both last updated 16 October 2026).
  4. Current parameter values, read from chain by this site.

Each section lists its own sources under “Sources”. When sources disagree, the code wins. These disagreements were found:

  • The 2/3 threshold. The x/fibre README says signatures must represent “more than 2/3 of the voting power”. The code accepts total × 2 / 3 rounded down, so exactly two thirds is enough. The module specification states the same rule, but a few lines later also calls it a “2/3+ threshold”.
  • Storage cap refusals. The Fibre server specification says the server does not currently return ResourceExhausted “for the cases described by older target designs”. The code returns it when an upload would exceed the server's storage cap.
  • Storage cap size. The x/fibre README describes full_stake_storage_budget as the cap of a “hypothetical 100%-stake validator” (CIP-51: “hypothetical full-stake validator”), from which each server or validator derives a “stake-proportional budget”. The code scales it by assigned rows (budget × rows ÷ 4,096), and rows are capped at 4,096, so every validator with at least 1/3 of the stake gets the full budget.

How this site turns chain and probe data into numbers is described in Methodology.