Routing fees roll in. Channels open and close. Rebalances are needed. Three streams of activity, three sources of truth, and no single number that tells you whether your node is paying for itself. Profitability is routing fees earned minus costs paid, and those costs are scattered: on-chain channel transactions, rebalancing, force-close fees, and the opportunity cost of locked capital. To get a real answer you need all of it in one place, filterable, in a shape your accountant can read.
If you have not started running a node yet and are asking whether it is worth it, the honest answer is: it depends. Block has reported close to 10% a year on the bitcoin it commits to its Lightning routing node. The only way to find out yours is to measure properly. This post shows what that looks like with the Clams CLI today, using a connected LND node. The workflow is the same for a handful of channels or hundreds as an LSP.
What profitability actually means for a Lightning node
Revenue is simple: routing fees earned forwarding payments. Costs hide in four places. On-chain fees for channel lifecycle events: funding, cooperative closes, and the pricier force-close sweeps. Rebalancing: fees you pay other nodes to restore inbound liquidity. Liquidity itself: inbound liquidity ads, JIT channel opens, submarine swaps. And opportunity cost: capital locked in channels that could earn elsewhere. The first three hit your balance whether you track them or not. The fourth is a modeling choice.
The Clams data model maps directly to these events
Lightning's accounting nuances are in the BOLT specs and our Lightning Network Accounting post. What matters here is that Clams normalizes every channel event into six canonical record types, with every sat traceable from where it came to where it went. Four of those types carry the profitability signal:
forwardsare routed payments. Each one credits a Routing Income account for the fee you earned.paysare payments you originated, including rebalances. Each carries the amount sent and the routing fee you paid.transactionsare the on-chain channel lifecycle events: funding, cooperative close, force-close sweeps.channelscarry capacity and the opener flag, which tell you how much capital is locked and which side paid the funding fee.
Once the node is synced these populate automatically. Everything below is native CLI output against a live node, no spreadsheet in between.
The walkthrough
Start with the connections you have synced.
$ clams connections list
Connections
-----------
Connection ID Label Kind Last Sync
019d6381-a8b3-78a3-9935-384a6654cc27 coreln-node CoreLn 2026-05-11T21:01:26+00:00
019d6381-a971-7a43-ad1c-93c979e99f80 lnd-node Lnd 2026-05-11T21:05:29+00:00
019e1b8a-f4d4-70d2-b25b-754f25925850 operations-wallet Descriptor 2026-05-12T09:36:06+00:00
019e1b91-c768-7570-b0d6-fb6f2d971f2d river River 2026-05-12T09:43:22+00:00
Four connections. Every command below scopes to the LND node with --connection lnd-node, so the numbers are that node's alone.
Channel state first. Capacity is capital locked; the opener flag says who paid the funding fee.
$ clams records channels list --connection lnd-node
Channels
--------
ID Capacity Funding Outpoint Opener
1883463418445824 1000000.000 77bd93e66adde188…:0 No
1912050720768000 1000000.000 7f4167ec5297187c…:0 No
37391091925843968 1491179.000 fcf2a68623c851f6…:0 Yes
Three channels. The two one-million-sat channels were opened by the remote peer (Opener: No), so their funding fee was not yours. The third, 1,491,179 sats, is yours (Opener: Yes): you paid the funding transaction, and that capital is locked until the channel closes.
Now the activity. journals events count is the one command that aggregates natively, grouped by event kind and by connection:
$ clams journals events count
Journal Event Counts
--------------------
Snapshot timestamp: 2026-05-15T18:39:54.931+00:00
Unique events: 318853
By Connection
-------------
Connection Total
coreln-node 195578
lnd-node 170477
operations-wallet 14
river 3
Connection Breakdown
--------------------
Connection Kind Count
lnd-node forward 5967
lnd-node invoice 60701
lnd-node pay 103804
lnd-node transaction 5
(Output trimmed to the lnd-node rows; the command prints every connection.) For this node: 5,967 routed forwards, 103,804 pays, 5 on-chain transactions. Counts, not sats. For sats, go to the records.
Routing income is the forwards list. Each row is one routed payment and the fee it earned:
$ clams records forwards list --connection lnd-node --limit 5
Forwards
--------
ID Connection Timestamp Amount
c9b2ae7d4d8285… 019d6381-a9… 2026-03-31 19:39:35 1.018
79ffadec5f2bcd… 019d6381-a9… 2026-03-31 19:54:10 1.017
ddcd10afafe35a… 019d6381-a9… 2026-03-31 19:54:17 1.015
c80502580cc525… 019d6381-a9… 2026-03-31 19:54:19 1.009
cc4b5d5a80f5ea… 019d6381-a9… 2026-03-31 19:54:50 1.016
Next cursor: svc3.ARAAAAAAAAAAAZ1POqFB…
Each forward earned about a sat. The Next cursor line means this is a paginated ledger, not a total. All 5,967 rows are here; the CLI hands you each one and does not sum them yet.
The Lightning cost side is the pays list. Amount is the value you sent; Fee is the routing fee you paid to get it there, including rebalances:
$ clams records pays list --connection lnd-node --limit 5 --descending
Pays
----
ID Timestamp Amount Fee Destination
pay:v1:2ec9edc107… 2026-05-11 20:58:05 33279.000 0.000
pay:v1:edc5f5924c… 2026-05-11 20:58:04 144703.000 1.448
pay:v1:c3a600699e… 2026-05-11 20:57:58 208856.000 2.089
pay:v1:ba55768a21… 2026-05-11 20:57:41 105913.000 0.000
pay:v1:4d713e6cd0… 2026-05-11 20:57:41 21748.000 0.000
Next cursor: svc3.ARAAAAAAAAAAAZ1POqFB…
The Fee column is your Lightning expense line, where rebalancing and routing costs accumulate. Amount is principal moving through, not a cost.
The on-chain cost bucket is the transactions list, the channel lifecycle events:
$ clams records transactions list --connection lnd-node
Transactions
------------
TXID Timestamp Block Inputs Outputs
df33aad171caea… 2026-03-31 19:19:17 1701 1 2
fcf2a68623c851… 2026-05-02 21:43:41 34007 1 2
0c68cb3cb3a0df… 2026-05-04 22:04:03 35366 1 5
c86f12d31d66b9… 2026-05-04 22:06:01 35368 1 1
fed733f2c42961… 2026-05-04 22:06:01 35368 2 1
Five transactions, matching the count. fcf2a68623c851f6… is the funding outpoint of the channel you opened (Opener: Yes above): the on-chain side of profitability. The list ties events to channels by txid; per-transaction fee attribution is not surfaced here yet.
Finally, the artifact your accountant actually wants: the full conserved double-entry ledger as CSV.
$ clams reports journal-entries --format csv --output lightning-ledger.csv
Journal entries CSV exported to lightning-ledger.csv
Snapshot 2026-05-15T18:39:54.931+00:00 (final)
Rows: 793429
Every leg of every event, timestamped, with account labels and an is_fee flag: the source of truth for a tax filing. One caveat: this export is workspace-wide, not yet filterable by connection or date, so for a multi-node workspace your accountant filters on the connection_label column downstream.
Clams gives you the raw, conserved ledger today: channels, forwards, pays, and on-chain transactions, filterable by connection. Every figure is one the engine computed, not assembled by hand.
The profitability report we are building
"Which channel is paying for itself" is the sharper question: lifetime routing earned against your share of the funding fee, the close cost, and the rebalances you paid to keep it liquid. The raw inputs are all in the records above, joined by channel ID and txid.
Clams is building this into a first-class report: one command that returns per-channel revenue, rebalance cost, lifecycle cost, and break-even, with none of the manual joins. It is in development. The records and exports above are the conserved data it will be built on, and they are available today.
What the number is for
A profitability figure is data, not a decision. The first thing it drives is tax: treatment of routing income varies by jurisdiction and by whether the node is a hobby or a business. Your accountant handles that; Clams gives them the journal entries export, every event timestamped and denominated in your reporting currency, ready to import. The second is operational, whether to scale from a handful of channels to a payments business. The same ledger answers both. We produce the number. The decision is yours.
Get started
Install the CLI, connect your LND or Core Lightning node, run clams journals process, and every record and report above populates against your own traffic. Prefer an API? The Clams REST API exposes the identical record types and reports; it is a wrapper over the same engine.
Routing a payment takes milliseconds. Knowing what it cost you should not take days or weeks.
Clams Team