The reason USDT on TRON dominates global stablecoin transfer volume isn't loyalty — it's fees. An EVM USDC transfer costs a dollar or more depending on gas. A TRON USDT transfer that hits a well-resourced address costs zero TRX. For merchants in emerging markets where customers are sending $30 to $200, that difference is the entire business case.
But "zero TRX" is not free: someone paid for it. TRON's resource model hides the fee inside a staking position. Understanding exactly how bandwidth and energy work, how to size a staking account for your transaction volume, and how to delegate resources to per-merchant deposit addresses is the difference between a 0.0% on-chain fee rate and an invisible 30% tax on every transaction.
Bandwidth versus energy#
Every transaction on TRON consumes two resources: bandwidth and energy.
Bandwidth maps to transaction size in bytes. A simple TRX transfer might consume 260 bytes; a TRC-20 USDT transfer, after encoding, is typically 350–400 bytes. TRON treats bandwidth like a renewable daily allowance: every account gets 600 free bandwidth units per day from the system. You can stake TRX to increase that cap. If your daily free allowance covers the tx size, bandwidth is effectively free. If it doesn't, 1 bandwidth unit costs 1,000 sun (0.001 TRX) from your balance.
Energy maps to virtual-machine execution cost. Plain TRX transfers have no
contract execution and consume zero energy. TRC-20 transfers, however, call the
USDT contract's transfer(address,uint256) function, and that call has a fixed
VM execution cost regardless of network conditions: 65,000 energy for a
standard USDT TRC-20 transfer (roughly 68,000 when the recipient is receiving
USDT for the first time, because initializing a new storage slot costs extra).
Energy is not renewable on a per-day basis the way bandwidth is. You obtain it by staking TRX. If your account carries no staked energy, the 65,000 units are burned directly from your TRX balance at a dynamic price set by network demand. At 420 sun per energy unit — a rate we observed throughout early 2026 — that is 27.3 million sun, or 27.3 TRX per transfer. At a $0.12 TRX price, each unoptimized USDT transfer costs $3.28. On a $50 payment that is a 6.6% fee. Not zero.
Stake 2.0 and the energy formula#
TRON's Stake 2.0 model (live since November 2023) separates energy and bandwidth into independent staking pools. You lock TRX to obtain one specific resource type and receive TRON POWER (TP) as a governance token alongside the resource units.
The energy yield from staking is not fixed; it depends on total network-wide staking. The current ratio (April 2026) is roughly 1 TRX staked = ~290,000 energy per day. Energy regenerates: once consumed, it restores at 1/24 of your total daily limit per hour, fully recovering over 24 hours.
To size a staking account for your gateway:
- Measure your peak USDT transfer volume per day (example: 5,000 transfers).
- Multiply by energy per transfer with a 5% safety margin: 65,000 × 1.05 = ~68,250 energy per transfer.
- Total daily energy needed: 5,000 × 68,250 = 341,250,000 energy/day.
- At 290,000 energy per staked TRX per day: ~1,177 TRX staked covers 5,000 daily transfers.
At $0.12/TRX, 1,177 TRX is a $141 capital lock you hold as long as you want zero-fee transfers at that volume. The unstake period is 14 days, so treat this as a permanent float rather than operational liquidity.
Delegating energy to deposit addresses#
TRON's system contract supports delegateresource(owner, receiver, resource, amount). This is the mechanism that makes per-merchant deposit addresses
practical: instead of funding each deposit address with enough TRX to cover
its own fees, you hold a single resource account with the staking position
and delegate a budget of energy to each deposit address when a payment intent
is created.
Delegation is temporary by default (one locking period), but the duration is configurable. The key constraint: delegation is always account-to-account. There is no shared pool that any address can draw from automatically.
A practical pattern for a payment gateway:
- Maintain one resource account per high-volume merchant (shared for smaller merchants).
- When a payment intent is created, call
delegateresourceto assign 70,000 energy to the deposit address for a 72-hour window. - After the payment is confirmed and swept, undelegate to recycle that energy to the next intent.
- Hold a 20% energy buffer above your measured peak to absorb burst volume — adding more staked energy requires an on-chain transaction that takes at least one block to confirm.
BchainPay handles steps 2 to 4 automatically when chain=tron is set on a
payment intent and a resource account is configured on the merchant profile.
If you are operating a hybrid setup, the BchainPay API exposes the full
resource state.
Querying resource state#
The chain-resource endpoint returns the current energy balance and delegation schedule for the gateway's resource account:
curl -s https://api.bchainpay.com/v1/chains/tron/resources \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json"Response:
{
"chain": "tron",
"resource_account": "TRxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"energy_limit": 341250000,
"energy_used": 87420000,
"energy_available": 253830000,
"bandwidth_limit": 600,
"bandwidth_used": 312,
"delegations_active": 143,
"staked_trx": 1177.0,
"updated_at": "2026-04-27T10:41:00Z"
}energy_available is energy_limit - energy_used, accounting for
regeneration since the last top-up. The field delegations_active counts
open delegation grants — each open grant consumes a small administrative
slot in the resource account and contributes to the energy_used tally.
Creating a payment intent with automatic energy delegation#
When you create a TRC-20 payment intent via the BchainPay API, energy delegation happens before the deposit address is returned to the caller:
const res = await fetch(
'https://api.bchainpay.com/v1/payment-intents',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.BCHAINPAY_SECRET_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': intentId,
},
body: JSON.stringify({
amount: 5000, // $50.00
currency: 'USDT',
chain: 'tron',
metadata: { order_id: 'ORD-8842' },
}),
},
);
const intent = await res.json();
// intent.deposit_address has had 70,000 energy delegated to it
// intent.resource_preflight.energy_delegated === 70000
// intent.resource_preflight.fee_trx === 0When resource_preflight.fee_trx is non-zero, the resource account did not
have sufficient energy to cover full delegation and the deposit address will
burn TRX for the transfer fee. This is the signal to top up the staking
balance before the next intent is created.
Monitoring and alerting thresholds#
Three metrics worth alerting on:
Energy utilization above 80%. At 80% consumed, new delegations start borrowing from the buffer. Set a critical alert at 80% to trigger a staking top-up before you hit zero. Energy regenerates over 24 hours, so if volume stays consistently high you will start burning TRX without a top-up.
Delegation failures. When delegateresource fails because of insufficient
energy, BchainPay emits an intent.resource_delegation_failed event in the
webhook stream. Route it to the same on-call queue as a failed payment — it
means the next transfer on that merchant will incur TRX fees.
Energy price spike. TRON's energy burn rate is published by
wallet/getchainparameters as getEnergyFee (in sun). When it rises above
500 sun, consider pre-leasing energy from JustLend to cover burst rather than
burning staking reserves. The threshold matters because rental pricing is
fixed and independent of the dynamic burn rate.
async function getEnergyPriceSun(): Promise<number> {
const params = await tronWeb.trx.getChainParameters();
const param = params.find((p: { key: string }) => p.key === 'getEnergyFee');
return param?.value ?? 420; // fallback to 420 sun if not found
}Energy rental as a burst lever#
Staking is optimal for baseline load. For burst — flash sales, end-of-month settlement spikes — renting energy from protocols like JustLend is often cheaper than locking additional TRX.
JustLend's energy rental is priced hourly (roughly 0.5 sun/unit/hour in early
2026) and settled in TRX. Renting 10 million energy for 24 hours costs
approximately 12 TRX (~$1.44). Permanently staking the TRX to generate
the same 10M energy per day requires holding 34.5 TRX ($4.14). Rental is
cheaper when the burst window is shorter than ~30 days.
We do not route BchainPay's primary production traffic through rental pools because they carry smart contract and counterparty risk. Rental is a fallback path, not a primary one. Implement it as a circuit breaker: fall through to rental only when staked energy drops below 30%.
async function ensureEnergy(required: number): Promise<void> {
const { energy_available } = await fetchResourceState();
if (energy_available >= required) return;
const deficit = required - energy_available;
const utilizationPct = (energy_available / energy_limit) * 100;
if (utilizationPct < 30) {
// below circuit-breaker threshold — rent the deficit
await rentEnergyFromJustLend(deficit, durationHours=24);
metrics.increment('tron.energy.rented', deficit);
} else {
// still in healthy range; queue a staking top-up for next maintenance window
alerts.warn('tron.energy.below_target', { energy_available, required });
}
}Bandwidth is almost never the bottleneck#
For completeness: every account's 600 free daily bandwidth units cover roughly one to two plain TRX transfers or zero to one TRC-20 transfers per day before fees apply. For a gateway sweeping hundreds of deposits, bandwidth staking is also required — but the cost is negligible compared with energy. Staking 1 TRX for bandwidth yields ~400 bandwidth units per day. A 400-byte TRC-20 transfer consumes 400 units. So 1 TRX staked covers one TRC-20 transfer's bandwidth per day, whereas the same 1 TRX staked for energy covers ~290,000 energy units (enough for ~4.5 USDT transfers). The energy position dwarfs the bandwidth position for any non-trivial payment volume.
Key takeaways#
- A TRON USDT transfer costs ~65,000 energy. Without staking, that burns ~27 TRX at current energy prices — not zero.
- At ~290,000 energy per staked TRX per day, 1,200 TRX covers roughly 5,000 daily USDT transfers with a safety margin.
- Use
delegateresourceto pre-assign energy to each deposit address at intent creation time; recycle delegations after settlement to conserve the energy pool. - Monitor energy utilization at 80% as a hard alert threshold. Subscribe to
intent.resource_delegation_failedwebhook events to catch staking shortfalls before they become merchant-visible fees. - Energy rental (JustLend, etc.) is a valid burst lever — but treat it as a circuit-breaker backup, not a primary funding source.
- Bandwidth staking matters for sweep transactions but is an order of magnitude cheaper than energy; size the energy position first, then add a small bandwidth buffer.