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

OSArchitectureJDK
Linuxx86_64 / amd64JDK 8 (Oracle JDK 8 recommended for production)
LinuxARM64 / aarch64JDK 17
macOSx86_64 / ARM64JDK 8 (x86_64) or JDK 17 (ARM64)
⚠️

The CPU architecture determines the JDK version

The JDK versions above are not alternatives: x86_64 / amd64 supports only JDK 8, while ARM64 / aarch64 supports only JDK 17. The node checks the architecture and JDK major version at startup and exits if they do not match. ARM64 support starts with java-tron 4.8.1.

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

RoleCPURAMSSDBandwidth
Fullnode16 cores32 GB3 TB+100 Mbps
Fullnode running as SR32 cores64 GB3 TB+100 Mbps
Lite Fullnode16 cores32 GBFew % of Fullnode, growing100 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 test

On 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 provides a Toolkit JAR that matches FullNode.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. Download the Toolkit JAR for your platform separately from the same release page and place it next to FullNode.jar. See Node maintenance toolkit for what each utility does.

2. Pick a configuration file

Each network has a default configuration:

NetworkConfigurationSource
Mainnetconfig.confprovided in framework/src/main/resources/
Nile testnetSee Nile network infocommunity-hosted
Shasta testnetNAThis is a closed testnet; third-party node participation is currently not supported.
Private chainCustom — see TRON private chainself-authored

Save the selected configuration as config.conf next to FullNode.jar.

If you are upgrading from an older release and need to preserve custom settings, follow the GreatVoyage-v4.8.2 configuration migration guide to merge them into the new configuration.

3. Start the node

Basic startup

Select the JDK and startup command for the host CPU architecture. The following examples use a host with 16 GB of RAM:

# x86_64 / amd64: JDK 8
java -Xms9G -Xmx9G -XX:+UseConcMarkSweepGC -jar FullNode.jar -c config.conf

# ARM64 / aarch64: JDK 17
java -Xmx9G -XX:+UseZGC -jar FullNode.jar -c config.conf

These commands are suitable for an initial startup and basic verification. For a long-running Mainnet node, use the complete JVM parameters below.

Recommended JVM parameters

The complete commands below are for a host with 16 GB of RAM and match the startup scripts in the java-tron source:

# x86_64 / amd64: JDK 8
java -Xms9G -Xmx9G \
  -XX:+UseConcMarkSweepGC \
  -XX:+PrintGCDetails -Xloggc:./gc.log -XX:+PrintGCDateStamps \
  -XX:+CMSParallelRemarkEnabled \
  -XX:ReservedCodeCacheSize=256m \
  -XX:+UseCodeCacheFlushing \
  -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m \
  -XX:MaxDirectMemorySize=1g \
  -XX:+HeapDumpOnOutOfMemoryError \
  -XX:NewRatio=2 \
  -jar FullNode.jar -c config.conf

# ARM64 / aarch64: JDK 17
java -Xmx9G -XX:+UseZGC \
  -Xlog:gc,gc+heap:file=gc.log:time,tags,level:filecount=10,filesize=100M \
  -XX:ReservedCodeCacheSize=256m \
  -XX:+UseCodeCacheFlushing \
  -XX:MetaspaceSize=256m \
  -XX:MaxMetaspaceSize=512m \
  -XX:MaxDirectMemorySize=1g \
  -XX:+HeapDumpOnOutOfMemoryError \
  -jar FullNode.jar -c config.conf
  • -Xms / -Xmx set the initial and maximum JVM heap. On hosts with at least 32 GB of RAM, set -Xmx to about 40% of physical RAM. On x86_64, use -Xms9G as a starting point and tune it against node load and monitoring data. The ARM64 startup script does not set -Xms by default.
  • ReservedCodeCacheSize sets the maximum JIT code-cache capacity; MetaspaceSize sets the initial threshold that triggers metaspace garbage collection; MaxMetaspaceSize caps metaspace capacity; and MaxDirectMemorySize caps NIO direct memory.
  • These recommended configurations use CMS GC and its legacy logging flags with JDK 8 on x86_64, and ZGC with unified logging on JDK 17 on ARM64. GC logs are written to a separate file, and a heap dump is generated on an out-of-memory error.
  • Every JVM option must appear before -jar; -c config.conf selects the node configuration file.

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 import

