pull down to refresh

All across the Lightning Network we can detect quite a lot of nodes, specially new nodes but also old nodes, that show a concerning lack of good node operation which impedes proper routing. I’ve seen nodes with a variable capacity whose channels are stagnant and non performant, which raises a question: what is the point on maintaining a public node if you are not able to route and dynamically assign resources as needed? Certainly it is a useless node, and channels of those nodes with other nodes better maintained are also useless, not because the fault of the good ones, but because the fault of the bad ones, which makes the whole network not as performant and great as it should be.
For the shake of improving the Lightning Network, I have created this guide, so every node out there can become useful, and, also, will greatly improve gains in routing for itself. Do not expect to become rich or even live out of routing fees, that is impossible unless you have a node with 100 or more BTC in 2025, but at least, a node should be able to cover its own maintenance costs; its the idea. Problem is that, currently, most nodes run on a loss, and that is highly related with the fee policy and the choice of nodes that they connect to. Let’s put an end to this. Here you will learn how to, at least, earn enough to cover electricity of your node, and with luck, a bit more.
Current earnings cover electricity and the payment of my node:
3K sats per day might not seem much for a 5 BTC capacity (2.5 BTC real outbound) node, but the screenshot was taken in a bad day, when the mempool was empty. I took the screenshot of a bad day on purpose, to prove my point. Some other days, specially when Bitcoin is going bullish and it is used a lot, I have seen 20K per day. A quick calculation brings around 1M sats per year at a minimum, more than enough to pay electricity, the machine, and even a bit more for beers and fun! Real gains across the year could be closer to around 5M in my case, which is not bad. And what is incredible, I maintain general low fees for most of the cases, except when I have no liquidity in the channel which must be high, as you will understand later in this article. So if you double or triple my recommended fees I would expect quite a lot more earnings. So expect gains of around 2% of the total capacity (4% for the amount you put in) per year minimum, and any extra beyond that by fine-tuning my recommendations I'm sure it will be very welcomed by you!

Step 1: put the node in a good machine

Please, don’t use an old computer or laptop, unless you change the SSD for a new one. Bitcoin and lightning uses the SSD heavily, which means it will fry it sooner or later. That is so that I recommend changing the SSD every 2 years even it it still feels good. If your SSD dies during operation, expect big loses. I’ve seen this so many times, and it also happened to me, that I am very serious about recommending it. Also, please use only Linux with ext4 file format, other formats, including ZFS, I’ve seen failing badly. If your filesystem fails, the sqlite db that LND or CLN uses will fail and you will force close many if not most channels, with big fees for onchain closings, which will totally ruin all your gains. You have been warned!
Also, please take your time to configure a clearnet (ipv4) address. Do not rely only on Tor, because Tor is slow and unreliable, specially when updating channel states on the gossip, which you will be doing a lot. Of course, configure Tor also, but as secondary, because too many nodes are Tor only, which is unfortunate.

Step 2: connect to good nodes

As a public node operator, your duty is to connect to as many nodes as possible, but first, to good reputable nodes. Your first 10 channels should be with big nodes and service providers, like exchanges, wallets, but also to very well positioned big nodes. Take your time to select these 10 first nodes and connect to the ones you think will improve your position in the network. Don’t choose the first 10 biggest, take your time to study the fees. Select nodes that use a wide range of fees, from 0 to 1000ppm. Don’t discard a node because you see some channels with high fees, it could only mean that they have no liquidity right now in that channel. But if all its channels have high fees, or at least all small channels have high fees, then discard it.
Then, when you have your first 10 big nodes connected, go ahead and go to https://lightningnetwork.plus/ to choose less popular ones. You need them, because you seek to fill the voids between smaller nodes, it is what most of your revenue will come from. Always try to do swaps, use the liquidity pool later when you have enough total inbound liquidity. Remember that total capacity is not total outbound. Total capacity is total outbound + total inbound. So you can start with 0.25BTC of your own, but total capacity could be much higher if other peers have open channels to you.
A proper public node should have a minimum of 50 channels at its peak. It doesn’t matter much the size of the channels, but the quantity and the quality. A node with 50x500k sized channels will usually perform 10x better than a node with 5x5M sized channels, even if they have the same total capacity. This is because more opportunities to route will be found if you have more channels, which means you are much better positioned.
Anyway, the minimum recommended is 1M per channel because most HTCLs are 100k to 500k and less than 1M will wipe out all your liquidity in the channels in one or two routings. This could change in the future because of the Bitcoin price, but in 2025 this is the state of things. But if you don’t have 0.25 BTC to open 50 channels (25 open by you, 25 by others using swaps), just use smaller channels, don't let your available liquidity to crush your excitement, who knows what is the future ahead us! Remember that we are just at the beginning of this technology and there is nothing that impides your channels to be open for the next 20 years when 1BTC=$1M! I would put the ultra minimum at 250k per channel, which means a 12.5M node (6.25M required sats to start with), but even that is too precarious in 2025. But hopefully not in the future! If you have less than that my honest recommendation is to run a private node and open private channels only, and only if you absolutely need a node because you have to provide a service for multiple people and you can't conform to use simpler wallets. Right now, I can think of only one example of requiring an ultra-small node instead of wallets, which is using LNBits to service your small business or family. Be aware, anyway, that a 12.5M node will definitely not cover your node running costs in 2025, it is just an investment and positioning for a future!
In any case, never, ever, put all your BTC in a LN node, at most one third of your bitcoins and only when you are confident.
Also remember you have to be online 24/7. Please, don’t setup a node if you can’t. Remember you are providing a constant service, not an intermittent one. This guide won’t work if you are not committed to this rule.

