Energy and bandwidth

How Tron meters transactions, what the platform does when a signing address has no resources, why an empty master wallet stalls every TRC-20 payout, and what staking TRX does and does not buy you.

8 min readUpdated 3 August 2026energy, bandwidth, trx, gas, staking, freezing

Every other chain in the platform charges a fee the sender pays out of a balance. Tron does not. It meters two resources — bandwidth, roughly the byte size of the transaction, and energy, roughly the computation a smart contract performs — and an account either owns enough of them or burns TRX at a governance-set price to substitute.

Two consequences follow immediately, and everything else on this page is a detail of one of them.

The signer always pays. Tron has no fee-payer primitive. There is no equivalent of an EVM meta-transaction or a Solana feePayer. Whichever account signs a transfer is the account whose resources are consumed. The platform therefore cannot pay a fee on a user's behalf — it can only physically send TRX to the address that is about to sign.

Running out is not a slow transaction, it is a failed one. A transfer that cannot cover its energy is mined, burns what resources it had, and reverts with OUT_OF_ENERGY. Not a single token moves. The transaction hash exists and the transfer did not happen.

Which flows consume what

Flow Bandwidth Energy Who signs
Native TRX withdrawal Yes No — no contract runs The user's own deposit address, or a pooled alternative
TRC-20 withdrawal Yes Yes — the token contract's transfer The user's own address, or a pooled alternative
Master wallet TRX top-up Yes No The master wallet
Deposits Nothing — the sender pays Nothing Not us

Deposits cost the platform nothing. Someone else signed them. Every resource problem on a Tron install is a withdrawal problem.

What the platform does about it

Before it builds a TRC-20 transfer, the service sizes and funds the signer. The sequence is deliberately idempotent, because a re-queued withdrawal runs it again.

  1. Simulate the transfer with triggerConstantContract against live contract state and read energy_used. That is a real execution against real balances, so it accounts for the specific token and the specific recipient.

    If the simulation is unavailable it falls back to 65,000 energy — a deliberately conservative figure. Over-funding costs the platform dust; under-funding costs a reverted payout.

  2. Read the signer's live resources with getAccountResources. Available energy is EnergyLimit − EnergyUsed. Available bandwidth is the free daily allowance the node reports (freeNetLimit − freeNetUsed) plus any staked allowance (NetLimit − NetUsed). An unactivated or unknown account is treated as having zero of both.

  3. Read the current burn prices from the node's chain parameters — getEnergyFee and getTransactionFee, both in sun. These are governance-mutable, so they are read live and cached for ten minutes rather than hardcoded. Sanity clamps reject a malformed response, and the last-resort defaults are 420 sun per energy unit and 1,000 sun per bandwidth point.

  4. Compute the shortfall, only what the signer is actually missing. Bandwidth is sized at 350 bytes for a signed TRC-20 triggerSmartContract transaction. The whole figure gets 20% headroom.

  5. Top up to that target from the master wallet. Not "send a fixed amount" — top up to a target. If the address already holds enough TRX, nothing is sent, which is what makes a retry safe.

  6. Wait for the funding transaction to confirm — up to 90 seconds, polled every three seconds. Skipping this would let the transfer validate against an account the network still believes has zero TRX.

Only then is the transfer built, signed and broadcast, with a feeLimit of 100 TRX as a hard ceiling on what one transfer may burn.

The TRX sized and spent above is denominated in TRX. A customer's wallet is denominated in the token they are withdrawing. Adding one to the other produced a real, shipped defect once — a 27 TRX estimate became a 27 USDT debit — and the code now carries an explicit unit invariant against it.

The user is debited amount + the token's own platform fee, and nothing else, on every chain. The quoted network estimate and the 1 TRX new-account activation figure are stored as informational metadata only. Your recovery of the TRX cost is the token's fee object, which you set when you import the token.

When the master wallet runs dry

This is the failure everyone meets eventually, so it is worth knowing exactly what it looks like.

If the master wallet holds less TRX than the top-up requires, the service raises a requeue rather than a failure. The withdrawal row stays PENDING, the reconciliation watchdog retries it later, and no refund is issued because nothing was attempted on-chain. Top the master wallet up and the backlog drains by itself.

The symptoms, in the order an operator usually notices them:

  • TRC-20 withdrawals accumulate in PENDING and never advance.
  • Native TRX withdrawals complete normally throughout — they never touch the master wallet.
  • The backend log carries TRON master wallet <address> has X TRX, needs Y TRX.
  • Nothing is marked failed and nobody is refunded, so no customer is out of pocket — they are just waiting.

The same requeue happens when a top-up broadcasts but does not confirm inside the 90-second window. That is safe by design: the retry re-reads the balance, finds the top-up landed, and skips funding entirely.

Freezing and staking TRX

Tron lets an account stake ("freeze") TRX to receive a daily energy or bandwidth allowance instead of burning TRX per transaction, and to delegate that allowance to another address.

There is no freeze, unfreeze or resource-delegation code path anywhere in this product. Staking is entirely an operator action, taken outside the platform with a normal Tron wallet against keys you control. Nothing in the admin panel will do it for you and nothing will tell you it has not been done.

What the platform does do is read live account resources before it funds a signer. So delegated resources are honoured automatically: if a signing address already has enough energy and bandwidth, the shortfall computes to zero, no TRX is sent, and the transfer proceeds on the delegated allowance.

That makes staking useful — but read the next paragraph before you plan around it, because the custody model limits where it can help.

Why staking is awkward here, and what to do instead

The addresses that sign TRC-20 transfers are not one address. Every ECO wallet gets its own independently generated Tron address, and when a user's own address does not physically hold the tokens, the withdrawal is sourced from whichever custodial wallet does — see Withdrawals. You cannot know in advance which address will sign, so you cannot pre-delegate energy to it.

Three approaches that do work, in ascending order of effort:

Keep the master wallet liquid. The default model. Burn TRX per transfer, size the token fee to cover it, and treat the master wallet balance as a monitored number. Simple, predictable, and the only approach that needs no manual work.

Stake for the master wallet's own transactions. Every top-up is itself a transaction consuming the master wallet's bandwidth. Staking a modest amount of TRX against the master wallet removes that cost from the loop. It does nothing for the transfers themselves.

Delegate to a small set of known signing addresses. Viable only if you concentrate custody — for instance if one or two wallets hold the working balance for a token and are consistently selected as the pooled source. Delegate energy to those addresses from a staked account, and the top-up logic will see it and stand down. This is real operational work and it silently stops helping the moment the pooled selection picks a different wallet.

Whichever you choose, the burn-price inputs are governance-mutable. Both getEnergyFee and getTransactionFee can be changed by Tron's Super Representatives, and the platform re-reads them every ten minutes precisely because they are not constants. A cost model you calibrated a year ago is not a cost model.

Native TRX is a different, cheaper story

A native TRX transfer runs no contract, so it consumes no energy — only bandwidth. The platform estimates it separately: build the transaction, take its serialised size as the bandwidth requirement, read the signer's current bandwidth, and price each missing point at 10,000 sun.

That estimate is informational. Nothing tops the address up, because the address being drained is the one holding the TRX and the burn comes out of it. The practical effect is that a native withdrawal of a user's entire balance can fail for want of a fraction of a TRX to cover bandwidth. Leave headroom, or set the token's minimum withdrawal so a full drain is not reachable.

What to monitor

  • Master wallet TRX balance. The single most important number on a Tron install. Alert on it, do not check it.
  • WITHDRAWAL_REQUEUED in the backend log. It names the address and both amounts. It is the earliest signal of the failure above.
  • OUT_OF_ENERGY in the log. A transfer that broke through the funding logic and reverted anyway — usually a token whose real energy cost exceeded the simulation, or a resource the signer lost between funding and broadcast.
  • The token fee against actual burn. If TRX is leaving the master wallet faster than the token fee replaces it, the fee is set too low. That is a pricing decision, not a bug.