Use --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 delegated witness_permission to 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

java -Xms9G -Xmx24G -XX:+UseConcMarkSweepGC -jar FullNode.jar --witness -c config.conf
📘

This command targets the recommended 64 GB x86_64 / amd64 SR host. ARM64 / aarch64 requires JDK 17; when adapting the simplified command above, remove -Xms9G and replace -XX:+UseConcMarkSweepGC with -XX:+UseZGC. For production, retain -Xmx24G and --witness, and add the remaining options for the host architecture under recommended JVM parameters.

When 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/snapshot

    Use 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

A Lite Fullnode starts in the same way as a Fullnode and requires no additional Lite Fullnode startup flags. Select the JDK and startup command for the host CPU architecture. The following examples use a host with 16 GB of RAM:

# x86_64 / amd64: JDK 8
java -Xms9G -Xmx9G -XX:+UseConcMarkSweepGC -jar FullNode.jar -c config.conf

# ARM64 / aarch64: JDK 17
java -Xmx9G -XX:+UseZGC -jar FullNode.jar -c config.conf

For long-running deployments, use the complete command for the host architecture under recommended JVM parameters.

FullNode.jar detects the Lite Fullnode snapshot structure at startup and runs in Lite Fullnode mode.

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:

  1. Pull the latest release JAR.
  2. Stop the node cleanly (kill -15).
  3. Replace FullNode.jar (and Toolkit.jar if it shipped).
  4. 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.

The installation path of libtcmalloc.so.4 varies by Linux distribution and CPU architecture. After installation, run ldconfig -p | awk '$1 == "libtcmalloc.so.4" {print $NF; exit}' to print the path on the host, then use that path in LD_PRELOAD. If the command prints nothing, verify that the package is installed correctly. The paths below are x86_64 examples only:

DistributionInstallExample x86_64 path
Ubuntu 18.04 / 20.04 / Debian stablesudo apt install libgoogle-perftools4/usr/lib/x86_64-linux-gnu/libtcmalloc.so.4
Ubuntu 16.04 LTSsudo apt install libgoogle-perftools4/usr/lib/libtcmalloc.so.4
CentOS 7sudo yum install gperftools-libs/usr/lib64/libtcmalloc.so.4

Before starting the node, set these environment variables in the current shell:

# Replace this path with the path printed by the command above
export LD_PRELOAD="/usr/lib/x86_64-linux-gnu/libtcmalloc.so.4"
export TCMALLOC_RELEASE_RATE=10

Then run the command for the host architecture under recommended JVM parameters in the same shell.

Run 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 true

For 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.

ServiceConfig keyDefault
HTTP — Fullnodenode.http.fullNodePort8090
HTTP — Soliditynode.http.solidityPort8091
HTTP — PBFTnode.http.PBFTPort8092
gRPC — Fullnodenode.rpc.port50051
gRPC — Soliditynode.rpc.solidityPort50061
gRPC — PBFTnode.rpc.PBFTPort50071
P2P listennode.listen.port18888
ZeroMQ event publisherevent.subscribe.native.bindport5555
Backup peer portnode.backup.port10001
⚠️

Port access control

Except 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):

  1. Enable in config.conf:

    storage {
      balance.history.lookup = true
    }
  2. (Optional) Use a snapshot that contains historical balance data — see Fullnode snapshots. Without one, the node only has balance history for blocks it synced after enabling this flag; pre-flag history is lost.

  3. Start the node normally. The API begins responding once sync catches up.


Related resources