TRON energy vs bandwidth: USDT transfer costs
Last updated:
Endpoint and plans: Tron RPC endpoint.
At a glance
| Property | Value |
|---|---|
| Bandwidth | Transaction bytes, including signatures and result reservation |
| Energy | TVM execution; no free daily quota |
| Free bandwidth | 600 on an activated account; gradual 24-hour recovery |
| Recipient state | Zero USDT balance can require a more expensive storage write |
| Dynamic surcharge | energy_penalty is included in energy_used |
| fee_limit | Caller-side energy budget in sun; bandwidth is separate |
What you see
Sending USDT burns several TRX even though the wallet shows free bandwidth. Another transfer burns almost nothing, or the next recipient costs roughly twice as much. TronLink can show available energy falling without a matching TRX debit: resource consumption and coin burning are different measurements. A transaction can also fail with OUT_OF_ENERGY while the account still holds USDT. USDT cannot itself pay the caller's TRX resource bill. To diagnose the difference, compare the recipient's token balance, the sender's available resources and the execution result, rather than just the amount of USDT sent.
Why this happens
Bandwidth measures the serialized transaction, including signatures and the protocol's result reservation. A wallet's JSON length is not that size. Energy measures instructions executed by the TRON Virtual Machine, so a native TRX transfer needs no contract energy while a TRC-20 transfer does. Available bandwidth and energy recover gradually over a rolling 24-hour window, rather than resetting at midnight. Staked or delegated bandwidth must cover the whole transaction; otherwise the network tries the free quota, then burns TRX for the whole byte charge if that quota also cannot cover it. Energy can instead be partly covered by resources and partly by burning TRX. Recipient storage matters: writing a zero token-balance slot is more expensive than updating a nonzero slot. An activated TRON account can still have a zero USDT balance; account activation and token storage are separate questions. Popular contracts also receive a Dynamic Energy Model surcharge. The simulation's energy_penalty describes that surcharge, already included in energy_used: adding it again double-counts. It can change between maintenance cycles, so yesterday's result is not a price guarantee. The TRX conversion uses getEnergyFee and getTransactionFee from getchainparameters. The official documentation checked on 2026-10-25 lists 100 sun per energy and 1,000 sun per bandwidth unit, with 1,000,000 sun to one TRX. Governance can change these values. Finally, fee_limit is a caller-side energy budget in sun, including energy covered by resources; it does not pay bandwidth or force a reverting transfer to succeed.
What one USDT transfer consumes
| Case | Energy | Bandwidth | TRX if fully burned | Source |
|---|---|---|---|---|
| USDT recipient already holds USDT | About 64,000 | About 345 | About 6.4 + 0.345 | TRON smart contract errors; TronLink Skills; TRON paying for resources |
| USDT recipient has zero USDT | About 130,000 | About 345 | About 13.0 + 0.345 | TRON smart contract errors; TronLink Skills; TRON paying for resources |
| Native TRX transfer to an activated account | 0 | About 270 | About 0.27 | TRON paying for resources |
What to do
- Simulate the exact transfer with triggerconstantcontract, using the real sender, token contract, recipient and amount. Inspect result.result, any error message and the returned contract result before trusting energy_used. A REVERT may consume little energy because execution stopped early; that is not an estimate for a successful payment. A nonempty result alone is not sufficient if the token returns false. Correct the cause and simulate again.
- Read getchainparameters immediately before calculating the burn allowance. Take energy price from getEnergyFee and byte price from getTransactionFee; do not copy the example constants into application configuration. Multiply the uncovered caller energy by its sun price, add the full bandwidth burn if no quota covers the transaction, then divide the sun total by 1,000,000. Preserve integer arithmetic until formatting the final TRX value.
- Set fee_limit using the caller's total estimated energy requirement times the current energy price, with a deliberate margin for state changes. Keep enough available energy or TRX to fund it, plus bandwidth separately. The limit is a ceiling for the caller's energy budget, not an extra fee paid in advance. Raising it helps an insufficient budget, but cannot repair an invalid recipient argument, a token restriction or an insufficient token balance.
- For recurring payments, consider Stake 2.0 through the protocol's freezebalancev2 operation, choosing ENERGY or BANDWIDTH for the resource you need. The resource allocation depends on the network's staking totals, so there is no permanent energy-per-TRX conversion. Check the available allowance before each payment and allow for gradual recovery over 24 hours. Staking is an on-chain action through a wallet or node that supports signing and submission.
- Delegation through delegateresource lets another account allocate resources obtained from Stake 2.0 to the sender. It does not change the USDT contract's execution cost; it changes which resources cover that cost. Check the incoming allocation and any lock conditions before relying on it. This is a protocol mechanism, not a recommendation for an energy rental service, and receiving a delegation is not the same as receiving spendable TRX.
- When planning several payouts, simulate each intended recipient rather than multiplying one existing holder's result by the batch size. Grouping estimates by zero versus nonzero USDT balance can help budgeting, but the distinction is a storage-cost effect, not a guarantee. Do not send unsolicited dust to alter a recipient's state. A routed contract or batch payout executes different logic and needs its own simulation; its energy cannot be inferred from a plain transfer.
- Budget bandwidth separately. With an untouched 600-unit free allowance, one roughly 345-unit transfer fits; two back-to-back transfers do not fit without recovery or another sufficient quota. If only a smaller free allowance remains, the ordinary rule burns TRX for the whole transaction's bandwidth, not just the missing units. Keep TRX for that possibility even when delegated energy covers execution, and reconcile the final receipt after sending.
Simulate a USDT transfer on your own TRON node
# OWNER_BASE58 must hold enough USDT; RECIPIENT_EVM_HEX is 40 hex characters.
# Remove the 41 prefix from the recipient's hex-41 address first.
PARAMETER="000000000000000000000000${RECIPIENT_EVM_HEX}00000000000000000000000000000000000000000000000000000000000f4240"
curl "https://<your-tron-node>/wallet/triggerconstantcontract" \
-H 'Content-Type: application/json' \
--data-binary @- <<JSON
{"owner_address":"$OWNER_BASE58","contract_address":"TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t","function_selector":"transfer(address,uint256)","parameter":"$PARAMETER","visible":true}
JSON
# Only use energy_used after confirming successful execution and a true return.Read prices; convert an all-burn estimate to TRX
curl "https://<your-tron-node>/wallet/getchainparameters" \
-H 'Content-Type: application/json' -d '{}'
# Set E, PE, B and PB from a successful simulation, prices and signed size.
# This assumes NO usable energy and NO bandwidth quota that covers B.
node -e 'const [e,pe,b,pb]=process.argv.slice(1).map(BigInt); console.log(String(e*pe+b*pb)+" sun; divide by 1000000 for TRX")' "$E" "$PE" "$B" "$PB"When this is not our problem
An RPC provider does not pay for or change TRON's resource costs. A different endpoint cannot remove a contract's storage writes or its dynamic energy surcharge. If you read TRON through Triport, use the dated sample and API procedure in Estimate a TRON USDT transfer fee: https://triport.io/docs/guides/estimate-tron-usdt-transfer-fee (linked below). Sign and submit through your wallet or sending node, then compare the receipt with the estimate.
FAQ
- How much energy does a USDT transfer use?
- Official TRON examples checked on 2026-10-25 show roughly 64,000 energy for a recipient with USDT and 130,000 for a zero USDT balance. These are reference magnitudes, not fixed protocol prices; simulate the actual transfer.
- Why does sending USDT to a new address cost twice as much?
- The expensive case usually means a zero USDT storage slot, even on an already activated account. Its storage write costs more, and dynamic energy magnifies the execution cost. This is not automatically an account-activation surcharge.
- Is bandwidth free on TRON?
- Activated accounts have 600 free units with gradual recovery over 24 hours. That can cover a small transaction's bytes, but it does not cover energy. Once no individual bandwidth quota covers the whole ordinary transaction, the full byte charge is burned.
- Energy vs bandwidth: which one does a TRX transfer use?
- A native TRX transfer uses bandwidth and no TVM energy. Calls made through a smart contract are different. Sending native TRX to an unactivated account can also invoke separate account-creation rules, so the table assumes an activated recipient.
- Can I estimate the fee before sending?
- Yes: simulate successfully, read current prices, check available resources and estimate the signed byte cost. Treat the result as a state-dependent budget. Recheck close to submission and use the final receipt to learn what was actually consumed and burned.
Sources
- TRON resource model — checked 2026-10-25
- TRON bandwidth and energy — checked 2026-10-25
- TRON paying for resources — checked 2026-10-25
- TRON smart contract errors: recipient state and USDT examples — checked 2026-10-25
- TronLink Skills: approximate USDT bandwidth (not its dated burn column) — checked 2026-10-25
- TRON FeeLimit and energy estimation — checked 2026-10-25
- TRON parameter encoding — checked 2026-10-25
- TRON Stake 2.0 — checked 2026-10-25
- TRON freezebalancev2 — checked 2026-10-25
- TRON delegateresource — checked 2026-10-25