Step 3: understand the flow

I’ve seen too many node operators that do not understand how payments are routed, and this is a big problem, because this is the base of everything we do with a LN node.
Payments go from one node to another to another to another until it reaches destination. Each node has what is called an outbound fee. This fee controls how much does it cost to route a payment through that node. If the fee is low it is considered attractive and other nodes will prefer to use that route. If the fee is high, it is obvious that nodes will not choose that route unless there is no other way.
But there is a problem here: all channels have a liquidity limit. If a channel has 1M liquidity and a payment of 500k comes through it, then now the channel has 500k liquidity, that is, a ratio of 0.5. If another 400k comes through, now it has 100k liquidity and a ratio of 0.1. If now somebody tries to route a 200k payment through that channel, and error will happen, because it doesn’t have enough liquidity. It is called an HTCL failure, and this are quite normal. Liquidity can come backwards, which means that now that channel becomes the income instead of the outcome, so if 300k comes in, in the example above, now the liquidity ratio is 0.4 (100k already there plus 300k that just came in). So it is easy to understand that liquidity is very volatile: it will come in and out with any successful in or out HTLC.
The problem is: how do you know if a channel has liquidity? For privacy reasons, the liquidity of a channel is never announced, and only the two connected nodes know it. This is logical, to avoid bad actors to figure out which payments have been done by other people. So the only possible solution is to try all connected channels you have until one lets you go through because it has enough liquidity. And it is going to be done, always, in the order of outbound fees, from low to high. So the channel that has the lowest fee with enough liquidity, will catch the prize.
There is a way to signal that you have liquidity or you don’t, and it is based on scarcity: if you don’t have much liquidity, you increase the outbound fee, so other nodes will not find attractive to route through you in that direction. You don't have much liquidity, so why bother to allow routing? But, when you have again outbound liquidity, because other nodes have taken the opposite direction (inbound) using another channel of yours which has liquidity (as outbound), you intelligently lower the fees to signal your new updated increased liquidity in the channel. So, the idea is simple: if you have liquidity in the channel, you put low fees, if you don’t have liquidity, you put high fees. Please read that again until you fully understand it, it is extremely important.
There is another concept introduced by LND which is negative inbound fees: if you put negative inbound fees, for example -100ppm, it means that any payment going from that inbound channel to another of your outbound channels, will have a maximum discount of 100ppm. (Don’t worry, you will never lose because LND forbids to route losing money, so 100ppm is the maximum, but it could be less if the outgoing channel has less than 100ppm fees.) What this does is to encourage the filling of empty channels at the cost of earning less in channels with plenty of liquidity. This is very good, because it will automatically rebalance your extremes: channels with no liquidity will be filled up, channels with plenty of liquidity will be emptied down, creating a balance.
It is obvious that the total ratio, including all your channels, should be around 100%. That means that the total amount summing all channels of inbound and outbound should be approximately the same. Don’t get obsessed with this, 80% or 120% is ok too, but if it is lower or higher than that you should take measures to open or close channels, or even swap out or in using boltz.exchange or LOOP.

Step 4: managing fees

So, in order to make proper routing, you will have to constantly monitor all your channels on a regular basis. Minimum recommended frequency is once a day. You can do this automatically or manually. Some people prefer to do it manually because each channel has its own characteristics and some fees work better than others, which is something you learn with time observing the flow. But some other people, like me, don’t want to spend so much time doing so, and do automatic fee management using charge-lnd or lndg automators. A mixture of both styles is possible by disabling automatic fee management for selected channels.
Every node operator has his/her own preferences, but here are some basic recommendations that you can tweak over time as you acquire experience:
ratio > 0.98: fees 0 (or less than 10)
0.2 < ratio < 0.98: fees proportional max 128, min 16
0.2 > ratio > 0.05: fees 500, inbound -16
ratio < 0.05: fees 1000, inbound -64
ratio = 0: fees more than 1000, inbound -128
So, as you can see, when the channel is full we encourage routing, when the channel is more balanced is when the earnings will occur (from 16 to 128ppm), when the channel is mostly empty we discourage forward routing (500ppm) but encourage backwards routing (inbound -16) and when it is almost empty we clearly totally discourage forward routing (1000ppm) but encourage backwards routing (inbound -64). And when someone just opened a channel with us, all liquidity is theirs so we aggressively encourage inbound routing by putting ultra high outbound fees and ultra inbound discounts. Simple, eh?

Step 5: automatic fee management

As stated before, you can automate this using charge-lnd or lndg or Lightning Terminal if you use LND. If you use CLN you are probably limited to create a personalized script, because I don’t know of any similar tool for it, apart from CL-BOSS which is unmaintained and non-customizable.
You will run this configuration a maximum of once per hour, and a minimum of once per day. You should not try to run it more frequent than once per hour because of two reasons: 1. The channel states stored in the gossip take from some minutes to some hours to properly propagate. 2. Some nodes will ban you if you try to update more than once per hour. What I recommend is once every 2 hours for big nodes with more than 50 channels. If you have less than 50 channels, your gossip will be slow to propagate so run it once a day. If you get many “Insufficient Fee” errors is because you are trying to update channel states too frequently. Also, some people report that increasing the variable numgraphsyncpeers in the LND configuration file helps with better propagation, but be aware that this will increase bandwidth usage.
I’ve been using lndg for some time, but I switched to charge-lnd because it is clearly superior and faster and more customizable. Lndg is still great for rebalancing (which I use a lot) and as a general interface, but I have disabled the fee management, which I now do with charge-lnd. If you can’t access charge-lnd then just use lndg with the frequency chosen above, but be aware that the configuration parameters are very limited, as you will soon realize (you are limited to just one strategy which is proportional, and it is very slow as it changes the fee in incremental steps). Yet it is better using lndg than nothing.
Lightning Terminal from Lightning Labs I have not tested. So I can’t say anything about it.
But here is a good starting configuration for charge-lnd that you can customize to your preferences:
[default]
# 'default' is special, it is used if no other policy matches a channel
strategy = static
base_fee_msat = 128
fee_ppm = 96
inbound_base_fee_msat = 0
inbound_fee_ppm = 0
min_fee_ppm_delta=20

[mydefaults]
# no strategy, so this only sets some defaults
base_fee_msat = 128
min_fee_ppm_delta = 0

[lost-onchain-sync]
# The fact that lnd was not synchronized with the chain for more than 5 minutes
# was an indicator of a severe problem in the past.
onchain.synced_to_chain = false
base_fee_msat = 210_000
fee_ppm = 210_000

[expensive]
# match channels where the peer node has set a high (>=8_000 ppm) fee rate
# and set the same fee rate on our side (strategy=match_peer)
chan.min_fee_ppm = 8000
strategy = match_peer

[leafnode]
# charge non-routing (private=true) peers a bit more for our service
chan.private = true
strategy = static
fee_ppm = 1000

[encourage-routing]
# 'autobalance' (lower fees so using outbound is more attractive) 
chan.min_ratio = 0.98
inbound_base_fee_msat = 0
inbound_fee_ppm = 0
strategy = static
base_fee_msat = 64
fee_ppm = 16

[discourage-routing]
# 'autobalance' (higher fees so using outbound is less attractive) 
chan.max_ratio = 0.2
chan.min_ratio = 0.05
strategy = proportional
inbound_base_fee_msat = -64
inbound_fee_ppm = -16
min_fee_ppm = 32
max_fee_ppm = 700
base_fee_msat = 1_000

[all-liquidity-is-theirs]
chan.max_ratio = 0.00
inbound_base_fee_msat = -128
inbound_fee_ppm = -128
strategy = static
base_fee_msat = 1_000
fee_ppm = 1000

[discourage-routing-extreme]
chan.max_ratio = 0.05
inbound_base_fee_msat = -128
inbound_fee_ppm = -32
strategy = proportional
min_fee_ppm = 32
max_fee_ppm = 1000
base_fee_msat = 1_000

[proportional]
# 'proportional' can also be used to auto balance (lower fee rate when low remote balance & higher rate when higher remote balance)
# fee_ppm decreases linearly with the channel balance ratio (min_fee_ppm when ratio is 1, max_fee_ppm when ratio is 0)
# 20% excess:
chan.min_ratio = 0.2
chan.max_ratio = 0.98
strategy = proportional
min_fee_ppm = 32
# 20% excess, so for a max of 128, it’s calculated 128/(1-0.20)=160
max_fee_ppm = 160
inbound_base_fee_msat = 0
inbound_fee_ppm = 0
base_fee_msat = 128
min_fee_ppm_delta=16
So you might run this config in a crontab or with your node distribution script if it is provided. I think Umbrel has this app in their portfolio, so just use it if you have Umbrel and ignore the following. If you run it manually or with a distro that doesn’t have charge-lnd, you can configure a crontab. This is just an example, please ask support for proper configuration on your distro. And if you distro do not include charge-lnd, ask support to include it, at this point it’s quite a necessity. Anyway here is the manual configuration:
$ crontab -e

0 */2 * * * echo "=======>" `date` >> /home/nodo/charge-lnd/log && /home/nodo/charge-lnd/env/bin/charge-lnd -c /home/nodo/charge-lnd/my.config >> /home/nodo/charge-lnd/log
That is supposing charge-lnd executable is installed under /home/nodo/charge-lnd/env/bin/charge-lnd and config is in /home/nodo/charge-lnd/my.config and LND is running without docker. If it is running under docker, you will have to ask support of your distro.

Step 6: help your peers

Remember that your peers are not only your competition, they are also your customers. So it is a strange symbiosis: you compete with them, but they also help you (and you help them).
If your peers are not well informed and have a bad maintained node, you are in a loss, because your channels with them will get stagnant and will not route. If they are well informed and know how to manage a node, then the channels will not be stagnant and they will route through you.
So it is stupid to keep this information as a secret. Every node operator should know it. And the more people know it, the better for everybody.
So, please, if you detect stagnant channels and bad maintained peers connected to you, just lead them to this guide, or guide them yourself. It’s a good idea to bookmark this guide so you have it prepared for the future.
And that’s it!! Happy routing!!
Great tips and data, thank you! I had a couple notes after reading - hope you don't mind.
  • 1M sat sat channels are fine now, but if we hit more mempool congestion a high fee environment with heavy routing could cause problematic force closes. Be careful with smaller, busy channels if onchain fees spike.
  • Ken Sedgwick has been maintaining CLBOSS recently. There's an ongoing biweekly meeting for node runners and contributors.
  • Core Lightning has the backup plugin to keep a duplicate sqlite db synced, or better yet postgres replication might be appropriate for serious funds. Either way should keep channels and funds safe in the event of catastrophic disk failure.
reply
Good notes, let me address them:
  • About the 1M channels problems when the mempool is congested, there should be no problem with modern implementations which use MPP. Anyway you have a good point, here is an additional config for that situation:
[onchain-congestion]
# if the onchain fee rate is high (>= 50 sat/vbyte) we increase the base fee to 20 sat
onchain.min_fee_rate = 50
base_fee_msat = 20_000
  • I used CL-BOSS when I had a CLN node. Thank you for informing that it is currently better updated. Do you know if now it does allow customization of the fee policy parameters?
  • I used the duplicate sqlite db sync when I had CLN, but I had to remove it because a failure in power supply causes out-of-sync, impeding that the node start, so it was useless in my case.
