Deploy a node
End-to-end deployment for any TRON node — regular Fullnode, block-producing SR Fullnode, or Lite Fullnode. Hardware requirements, getting the client, starting it, configuration toggles, and day-to-day operation.
This page is the operational home for deploying any TRON node — Fullnode (the standard), SR Fullnode (block-producing), or Lite Fullnode (snapshot-based). The same FullNode.jar and the same procedure apply; you choose between them with a configuration option or a command-line flag.
For the conceptual comparison between node types and how to decide which to run, see Nodes overview.
Supported platforms
| OS | Architecture | JDK |
|---|---|---|
| Linux | x86_64 | Oracle JDK 8 |
| Linux | ARM64 | Oracle JDK 17 |
| macOS | x86_64 / ARM64 | Oracle JDK 8 (x86_64) or 17 (ARM64) |
Hardware requirements
Minimum
The bare minimum to run a java-tron node without immediately running into resource limits:
- CPU: 8 cores
- Memory: 16 GB
- SSD: 3 TB
- Network bandwidth: 100 Mbps
This is enough to keep up with the chain and serve light query loads. For production, prefer the recommended profile below.
Recommended
| Role | CPU | RAM | SSD | Bandwidth |
|---|---|---|---|---|
| Fullnode | 16 cores | 32 GB | 3 TB+ | 100 Mbps |
| Fullnode running as SR | 32 cores | 64 GB | 3 TB+ | 100 Mbps |
| Lite Fullnode | 16 cores | 32 GB | Few % of Fullnode, growing | 100 Mbps |
SR Fullnodes carry the consensus path on top of the standard workload, so additional CPU and RAM headroom matters. Lite Fullnodes start small but accumulate data at the same rate as a Fullnode — re-prune periodically to keep disk usage bounded (see Lite Fullnode deployment).
Managed hosting is also available from third-party providers such as Chainstack Self-Hosted.
1. Obtain FullNode.jar
You can either compile from source or download a published release.
Option A: Compile from source
git clone https://github.com/tronprotocol/java-tron.git
cd java-tron
git checkout -t origin/master
./gradlew clean build -x testOn a successful build, FullNode.jar is at ./build/libs/FullNode.jar.
Option B: Download a release
Grab the latest published JAR from java-tron releases. Releases are signed; verify the checksum before using in production.
Toolkit ships with the release. Every published java-tron release includes a Toolkit JAR alongsideFullNode.jar. The Toolkit is a bundle of database-maintenance utilities — generate a Lite Fullnode snapshot from a Fullnode database, fast-copy a database between volumes, convert between LevelDB and RocksDB engines, partition a database across volumes, and apply LevelDB startup optimizations. You do not need to install Toolkit separately; it's already in the release archive next toFullNode.jar. See Node maintenance toolkit for what each utility does.
2. Pick a configuration file
Each network has a default configuration:
| Network | Configuration | Source |
|---|---|---|
| Mainnet | main_net_config.conf | bundled in framework/src/main/resources/ |
| Nile testnet | See Nile network info | community-hosted |
| Shasta testnet | NA | This is a closed testnet; third-party node participation is currently not supported. |
| Private chain | Custom — see TRON private chain | self-authored |
Save the file as config.conf next to FullNode.jar.
3. Start the node
For a plain (non-block-producing) Fullnode on Mainnet:
# JDK 8 — concurrent mark-sweep GC
java -Xmx24g -XX:+UseConcMarkSweepGC -jar FullNode.jar -c config.conf
# JDK 17+ — CMS was removed in JDK 14, use G1GC instead
java -Xmx24g -XX:+UseG1GC -jar FullNode.jar -c config.conf-Xmx24g— JVM max heap. Size for your host: roughly 70% of physical RAM, never exceeding it. On a 16 GB minimum-spec host, use-Xmx12g, not-Xmx24g.-XX:+UseConcMarkSweepGC/-XX:+UseG1GC— GC algorithm; must come before-jar. CMS was removed in JDK 14, so JDK 17+ must use G1GC.-c config.conf— configuration file path.
Initial sync from genesis can take weeks to months on Mainnet (the chain holds multiple TB of data and grows continuously). To skip cold sync, download a database snapshot and place it in the output-directory next to FullNode.jar before starting.
To shut down a running node cleanly, send SIGTERM:
kill -15 <pid>
Avoid SIGKILL (kill -9) — a forced shutdown can corrupt the LevelDB / RocksDB store, requiring a re-sync from snapshot.
Block-producing Fullnode (Super Representative)
Adding the --witness flag turns a Fullnode into a block producer. This is what an SR runs to participate in consensus and earn the block reward. You must also provide the SR's signing key, either as a raw private key in the config or as a keystore file.
Provide the signing key
Option A: raw private key in config.conf — quick to set up, but the key is in plain text.
localwitness = [
650950B1...295BD812 // hex-encoded private key, 64 chars
]
Option B: encrypted keystore file — production setup; requires interactive password entry at startup.
localwitness = []
localwitnesskeystore = [
"subdir/localwitnesskeystore.json"
]
The path is relative to the directory you run the start-up command from. Starting with GreatVoyage-v4.8.2, use the Toolkit distributed with the node to create or import a keystore:
java -jar Toolkit.jar keystore new
# Or import an existing private key
java -jar Toolkit.jar keystore importUse --keystore-dir to specify the output directory. The legacy FullNode.jar --keystore-factory entry point remains available, but now displays a deprecation warning and is planned for removal in a future release. Use the Toolkit for new operations and gradually update scripts or workflows that depend on the legacy entry point. See Node maintenance toolkit for the complete commands and security guidance.
If the SR has delegatedwitness_permissionto a separate Account, use the delegated key here, not the SR account's owner key. See SR best practices for the witness-permission separation pattern.
Start with the --witness flag
--witness flagjava -Xmx24g -XX:+UseConcMarkSweepGC -jar FullNode.jar --witness -c config.confWhen using a keystore + password, the process prompts for the password interactively at start-up, so do not run under nohup. Use a session manager — screen, tmux, or systemd with Type=notify — to keep the process alive after disconnecting.
Lite Fullnode deployment
A Lite Fullnode runs the same FullNode.jar as a regular Fullnode but boots from a state-data snapshot instead of syncing from genesis. The snapshot contains the complete current state plus the most recent 65,536 blocks; everything older is not on disk. See Nodes overview for the conceptual comparison.
Obtain the snapshot
Two options:
-
Download a public snapshot from Public Backup Data. Fastest.
-
Prune an existing Fullnode database with the Toolkit:
java -jar Toolkit.jar db lite -o split -t snapshot -fn /path/to/fullnode/output-directory -ds /path/to/snapshotUse this if you already operate a Fullnode and want to bootstrap a Lite Fullnode from it. See Node maintenance toolkit.
Place the extracted snapshot in the output-directory next to FullNode.jar.
Start the node
Start exactly like a regular Fullnode (JDK 17+ → swap CMS for G1GC):
java -Xmx24g -XX:+UseConcMarkSweepGC -jar FullNode.jar -c config.confNo special flag is needed — the node detects the snapshot at startup and proceeds.
Default API restrictions
By default, a Lite Fullnode rejects queries that would require pre-snapshot historical data: every block-by- and transaction-by- lookup and the market-pair queries on /wallet/, /walletsolidity/, and /walletpbft/. Filtered requests receive this API is closed because this node is a lite fullnode. See the full filter list in LiteFnQueryHttpFilter and LiteFnQueryGrpcInterceptor.
To allow historical queries on data produced after the node first started up, add to config.conf:
node.openHistoryQueryWhenLiteFN = true
Pre-startup history (everything older than the snapshot's 65,536-block window at first launch) remains absent from disk and cannot be served regardless of this setting.
Periodic re-pruning
A Lite Fullnode accumulates data at the same rate as a Fullnode after startup. To keep disk usage bounded, periodically re-prune the running node's data into a fresh snapshot using the same Toolkit.jar db lite command. Monthly is a common cadence.
Day-to-day operation
Shutting down cleanly
Send SIGTERM to allow the node to flush state and close the database cleanly:
kill -15 <pid>
Avoid SIGKILL (kill -9). A forced shutdown can corrupt the LevelDB / RocksDB store, requiring a re-sync from snapshot.
Keeping the node online
A node does not need to be online non-stop, but the longer it stays up the less time it spends catching up after restarts. Two operational notes:
- A clean shutdown preserves the database; a forced shutdown can corrupt it.
- On restart, the node resumes sync from its last known head. If it has been offline for a while, expect a catch-up period before it serves the latest block.
Updating the client
Keep the client up to date — especially before hard-forking proposals take effect. An out-of-date client may fail to apply blocks after a fork-activating boundary and require a forced upgrade.
The simplest update procedure:
- Pull the latest release JAR.
- Stop the node cleanly (
kill -15). - Replace
FullNode.jar(andToolkit.jarif it shipped). - Restart.
For SRs, drain block production to a standby node before upgrading the primary — never upgrade the active producer in place. See SR best practices for the full upgrade procedure.
Other common configuration toggles
Optimize memory allocation with tcmalloc
tcmalloc reduces fragmentation and tail latency for the JVM's native allocations. Install it once, then preload it before launching FullNode.jar.
| Distribution | Install | Library path |
|---|---|---|
| Ubuntu 18.04 / 20.04 / Debian stable | sudo apt install libgoogle-perftools4 | /usr/lib/x86_64-linux-gnu/libtcmalloc.so.4 |
| Ubuntu 16.04 LTS | sudo apt install libgoogle-perftools4 | /usr/lib/libtcmalloc.so.4 |
| CentOS 7 | sudo yum install gperftools-libs | /usr/lib64/libtcmalloc.so.4 |
Add the preload to your start script:
#!/bin/bash
export LD_PRELOAD="/usr/lib/x86_64-linux-gnu/libtcmalloc.so.4"
export TCMALLOC_RELEASE_RATE=10
java -Xmx24g -XX:+UseConcMarkSweepGC -jar FullNode.jar -c config.confRun as a read-only query node
A node can serve queries without joining the P2P network — useful for indexers and analytics services that ingest data via another channel.
The only mechanism to disable P2P is the CLI flag --p2p-disable (verified in CommonParameter.java; there is no corresponding node.p2p.enable config key). Pass it at start-up:
java -jar FullNode.jar -c config.conf --p2p-disable trueFor defense-in-depth, also disable discovery and clear the peer lists in config.conf so no outbound P2P connections are attempted:
node.discovery.enable = false
node.active = []
node.passive = []
A node started this way still serves HTTP and gRPC queries from its local database; it just does not initiate or accept block-sync traffic.
Default ports
The Mainnet config.conf ships these defaults. If you run multiple nodes on one host, override the ones that would collide.
| Service | Config key | Default |
|---|---|---|
| HTTP — Fullnode | node.http.fullNodePort | 8090 |
| HTTP — Solidity | node.http.solidityPort | 8091 |
| HTTP — PBFT | node.http.PBFTPort | 8092 |
| gRPC — Fullnode | node.rpc.port | 50051 |
| gRPC — Solidity | node.rpc.solidityPort | 50061 |
| gRPC — PBFT | node.rpc.PBFTPort | 50071 |
| P2P listen | node.listen.port | 18888 |
| ZeroMQ event publisher | event.subscribe.native.bindport | 5555 |
| Backup peer port | node.backup.port | 10001 |
Port access controlExcept for required P2P connectivity, expose HTTP, gRPC, ZeroMQ, and backup-node ports only to trusted private networks or explicitly authorized clients. Restrict source addresses with a firewall or security group. If a public API is required, place the node behind a trusted gateway that provides TLS, authentication, and rate limiting instead of exposing node ports directly.
Enable historical account balance queries
To use wallet/getaccountbalance for historical balance lookups (any block, any account):
-
Enable in
config.conf:storage { balance.history.lookup = true } -
(Optional) Use a snapshot that contains historical balance data — see Database snapshots. Without one, the node only has balance history for blocks it synced after enabling this flag; pre-flag history is lost.
-
Start the node normally. The API begins responding once sync catches up.
Related resources
- Nodes overview — Node types and how to choose
- Database snapshots — Skip cold sync from genesis
- Node maintenance toolkit — Database utilities shipped with the release
- TRON private chain — Run an isolated network
- Becoming a Super Representative — Apply, register, and operate an SR
- SR node configuration — Witness permission delegation
- Accounts and keys — TRON's account and key model
Updated 5 days ago