Lite Nodes¶
A lite node stores full block data only from a chosen height upward. Below that height it keeps just the indexes later blocks actually need: key output info, spent key images, per-amount output counts and block headers. The block bodies, transaction records, payment ID index and timestamp indexes for those heights are never written.
This is a different feature from --prune, and the two cannot be combined.
--prune | --lite | |
|---|---|---|
| What it drops | Raw block bodies older than --prune-depth | Bodies, transaction records, payment IDs and timestamp indexes below --lite-height |
| When | A pass at every startup, after a full sync | At write time, from the very first block |
| Reversible | Yes, by resyncing | No — permanent for the database |
| Wallet rescan below the cut | Works | Does not work |
The in-repo long form, with storage measurements and design notes, is LITENODE.md.
Usage¶
--lite Enable lite mode. Permanent for this database.
--lite-height <H> Height at and above which full block data is kept. Required.
A user who created a wallet at height 4,000,000 and wants a node just for it:
That node syncs, mines, relays and validates exactly like a full node, and the wallet syncs against it normally.
Who should run one¶
| A user, own node for own wallet | Yes. This is what lite mode is for |
| An operator, public node others connect to | No — run a full node, with --prune if disk is tight |
| An operator, private or service node, wallets you control | Yes, good fit |
Never make a lite node a seed node.
Choosing H is the whole decision¶
Set H at or below your wallet's creation height.
If H is above it, the wallet's scan is clamped up to H and it will never see transactions between its creation height and H. The balance simply comes out too low. The wallet logs a warning and /info reports lite_start_height, but neither gets read when the number looks plausible.
then round down by another 10-20k for margin. Err low: too low costs some disk, too high costs transactions you cannot see.
Two things to accept before you start:
Hcannot be changed without deleting the data directory. The daemon refuses to start on a mismatch rather than wiping anything, but the choice is one way.- A lite node cannot serve a wallet older than its
H. Restoring an older seed later needs a full node, or a fresh lite node at a lowerH.
Why an operator usually should not¶
A public lite node is a worse network citizen and a support liability:
- It cannot serve blocks below
H, so it cannot help new nodes bootstrap. Peers belowHskip it as a sync source automatically. If everyone ran lite, nothing could sync. - You do not know how old your users' wallets are. Someone restoring a two-year old seed against your node is clamped to
Hand sees a wrong balance. That reads as lost funds, and it reaches you as a support ticket rather than a bug report.
Lite mode suits an operator when you control which wallets connect: a service node behind a recently created hot wallet, a mining node (mining reads only alreadyGeneratedCoins and the last 100 block sizes, so history is irrelevant to it), or a validation and relay node on cheap disk.
Lite mode and explorer mode are mutually exclusive¶
--daemon-mode explorer --lite is refused at startup. Every explorer endpoint below H — f_blocks_list_json, f_block_json, f_transaction_json, /queryblocksdetailed — reads the transaction records lite mode drops, so it would return nothing for those heights rather than report an error.
It saves disk, not bandwidth¶
The node still downloads every block from 0 to H over P2P: the key output and key image tables have to be built from real block data. What changes is that most of what it downloads below H is used and discarded rather than written.
That pass is cheaper than a normal sync — below the last compiled-in checkpoint the daemon already skips proof-of-work and ring-signature verification, and lite mode also skips the majority of the database writes — but it is still a full download measured in hours. Roughly 4,000 blocks/min on a modest box at low heights, slower through denser later blocks.
To skip that download entirely, import a snapshot instead: see Lite Node Snapshots.
Running one¶
Startup refuses rather than repairs. Every mismatch between the flags and what the database was built as exits without touching it. Deleting the data directory is always left to you. A daemon that will not start is telling you something, and the fix is never to add a force flag.
| Combination | Result |
|---|---|
--lite without --lite-height | Refused — there is no safe default |
--lite --prune | Refused — mutually exclusive |
--lite --daemon-mode explorer | Refused — explorer needs records lite drops |
--lite on a database synced in full | Refused — delete the data directory yourself |
No --lite on a lite database | Refused — it has no block bodies to serve |
--lite-height H' on a database built at H | Refused — H cannot be changed |
--rewind-to-height below H | Refused — those blocks cannot be undone |
| A database from an older storage format | Refused — restart with --resync, the only thing that deletes a chain |
The 14-day rule is checked at handshake time, not at startup, because the network's height is not knowable before then. If H is too close to the tip the daemon exits and names the highest value the network currently allows. The check is deliberately hard to trigger: once the node's own chain reaches H + 20160 the question is settled from local data and no peer is consulted at all, and before that what is weighed is the tallest chain claimed across several peers, so no single peer can produce the verdict.
Monitoring¶
/inforeportsliteandlite_start_height.statusshowsLite Node, and on a lite nodeFull Block Data From. While the node's own tip is still belowHit also showsLite Sync Stage: Index only, which is whyBlock Versionreadsv0for that part of the sync.print_cnshows which peers are pruned.
Changing the lite height¶
H cannot be changed in place, but a database can be rebuilt at a different one:
--resync deletes the chain and the peer state, and the rebuild starts at the new height. This is the supported way to move H, and the reason changing --lite-height on its own is refused: the destructive step has to be asked for rather than inferred.
Raising H on an existing database — turning blocks between the old and new height from full into index-only — is a deletion pass rather than a download, and is not implemented.
RPC behaviour¶
/infogainslite(bool) andlite_start_height./inforeportsmajor_versionandminor_versionas0while the node's own top block is still belowH, which is most of a first sync. Reading them needs the block body, and there is none down there. Everything else in the response works normally./getwalletsyncdataand/getrawblocksclamp a start height belowlite_start_heightup to it, and drop any start timestamp. A wallet that asks from 0 is served from the lite height rather than fed an empty response forever./get_global_indexes_for_rangerefuses belowlite_start_height. There is nothing sensible to clamp to — a silently narrowed range would read as "these heights hold no transactions", which is a different and wrong answer.- Peers asking for a block below the lite height get it reported in
missed_ids, so they ask elsewhere instead of losing the connection.
Wallet behaviour¶
Every wallet built on walletbackend — wrkz-wallet, wrkz-wallet-api, the C API the desktop and mobile wallets use, and the WASM web wallet — reads lite_start_height from /info and acts on it.
| The wallet | What happens |
|---|---|
| Has scanned nothing yet | Its scan height is floored to lite_start_height. A warning is logged; status names the floor |
Has scanned to a height at or above lite_start_height | Nothing changes. It carries on |
Has scanned to a height below lite_start_height | Sync stops |
The third case is the one worth understanding. The daemon would answer from its lite height whatever the wallet asked for, so continuing would move the wallet's recorded position over blocks nobody ever looked at: the wallet would report itself synced while every transaction in the skipped stretch was missing. Stopping is the honest answer. Point that wallet at a full node, or rebuild the lite node at a lower H.
Rescanning a wallet below H against a lite node does not work, for the same reason.