docs / guide · updated 2026-08-01
Independent writer FAQ
This page is for someone who has read the call for an independent writer and wants the operational detail before deciding. It is deliberately long. The post is the summary; this is the part you read once you are seriously considering the work.
Current status
The network has one writer. It is operated by the project, it runs on one machine, and there is no second writer.
A writer becomes part of anything only when individual follower operators choose to authorize it in their own configuration. The project may include other writers as part of the default configuration once they are launched.
What a writer is, what are the other network roles
| Role | What it decides | What it holds |
|---|---|---|
| Writer | Which blobs belong in each head, from its own Ethereum inputs, and signs that claim. | Its own store, publication signing key, libp2p identity, IPNS name, indexers, and ingest credential. |
| Public edge | Nothing. It verifies a writer’s signed state against a pinned contract and relays it. | Read-only access to immutable blocks. No signing key, no mutation credential. |
| Follower | Which writers to authorize, which heads to retain, and what to serve locally. | Its own verified copy of the heads it selected, and its own durable replay floors. |
| Kubo replica | The same decisions as a follower. | An existing Kubo repository as the block store, pin database, and swarm identity. |
| Relay | Nothing. It is a libp2p introduction and hole-punching control path. | Nothing. It is not the bulk transfer path for archive data. |
The distinction that matters for this role: replicas decentralize availability, and independently deriving writers decentralize completeness assurance. A hundred copies of one writer still inherit that writer’s source schedule and acquisition assumptions. How BlobArchive works has the full role breakdown.
Which heads would I publish?
At launch the production archive publishes four finalized heads, all,
arbitrum-one, robinhood and base, and one bounded unfinalized head.
An independent writer publishes finalized heads. The multi-writer contract
applies to finalized-monotonic heads only. An unfinalized-mutable head has
exactly one authority by design, and a follower’s source set may name exactly
one source for it; a second writer does not publish it.
You do not have to take all four. A writer that publishes only all, or only
one filtered chain head, is a coherent deployment. Writers for other networks,
eg testnets or other L2s, than the ones published at launch are welcome. The trade-off is that a
filtered head requires you to independently obtain both the beacon blob bytes
and the parent-chain history that determines which batches belong in the head,
and to maintain that chain’s source schedule as its owner changes posting
mechanisms. The all head has no filter manifest and is the simpler
commitment. See heads and retention.
What independence requires, specifically
The point of a second writer is a second failure domain. Each writer must have its own:
- Host and provider, in separate power, storage, network, and administrative failure domains.
- Administrative control path. We do not hold shell, an account, a management agent, or any other access on your machine, and we do not want one.
- Store, backups, and a tested restore. The unit of backup is the whole store; a restore that has never been performed is not a recovery plan.
- Publication signing key and signer-local revision state.
- libp2p private key, PeerID, IPNS name, and IPNS sequence state.
- Endpoint and any DNS name used to reach it.
- Indexers and mutation credential.
- Beacon-chain input, and for filtered heads, the parent-chain RPC input. These should not terminate at the same node, reverse proxy, or provider account as ours.
- Monitoring and alerting, watching your own publication path.
Three things are never shared between concurrently running writers: private signing keys, libp2p keys, mutable KV state, IPNS sequence counters, or store directories. Content-addressed blocks may be copied freely; mutable authority state may not. There is also no lease, coordinator, or leader election to serialize writers, and adding one would break the model rather than improve it.
An ALL-head writer should obtain finalized existence from an independent beacon authority. Post-Fusaka this is a real design decision rather than a formality: a healthy ordinary consensus node may custody too few data columns to reconstruct complete blobs, and a node configured for long retention does not retroactively acquire history it never received. Measure your node’s actual serving frontier rather than trusting its configuration or an HTTP status. Discovery and trust covers why this is a common-mode boundary between writers and not just an acquisition detail.
Who holds the signing key?
You do. Always.
You generate your publication signing key on your own host, it stays there, and it is never sent to us, escrowed with us, backed up by us, or held by us in any form. There is no protocol mechanism for the project to hold another writer’s signer and no circumstance in which we would ask.
Consequences worth understanding before you generate it:
- Your key is your authority and its scope is exactly your own claims. A writer is trusted only for statements under its own signer.
- A key alone is not an identity. A signing key without its signer-local revision history can replay or equivocate, so never move only the private key to a new revision store.
- Rotation is source replacement, not an in-place swap. Create a new key and a new stable source ID on independent writer state, add it while the old source remains authorized, prove an equivalent or dominating claim, then retire the old source and keep its history.
- Do not reuse one key for both publication signing and libp2p identity. If they are the same key, losing it is a publication-key compromise, not a transport rotation.
- Compromise response is deauthorization first. Followers remove the key from active authorization immediately, without waiting for a replacement or a quorum. Deauthorization prevents future admission; it does not undo a generation already adopted.
What does it cost to run?
Every number below was measured on the production writer on 2026-08-01. It is a one-operator sample from a network with essentially one consumer, not a benchmark.
| Measure | Value (measured 2026-07-31) |
|---|---|
| Archive on disk | 2.8 TiB |
| Growth, last 24h | 7.94 GB |
| Growth, last 7 days | 55 GB, an average of about 7.9 GB/day |
| Implied growth at that rate | roughly 240 GB/month, about 2.9 TB/year |
| Writer memory | median RSS 0.48 GB, peak 2.08 GB over 7 days |
| Edge memory | peak 2.63 GB over 7 days |
| Writer CPU | p95 3.28 cores over 7 days |
| Egress | not reliably measured yet |
Three qualifications, each of which matters more than the numbers:
- The CPU peak is not ingest. p95 of 3.28 cores is driven by the periodic full-archive integrity scrub. Steady-state ingest is close to idle. Size for the scrub, and expect the scrub window to lengthen as the archive grows. Work will be underway post-launch to make scrubs cheaper.
- Growth will rise, and the current rate is a floor. The Ethereum
Foundation’s recorded post-Fusaka parameters are a target of 14 blobs per
block and a maximum of 21 after the first two Blob Parameter Only forks,
about 2.3 times the pre-Fusaka data space. Sizing storage against 8 GB/day
will leave you short. Budget for materially faster growth and for headroom
you have not yet needed. Filtered heads share blob blocks with
allrather than storing second copies, so publishing several heads costs far less than the sum of their sizes. - We cannot give you an egress figure. The network currently has close to one consumer, so any measured egress would understate a real operator’s by an amount we cannot bound.
How would I bootstrap?
There are two safe paths. They differ in how much trust the new writer inherits from the existing one.
- Rebuild from independent chain inputs. Provision a fresh store, keys, identity, endpoint, and upstreams; configure the same archive ID and immutable logical-head parameters; for each filtered head publish the recorded genesis manifest and require its CID to match, then run the indexer under that exact schedule, applying each recorded successor manifest at its exact boundary. At a fixed finalized boundary, compare roots. This is the strongest form of independence and the slowest.
- Seed immutable data, then prove it independently. A full follower promoted to a writer copies an exact selected root, manifest tip, and DAG without cloning any writer authority state. Give the promoted copy a new writer key and publication state, keep the logical archive ID, and switch it to genuinely independent upstreams. This is faster. It is also not yet independence: a seeded writer inherits the seed’s coverage decisions until it has advanced from its own upstreams, and a root that matches by copying proves faithful copying rather than that the source omitted nothing.
This is the bounded help we offer: an authenticated snapshot or bootstrap assist to shorten the initial data transfer. It is bounded because it is a data convenience, not a shortcut through the proof gate. If you take the seed path, the manifest chain still has to be replayed separately and an independent anchored audit still has to be completed.
The independent-writer guide has the exact procedures, and the operations guide has the promotion runbook, the backup and restore procedures, and the deterministic replication audit.
What has to match, and what may differ?
Every writer in a logical archive shares:
- one public, stable
publish.archive_id(64 lowercase hex characters); - the network and head names;
finalized-monotonichead kind and the immutable head parametersorigin_slot,seg_bits, andfanout_bits;- the intended finalized chain history; and
- for filtered heads, the exact ordered manifest history from genesis through the current tip, and the same filter meaning and source-range schedule.
Operational settings — batch size, polling cadence, cache size, worker count — do not define logical identity and may differ. Keep everything that defines content identical and under version control.
Writers may temporarily have different finalized coverage. That is safe when the lower root is an exact prefix of the higher root and their manifest tips are equal or ancestor and descendant in the same direction. If one writer has greater coverage while another has the descendant manifest, the claims are incomparable and followers hold their last good generation until the directions agree.
What is the proof gate?
Before a follower operator adds a writer to an active source set, all of the following must hold:
- the signed publication document authenticates under the expected public key;
- archive ID, network, head name, head kind, and immutable parameters match the logical archive inventory exactly;
- at a fixed coverage boundary, the root is equal to, or an exact projected extension of, an already trusted writer’s root;
- the manifest tip is equal to or a valid descendant of the recorded history, with root and manifest ordering pointing in compatible directions;
- the follower can fetch the signed document and required proof blocks through that source’s own publication and peer paths; and
- the writer has advanced from its own independent upstreams after bootstrap, proving it is no longer coupled to whatever seeded it.
Matching timestamps, a larger revision number, a higher IPNS sequence, arrival order, source-list order, and majority agreement are explicitly not substitutes for any of these. A timeout or a missing proof block means not yet proven, which is a different state from conflict.
How do followers authorize a writer?
Locally, by explicit configuration, one operator at a time. A follower’s source roster names each writer by a stable local source ID with its pinned public key, its name channel, and the exact heads it may contribute:
follow:
archive_id: "<64 lowercase hex characters>"
sources:
writer-a:
url: https://writer-a.example.org
ipns: k51qzi5uqu5d...
pubkey: "<64 lowercase hex characters>"
heads: [all, unfinalized]
writer-b:
url: https://writer-b.example.org
ipns: k51qzi5uqu5d...
pubkey: "<64 lowercase hex characters>"
heads: [all]
source_set:
revision: 1
acknowledge_digest: "sha256:<canonical roster digest>"
The roster digest must be acknowledged by that operator and the revision is an irreversible local authorization floor. There is no writer registry in the protocol, no feed of recommended writers that a follower consumes automatically, and no DNS name that silently rotates between writers. Publishing does not require our approval either: any operator may run a writer, publish through IPNS, use DNSLink under a domain they control, and distribute a signer-pinned follow profile, with no involvement from this project at all.
Human review applies only to the two things the project controls: names under
blobarchive.net and the follow profiles shipped inside released binaries.
That is a distribution decision, not admission to the protocol, and its
absence does not make an independently published writer less functional.
What happens when two writers disagree?
Nothing votes. A follower durably latches a finalized head only after closing a cryptographic contradiction: equal coverage with different roots, a failed prefix projection, or two readable manifest histories that are not descendants of one another. A latch freezes advancement of that head while the follower keeps serving its last durably admitted generation, and clearing it requires an operator to review the evidence and clear that exact evidence ID.
A missing proof, a timeout, a malformed publication, or temporarily incomparable coverage is not a latch and is retried without intervention.
The practical implication for a writer operator: being briefly behind is normal and safe. Being wrong is visible, durable, and requires a human to resolve. The system is built so that disagreement surfaces instead of being copied through the replica fleet.
What about upgrades and compatibility over time?
- Manifest upgrades are coordinated, in lockstep. Confirm every writer starts from the same manifest tip, run the same successor preflight against each writer’s current generation, publish the successor on each, and require the returned CID to be identical everywhere before any indexer uses the new schedule. If one writer returns a different CID, it is removed from advancement and repaired. Never mint a new genesis manifest or skip a predecessor to make a lagging writer catch up.
- Posting-mechanism changes are an append-only schedule, not an edit. Close the old source at a measured L1 block, add the new one at the next block, publish the successor manifest, and resume against the exact published schedule. A missed transition is repaired by backdating to the exact block and rescanning deterministically, not by patching forward.
- Store capability markers protect against downgrade. The first durable conflict latch upgrades the store’s capability marker, and older binaries that do not understand latches refuse the store rather than starting while silently ignoring safety state. Do not bypass that.
- Version currency is your responsibility. A writer that stops tracking releases will eventually be running something the rest of the network is not.
What monitoring is expected?
Start with the writer deployment monitoring table, which separates the private writer, indexers, public edge, and end-to-end canary. On your side, as a writer operator, alert on:
- changes to a chain’s canonical posting authority or allowed posters;
- expected blobs missing from a filtered head even while coverage advances;
- source-manifest publication and indexer progress;
- signature, conflict, or publication failures;
- GC and integrity-scrub completion;
- disk capacity, process resource limits, and unexpected restarts; and
- your own publication path being reachable and current.
Keep one non-empty historical blob as a byte-exact regression anchor. A
successful HTTP status is not an archive-integrity test — a beacon endpoint
can answer 200 with an empty array for a slot that provably held a blob,
which is how an incomplete archive passes a status-only check.
Followers observe writers locally rather than writers reporting to a central service. A source-set follower exports per-source availability, last-success timestamp, per-head covered and synced-to values, and a one-hot durable selection series, with labels drawn only from its own configuration. Nothing about your keys, CIDs, revisions, URLs, or PeerIDs becomes a metric label anywhere. Operate and troubleshoot covers the follower side of this.
What are the incident and contact expectations?
We would ask an independent writer operator to:
- publish a contact route that a follower operator can actually reach, and keep it current;
- tell us and your followers before planned maintenance that will interrupt publication, with as much notice as the work allows;
- report an outage of your publication or serving path when it is sustained, and post a resolution stating the measured window and whether integrity, publication progress, or only reachability was affected;
- preserve evidence before repairing anything after a conflict — the report, the signed documents, the source floors, and the last trusted frontier are what make a later forensic comparison possible; and
- handle security-sensitive reports through private vulnerability reporting rather than public discussion, per the repository security policy.
We hold ourselves to the same communication expectations for the writer we run. Neither side is offering the other an uptime SLA or a guarantee of individual operational support.
What does the project provide?
- The software, open source, with the writer configuration example and systemd units in the repository.
- Deployment and security documentation: the operations guide, the independent-writer guide, and the security policy.
- Compatibility tooling: the deterministic replication and audit
procedure that lets two writers compare roots at a fixed boundary, and
bloard config-inspectfor roster and digest verification on the follower side. - Bounded authenticated bootstrap or snapshot help, as described above.
- Canary support: review of your configuration and comparison results during the isolated period, before anything you run matters to anyone.
What does the project not promise?
- Not zero operational work. This is a production service with real storage growth, real upgrades, and real failures at inconvenient times.
- Not Byzantine consensus. There is no quorum, no leader election, no shared lease, and no majority that decides which claim is true.
- Not automatic trust. Follower operators authorize writers individually. We cannot grant you their trust and would not want the ability to.
- Not reimbursement. Hardware, bandwidth, and time are yours. There is no reward program attached to this role.
- Not relay-based bulk transfer. Relay circuits are an introduction and hole-punching control plane. A single raw blob already exceeds the production relay circuit’s data allowance before protocol framing, so relay-only transfer is not a fallback for archive data.
- Not a support contract. GitHub Discussions is a community surface, not a promise of individual operational support.
The staged path, in detail
- Informal interest. A public thread or a message. No commitment either way, and nothing is provisioned. The output is a shared understanding of whether this is worth either party’s time.
- Architecture and cost fit. Your provider, region, hardware, storage plan, upstream beacon and parent-chain sources, and expected growth headroom, checked against the envelope above before anything is built. The likely outcome of this stage is sometimes that it does not fit, which is a useful result and not a failure.
- Isolated canary. You provision the writer with its own keys, store, identity, endpoint, and upstreams, and run it. It is authorized in no follower’s source set. It publishes nothing anyone depends on. This stage exists so that a new writer can be wrong in private, and it should run long enough to cover at least one upgrade, one restart, and one scrub cycle.
- Compatibility. At a fixed finalized boundary your roots match, your manifest history matches exactly, your writer has advanced from its own upstreams after bootstrap.
- Optional public authority. If you want a name under
blobarchive.netor inclusion in the shipped follow profiles, that is a human-reviewed curation decision at this point. It is genuinely optional: publishing under your own domain, your own signer, and your own distributed profile requires nothing from us at any stage.
How to apply
Open a thread on GitHub Discussions: https://github.com/blobarchive/bloar/discussions. A useful first message answers:
Operator: who you are, and whether you are acting for an organization
Region/network: region, provider, and ASN if you know it
Hardware: CPU, memory, storage type and capacity, and headroom plan
Experience: relevant operational experience, especially Ethereum
infrastructure, IPFS/libp2p, or long-lived archival storage
Heads: which finalized heads you would want to publish
Timing: when you could realistically start, and at what pace
None of that is a form to be scored. It is the information needed to have the stage-2 conversation without three rounds of clarifying questions.
Where to read next
- The call for an independent writer — the summary and the reasoning behind the ask.
- How BlobArchive works — the architecture and the operational roles.
- Discovery and trust — what each layer of the trust chain proves, and what it does not.
- BlobArchive for L2s — the consumer side, and why a writer’s source-schedule completeness matters to it.
- Join the network — running a follower first, which is a sensible way to learn the system before committing to a writer.
- All documentation — the operator guides, the architecture walkthrough, and the normative reference.
- The independent-writer guide and the operations guide — the normative procedures behind everything on this page.