Lightning Beginner 5 min read
Lightning Fees
Understanding Lightning Network fees. Base fees, proportional fees, routing economics, and fee optimization for agents.
fees routing base-fee ppm economics
Lightning Fees
Lightning fees are dramatically lower than on-chain Bitcoin fees. Instead of paying by transaction size, you pay routing nodes a small amount for forwarding your payment.
Why Fees Matter for Agents
| Aspect | Impact |
|---|---|
| Micropayments | Fees must be tiny for small amounts |
| Routing | Fees affect path selection |
| Economics | High fees make some payments uneconomical |
| Predictability | Fees are known before payment |
Fee Structure
Lightning fees have two components:
Base Fee
Fixed amount charged per forwarded payment, regardless of size.
base_fee = 1000 msat (1 satoshi)
Proportional Fee (Fee Rate)
Percentage of payment amount, expressed in ppm (parts per million).
fee_rate = 100 ppm = 0.01%
For 100,000 sat payment:
proportional_fee = 100,000 × 100 / 1,000,000 = 10 sats
Total Fee Calculation
total_fee = base_fee + (amount × fee_rate / 1,000,000)
Example:
- Amount: 100,000 sats
- Base fee: 1000 msat (1 sat)
- Fee rate: 100 ppm
fee = 1 + (100,000 × 100 / 1,000,000)
fee = 1 + 10
fee = 11 sats
Fee Comparison: Lightning vs On-Chain
| Payment Size | Lightning Fee* | On-Chain Fee** |
|---|---|---|
| 100 sats | ~1 sat (1%) | ~200 sats (200%) |
| 1,000 sats | ~2 sats (0.2%) | ~200 sats (20%) |
| 10,000 sats | ~3 sats (0.03%) | ~200 sats (2%) |
| 100,000 sats | ~11 sats (0.01%) | ~200 sats (0.2%) |
| 1,000,000 sats | ~101 sats (0.01%) | ~200 sats (0.02%) |
*Assuming 1 sat base fee + 100 ppm, single hop **Assuming 1 sat/vB, ~140 vbyte transaction
Key insight: Lightning wins for smaller payments.
Multi-Hop Fees
Fees accumulate across each hop:
Alice → Carol → Dave → Bob
fee=5 fee=3
Bob receives: 100,000 sats
Dave charges: 3 sats → Dave receives 100,003
Carol charges: 5 sats → Carol receives 100,008
Alice sends: 100,008 sats
Fee Accumulation
def calculate_route_fee(amount, hops):
"""
Calculate total fees for a route.
hops = [(base_fee, fee_rate), ...]
"""
total = amount
for base_fee, fee_rate in reversed(hops):
fee = base_fee + (total * fee_rate // 1_000_000)
total += fee
return total - amount
Typical Fee Ranges
| Node Type | Base Fee | Fee Rate | Use Case |
|---|---|---|---|
| Hobbyist | 0-1 sat | 0-50 ppm | Community support |
| Routing node | 0-1 sat | 50-500 ppm | Balanced |
| Well-connected | 1+ sat | 100-1000 ppm | Premium routes |
| Private | Variable | Variable | Custom agreements |
Zero Base Fee
Some nodes set base_fee = 0 for:
- Better micropayment support
- Path selection algorithms favor them
- Philosophy (proportional-only)
Setting Your Fees
Via LND
# Update channel fees
lncli updatechanpolicy \
--base_fee_msat 1000 \
--fee_rate_ppm 100 \
--chan_point abc123:0
Via Core Lightning
lightning-cli setchannel CHAN_ID 1000 100
# (base_fee_msat, fee_rate_ppm)
Dynamic Fee Strategies
def adjust_fees_by_liquidity(channel):
"""Higher fees when liquidity is scarce."""
local_ratio = channel.local_balance / channel.capacity
if local_ratio < 0.2:
# Low outbound, charge more
return {"base": 2000, "rate": 500}
elif local_ratio > 0.8:
# High outbound, charge less to encourage flow
return {"base": 0, "rate": 10}
else:
# Balanced
return {"base": 1000, "rate": 100}
Fee Optimization for Agents
Minimizing Costs
- Fewer hops: Direct channels avoid intermediary fees
- Low-fee routes: Use pathfinding with fee limits
- Batch payments: Combine when possible (MPP)
Setting Fee Limits
# LND: Maximum fees
routes = lnd.query_routes(
pub_key=destination,
amt=amount,
fee_limit={"fixed_msat": 10000} # Max 10 sats
)
Fee Budget
def calculate_fee_budget(amount, max_percent=1.0):
"""Calculate max acceptable fee."""
return int(amount * max_percent / 100)
# For 100,000 sats with 1% max
budget = calculate_fee_budget(100000, 1.0) # 1000 sats max
Fee Economics
When High Fees Make Sense
- Unique routes: Only path to destination
- Large payments: Fixed cost amortized
- Time-sensitive: Pay for reliability
When Low Fees Matter
- Micropayments: Fee > payment = useless
- High volume: Fees compound
- Competition: Others offer lower rates
Break-Even Analysis
For routing nodes, profitability requires:
revenue = (payments_routed × avg_fee)
costs = (channel_opening + rebalancing + operations)
profitable if: revenue > costs
Fee-Related Failures
| Error | Meaning | Solution |
|---|---|---|
FEE_INSUFFICIENT | Your fee too low | Increase fee limit |
INCORRECT_CLTV_EXPIRY | Fee changed | Refresh route |
| Route not found (with budget) | No cheap route | Increase budget or direct channel |
LNURL and Zero Fees
Some services absorb fees:
- LNURL-pay: Service pays routing fees
- Lightning Address: Provider handles fees
- Custodial wallets: Internal transfers free
Related Topics
- Routing - How fees affect path selection
- Liquidity - Rebalancing costs
- Invoices - Fee information in invoices
- BOLT-07 - Fee announcement format
Machine-Readable Summary
{
"topic": "lightning-fees",
"key_concepts": [
"base-fee",
"proportional-fee",
"ppm",
"multi-hop-accumulation"
],
"typical_values": {
"base_fee_msat": "0-1000",
"fee_rate_ppm": "1-500"
},
"formula": "total_fee = base_fee + (amount × fee_rate / 1_000_000)"
}