reply
CLBOSS has five different "FeeModders" which collectively adjust channel fees. Some are configurable and some not. The most relevant one here is probably FeeModderByBalance which I've tried tweaking, but it doesn't have publicly accessible config parameters. We've been discussing in the calls ways to make it more responsive.
The power failure scenario is definitely a concern. I have a script to replace an outdated db, but I'm not sure such a feature from within the plugin would be appropriate. Maybe the plugin could document a generic pre-start db restore script though.
reply
Thank you for the info about FeeModders, I remember something about it, but I desisted because, as you say, it doesn't have accesible parameters. I hope this changes in the future. In general, I find CL-BOSS too much automatic and too little configurable. It's a pity because the idea is great.
Yes, I had a script too for the outdated db. I think everybody using that feature has it. But what is the point if it is not a reliable solution?
Because of these and many other things, I finally switched from CLN to LND. I'm happier now.
reply
The house is burning and the old woman is combing her hair....
People are debating the OP_RETURN war and you are worried that some noobs node runners don't know how to run properly LN routing nodes. 😂😂😂😂😂😂😂

just joking man... very good guide, thanks. You should post it on https://stacker.news/~bitcoin_beginners because the Bitcoin territory is full of crazy stuff and people will ignore this important guide.
reply
Thanks, I will do so.
About the op_return drama, I pass.
reply
and in fact the whole drama is about -datacarriersize option :)
reply
Can you clarify the flow to me and which fee is seen?
Let's say I have channels to A and B. My fee on the channel with A is 1 sat. My fee on the channel with B is 5 sats.
If A sends to B, through my node, do they pay 1, 5, or 6?
reply
Sure, the fee is the outbound fee, which means the fee you charge for going out. So in your example, A pays 5 sats to you. B doesn't pay anything to you. But in addition to pay you, A will pay to B whatever B has as outbound fee (you can't control this).
Another thing is the inbound fee which is always negative or 0, and it is a discount. So if you put an inbound fee of -5, A will pay 0, because A is the inbound and B is the outbound which you put an outbound fee of 5, so the discount applies: 5-5=0. Do not confuse this with the outbound of A which is 1. Remember, outbound and inbound fees are different, they are not the same parameter, each channel has both fees, both inbound and outbound.
Any more questions I will happily answer.
reply
31 sats \ 3 replies \ @anon 14h
RTL only provides an interface to "Update Free Policy" where one can set base fee (msat) and fee rate (ppm). I guess that is outbound fees, right?
Then how do I set inbound fees in RTL (I run Core Lightning node with RTL)? My guess is that this is not supported in RTL because inbound fees are something that only LND supports and Core Lightning does not, right?
Are inbound fees in the LN protocol? That is, are they part of the channel fees gossip? I guess the answer is "no". If that is the case, then how do senders know about inbound fees when creating the payment routes?
reply
Fee policy means outbound fee policy, yes.
Inbound policies are a thing available in LND only, I think, but there is a BLIP: https://github.com/lightning/blips/pull/18
Other implementations should enable this, but you know CLN, it is always the last one and usually it comes late. Another reason not to choose CLN added to the long list.
For setting inbound fees graphically I know of LNDg in their advanced settings tab, which is also a good rebalancer and has a good interface (only for desktop).
reply
0 sats \ 1 reply \ @anon 10h
I see. That https://github.com/lightning/blips/pull/18 is not merged since 2022. Looks like there is a simpler and less disruptive way to implement that and it is to ask the peer on the other end of the channel to lower their fee and you will pay the diff to them. For example, assuming a channel between A and B:
A (outbound fee 1000) ---> (inbound fee -100) B
would be the same as:
A (outbound fee 900) ---> (no inbound fee, B pays 100 to A after a payment goes through) B
In the second case a greedy and mean A can increase the fee from 900 to 1000 shortly after and get 1000 from the sender and 100 from B. But that is equivalent to the first case where A can increase its fee to 1100 after noticing B set -100 inbound.
Inbound fees have to be supported by all softwares that support sending payments over LN. I wonder how many support that currently.
reply
As I said, losing is imposible because it is a discount. But if you don't believe me, let Lighting Labs tell you so:
That's very helpful, thanks.
reply
21 sats \ 1 reply \ @OT 19h
This is great!
Thanks!
Are you concerned at all about another spike in the mempool like what happened in 2022 (ordinals). Lots of channels were closed at large losses.
reply
Channels were closed because of a bug in LND as far as I remember, so no, I'm not concerned.
reply
21 sats \ 1 reply \ @aljaz 6 May
I keep a somewhat up2date list of resources for node operators that you might be interested in https://lightning-network.tech/
reply
Very good, would you add this article to it?
reply
Great guide. Thanks
reply
Appreciated for dedicated guide. That was worth my bookmark.1

Footnotes

reply
You are welcome, hope it helps.
reply