So you're operating your own Lightning Network node and you've opened a few channels - nice work! But opening channels is just the first step. To make your node more useful for yourself as well as to the rest of the network - i.e. to route payments - it's necessary to balance your channels. In this article, you will learn how to use the lncli command-line tool to manually rebalance your lnd node's channels.

Why Balanced Channels Are Better

Un-balanced channels are a problem because only the counter-parties in a channel know about the internal state of a channel (local vs. remote balances). So when a node constructs a route thru which to send a payment, they are hoping that each channel along the route will have sufficient local balance to route the payment onward. If all of your node's channels are equally balanced, then there's a better chance that another node will succeed in routing a payment thru your node. This is better for the health of the network and also it's better for you, because you can collect routing fees.

Another reason to balance your channels is to give your node more options when sending its own payments. For example, if many of your channels have zero or very low local balance, your node won't be able to use those channels to send payments.

Manual Channel Rebalancing

So first thing to do is to figure out which of your node's channels are in need of rebalancing. Use the following command to get a list of your node's active channels:

lncli listchannels --active_only

Example results:

{
    "channels": [
        {
            "active": true,
            "remote_pubkey": "REMOTE_NODE_PUBKEY_01",
            "channel_point": "XXX:0",
            "chan_id": "SHORT_CHANNEL_ID_01",
            "capacity": "500000",
            "local_balance": "499530",
            "remote_balance": "0",
            "commit_fee": "729",
            "commit_weight": "724",
            "fee_per_kw": "1006",
            "unsettled_balance": "0",
            "total_satoshis_sent": "0",
            "total_satoshis_received": "0",
            "num_updates": "0",
            "pending_htlcs": [
            ],
            "csv_delay": 144,
            "private": false,
            "initiator": true,
            "chan_status_flags": "ChanStatusDefault",
            "local_chan_reserve_sat": "5000",
            "remote_chan_reserve_sat": "5000",
            "static_remote_key": true,
            "commitment_type": "STATIC_REMOTE_KEY",
            "lifetime": "7",
            "uptime": "7",
            "close_address": "",
            "push_amount_sat": "0",
            "thaw_height": 0,
            "local_constraints": {
                "csv_delay": 144,
                "chan_reserve_sat": "5000",
                "dust_limit_sat": "573",
                "max_pending_amt_msat": "495000000",
                "min_htlc_msat": "1",
                "max_accepted_htlcs": 483
            },
            "remote_constraints": {
                "csv_delay": 144,
                "chan_reserve_sat": "5000",
                "dust_limit_sat": "573",
                "max_pending_amt_msat": "495000000",
                "min_htlc_msat": "1",
                "max_accepted_htlcs": 483
            }
        },
        {
            "active": true,
            "remote_pubkey": "REMOTE_NODE_PUBKEY_02",
            "channel_point": "XXX:0",
            "chan_id": "SHORT_CHANNEL_ID_02",
            "capacity": "500000",
            "local_balance": "0",
            "remote_balance": "499302",
            "commit_fee": "728",
            "commit_weight": "724",
            "fee_per_kw": "1006",
            "unsettled_balance": "0",
            "total_satoshis_sent": "0",
            "total_satoshis_received": "0",
            "num_updates": "0",
            "pending_htlcs": [
            ],
            "csv_delay": 144,
            "private": false,
            "initiator": false,
            "chan_status_flags": "ChanStatusDefault",
            "local_chan_reserve_sat": "5000",
            "remote_chan_reserve_sat": "5000",
            "static_remote_key": true,
            "commitment_type": "STATIC_REMOTE_KEY",
            "lifetime": "7",
            "uptime": "7",
            "close_address": "",
            "push_amount_sat": "0",
            "thaw_height": 0,
            "local_constraints": {
                "csv_delay": 144,
                "chan_reserve_sat": "5000",
                "dust_limit_sat": "573",
                "max_pending_amt_msat": "495000000",
                "min_htlc_msat": "1",
                "max_accepted_htlcs": 483
            },
            "remote_constraints": {
                "csv_delay": 144,
                "chan_reserve_sat": "5000",
                "dust_limit_sat": "573",
                "max_pending_amt_msat": "495000000",
                "min_htlc_msat": "1000",
                "max_accepted_htlcs": 483
            }
        }
    ]
}

In the above example output, we can see that we have two active channels. Both have a channel capacity of 500000 sats. Each of these channels has their balance completely on one side or the other. With such an imbalance, it's unlikely that either channel will be used to route payments for other nodes.

Not Enough Remote Balance?

Triangular channel swaps can help you to use your capital more effectively

If all of your channels have only a local balance and no remote balance, then you will not be able to rebalance them. Before you can continue with the rest of this guide, you will need to first find a counter-party who is willing to open a channel to your node.

Channel Swapping and Liquidity Triangles

I recommend to use one of the following collaborative channel swapping services or groups:

Manual rebalance via self payment

To balance the example channels above, you will pick two of your channels that need to be re-balanced. The first channel should have excess local balance. The second channel should have excess remote balance. You will use these two channels to pay yourself thru what is sometimes referred to as a "channel cycle".

Generate a new payment request so that you can pay yourself the amount that you wish to rebalance.

lncli addinvoice 250000

The invoice amount here is 250000 sats because that's half the channel capacity in the example channels above. Change this amount to whatever makes sense in your case.

Use the following command to pay the invoice:

lncli payinvoice \
    --allow_self_payment \
    --fee_limit 30 \
    --outgoing_chan_id SHORT_CHANNEL_ID_01 \
    --last_hop REMOTE_NODE_PUBKEY_02 \
    SELF_PAYREQ
  • --allow_self_payment - This flag is required to pay your own invoice
  • --fee_limit - The maximum fee to pay (sats).
  • --outgoing_chan_id - The short channel id ("chan_id") of the out-bound channel. This is the channel that has excess local balance.
  • --last_hop - The public key of the remote node for the in-bound channel. This is the channel that has excess remote balance.

Replace SHORT_CHANNEL_ID_01 with the "chan_id" of the out-bound channel.

Replace REMOTE_NODE_PUBKEY_02 with the "remote_pubkey" of the in-bound channel.

Replace SELF_PAYREQ with the invoice that you generated in the previous command.

You may need to increase the fee limit in case you are unable to route any payments. Alternatively, you can try to generate and pay an invoice for a smaller amount.

If the payment was successful, then congratulations! You've rebalanced your first channels.

Use the command from earlier to inspect the updated balances of your active channels:

lncli listchannels --active_only

You should see that both of the channels are now balanced.

Rebalancing with other tools

Here's a list of other tools that you could use to help you re-balance your channels: