Run Pocket Nodes

In this section, you’ll get information on running a Pocket node.

These details are mostly for “intermediate” node runners, who are familiar with running full nodes and have the knowledge required to avoid getting lost. If you would like a more beginner’s tutorial, visit Zero To Node. You may also want to explore node-hosting services.

Want to understand the economics of running a Pocket node before you dive in? Read about Node Economics.

Read our guide to decide whether you want your Pocket nodes to be operated with custodial staking or non-custodial staking.

For a no-frills guide to commands, you should head over to Pocket Core on GitHub.

Environment Setup

This section will detail the hardware and software needed to run a Pocket node.


Hardware Requirements: 4 CPUs/vCPUs | 16 GB RAM | 500GB Disk


These are just the hardware requirements for your Pocket node. You’ll also most likely be running the full nodes of other blockchains, which will have their own hardware requirements.


There are three ways to install the software you need to run Pocket Network:


Install your dependencies:

Create source code directory:

mkdir -p $GOPATH/src/ && cd $GOPATH/src/

Download the source code of Pocket core:

git clone && cd pocket-core

Checkout the latest release of Pocket core:

git checkout tags/<release tag>
git checkout tags/RC-0.9.2

Make sure you have your $GOPATH environment variable set correctly:

echo $GOPATH

Build from source and place the build in the $GOPATH/bin directory:

go build -o $GOPATH/bin/pocket <Source code directory>/...
go build -o $GOPATH/bin/pocket $GOPATH/src/

Test your installation:

pocket version
AppVersion: RC-0.9.2

You can find the latest release on the Pocket Core GitHub pagee.


You can also use Homebrew to build Pocket Core instead of building from source.

Install your dependencies:

Install using Homebrew:

brew tap pokt-network/pocket-core && brew install pokt-network/pocket-core/pocket

Test your installation:

pocket version
AppVersion: RC-0.9.2


See Pocket Core Deployments on GitHub for details on how to install using Docker.


  • Reverse Proxy: For SSL termination and request management
  • Ports: Expose Pocket RPC (Default: 8081) and P2P port (Default: 26656)
  • SSL Cert: Required for validator’s serviceURI

Set open files limit

ulimit -Sn 16384

The value of ulimit -Sn should be set to greater than or equal to the sum of the following:

  • Maximum inbound peers
  • Maximum outbound peers
  • Maximum open connections
  • gRPC maximum open connections
  • Desired concurrent Pocket RPC connections
  • 100 × Constant number of Write-ahead Logging, database, and other open files

This limit is set based on the standard configuration provided with Pocket Core in <POCKET_DATADIR>/config/config.json. If you modify your config, you will need to ensure that you modify your open files limit as well.

Secure your server

Make sure the server that hosts your node is protected by up-to-date anti-virus and anti-malware software, as well as a firewall.

Your node’s private key will be available in plaintext on the server, so your key is only as secure as your server.

Pocket Node Setup

Once you have your environment set up, you are now ready to deploy your node.

Create an account

An account is needed to participate at any level of the network.

pocket accounts create
> Enter Passphrase
> Account generated successfully:
> Address: <address>

Alternatively, you can create your account using the Wallet app, then use the encrypted import command to import the account into your node environment:

pocket accounts import-armored </path/to/ppk.json>

Backup the account

Backup your private key to an encrypted and ASCII armored JSON file, to the specified --path , using the export option. You will be prompted for the decrypt passphrase and an encryption passphrase for the exported account. You will also have the option to add a hint to help remember your passphrase.

pocket accounts export <address> --path <path>
pocket accounts export 59f08710afbad0e20352340780fdbf4e47622a7c --path $HOME/super-secret-dir

Do not use your node’s account as your personal account address. Since the node’s private key is stored in plaintext on the server, the key is as secure as your server is. Regularly sweep your node’s rewards and transfer them to a more secure account stored offline.

Learn more about securely managing your POKT accounts.

Fund the account

To stake a node in Pocket Network, the account must have a balance above the minimum stake, which is 15,000 POKT (or 15,000,000,000 uPOKT).


We recommend staking more than the absolute minimum node stake of 15,000 POKT (such as 15,100) as a reasonable buffer against operational slashes which can occur on even properly configured nodes as well as misconfigured and misbehaving ones. If slashes cause your node stake to drop below 15,000, you node will be forcibly unstaked.

Send POKT with the following command:

pocket accounts send-tx <fromAddr> <toAddr> <uPOKT amount> mainnet 10000 "tx message"

You won’t be able to send POKT using the command line until you have your node set up. Until then, you can use the Wallet app.

If you’re using the testnet, you can fund your account using the Testnet Faucet.

Set the account operator

pocket accounts set-validator <address>

Check that the command was successful with pocket accounts get-validator

Set Relay Chains

A Relay Chain is a blockchain that a Pocket node connects to or runs in order to service applications. Applications access Relay Chains through the serviceURI, the endpoint where nodes publicly expose the Pocket API. You can view a list of all the Relay Chains that Pocket supports.

Once you have your Relay Chains properly configured, you can set up your node to serve requests to those Relay Chains via the generate-chains command. Relay Chains are referenced through a four digit ID (example: 0021 for Ethereum Mainnet).


Relay Chain IDs can be found here.

pocket util generate-chains

A wizard will step you through the process of adding each Relay Chain ID, and will output a $HOME/.pocket/config/chains.json file when done.

If you were only servicing Pocket nodes, the response would look like this:

> Enter the chain of the network identifier:
<Relay Chain ID> (Example: 0001)
> Enter the URL of the network identifier:
<Secure URL to Relay Chain>
Would you like to enter another network identifier? (y/n)

Setup the Genesis Configuration File

Genesis files can be found here:

The appropriate genesis file should be placed at .pocket/config/genesis.json

mkdir -p $HOME/.pocket/config
curl -o $HOME/.pocket/config/genesis.json
mkdir -p $HOME/.pocket/config
curl -o $HOME/.pocket/config/genesis.json

Test your node

Test that your node is configured correctly by simulating a relay.

pocket start --simulateRelay

Then send a curl request to your validator URL http://<your node>:<your pocket rpc port>/v1/client/sim to test if your node responds.

curl -X POST --data '{"relay_network_id":"<relay chain ID from chains.json>","payload":{"data":"{\"jsonrpc\":\"2.0\",\"method\":\"eth_getBalance\",\"params\":[\"0xe7a24E61b2ec77d3663ec785d1110688d2A32ecc\", \"latest\"],\"id\":1}","method":"POST","path":"","headers":{}}}' <your node URL>:8081/v1/client/sim

If successful, you’ll see a 200 OK response. If you see a 400 Bad Request, you either have incorrect/missing parameters in the request or bad formatting in the data field.

Finally, stop your node with Ctrl-C. If you don’t, you’ll be leaving –simulateRelay running, which means anyone will have unfiltered access to your node.

Download snapshot

Downloading from the latest snapshot will drastically shorten the time it takes to sync the blockchain. The easiest way is by downloading with wget and extracting the archive as it downloads.

mkdir -p $HOME/.pocket/data
wget -qO- | tar -xz -C $HOME/.pocket/data

Other options for downloading the latest snapshot can be found in the pocket-snapshotter repo.

Sync the blockchain

pocket start --seeds=<seeds> --mainnet
pocket start --seeds="" --mainnet

See the section on seeds for more details.


Ensure the node is all the way synced before proceeding to the next step.

Stake the node

Stake the account to participate in the network. Staking as a servicer node locks up POKT tokens that can be burned as a security mechanism for bad acting.

pocket nodes stake custodial <address> <amount> <relay_chains> <serviceURI> mainnet 10000 false
pocket nodes stake custodial 3ee61299d5bbbd2974cddcc194d9b547c7629546 20000000000 0001,0002 mainnet 10000 true

You should at least 1 POKT unstaked to pay the transaction fees for your node’s claim and proof transactions.

All node runners must always maintain a liquid (unstaked) balance of at least 0.02 POKT in order to submit the claim and proof transactions (which each have a transaction fee of 0.01 POKT) that generate their rewards. If a node successfully submits both the claim and proof, they will earn enough POKT to submit the next claims and proofs, and so on. However, if a node falls below a liquid balance of 0.02 POKT, their revenue will be halted.

Claim transactions have 3 sessions, the ClaimSubmissionWindow, to be successfully submitted after the conclusion of the session in which the work was done, otherwise they are lost. If a claim transaction fails, Pocket Core will auto-repeat the transaction once in each new session, until the claim is lost. This means your node will automatically take 3 attempts to submit the claim. There is a claim submission window because the global secret key that determines the required proof leaf is revealed once that window closes. Extending the claim submission window would delay the time at which the corresponding proof can be sent and rewards earned.

If you manage to successfully submit the claim transaction, you then have 120 blocks, the ClaimExpiration period, to submit the corresponding proof transaction, otherwise the pending claim expires. There is a claim expiration date because otherwise the claims would remain in the state and bloat the blockchain.


Bad Behavior Warning: Pre-staking

Pre-staking is the act of a node runner staking on a RelayChainID prior to spinning up the RelayChain node. This behavior has an extremely negative impact on the quality of service for new chains due to apps being matched in sessions with Pocket nodes that don’t actually have RelayChain nodes connected to them. If you do this, your node will be challenged and slashed. You should always deploy your RelayChain node and simulate relays before staking your Pocket node for the RelayChainID.


Staking a node successfully will earn you a trophy which can help you ultimately earn a vote in the DAO. Learn more about how to claim your vote.

Custodial and Non-Custodial Staking

Pocket has the ability for node runners to set up their nodes to run with “non-custodial” staking. This means that the Pocket address that is associated with staking and running the node is not the recipient of the funds once the node is unstaked.

This feature was activated as of version

Node runners who staked their nodes prior to activation of non-custodial staking will have one opportunity to decide if they want their nodes to have custodial or non-custodial staking. After this point, if they wish to switch between the two options, they will need to unstake/restake their node.

Custodial staking

Custodial staking is the process of having the operator of the node be the recipient of the rewards of that node. This is true regardless of whether the node is a servicer or a validator.

In this scenario, only one Pocket account is needed to run a node. This account handles all aspects of node maintenance such as staking, editing the stake, unjailing, and unstaking.

Prior to activation of non-custodial staking, this was the only option that node runners had.

Non-custodial staking

Non-custodial staking is the process of having the operator of the node be a different account from the account that receives the rewards.

In this scenario, there are two Pocket accounts necessary to the staking of a node: the operator account and the output account.

The operator account is the account from which the staked POKT is taken. The operator account also acts as the signer for claims and proofs, as well as block proposals and attestations, and so needs to have some POKT remaining in the account to pay for those transactions.

The other account, known as the output account, is designated to receive the staked POKT when a node is unstaked, as well as receive all of the rewards generated by that node. The rewards generated by the node will be sent to the output address and will be available immediately. Only the initial stake itself is locked.

Both the operator and output accounts can perform the staking and also any and all node maintenance (unstake, unjail, etc.).


The output account can’t be changed after staking, so it is vitally important to both make sure your output account is set correctly in the staking command, as well as to ensure access (keys) to that output account.

Failure to do both of these tasks will result in all rewards and staked funds being sent to an inaccessible account and lost forever! It is not possible for the operator account to receive staked POKT or rewards in a non-custodial configuration.

Benefits of non-custodial staking

An operator address must reside in a “hot” wallet on the node. This could potentially represent a security risk when the server is operated by a third-party. As third-party node hosting is common, there has arisen a need to have the recipient wallet for rewards not be on the same server as the node.

Non-custodial staking allows for this scenario. All you need to specify is the wallet (“output”) address, which is denoted when staking the node. The wallet can reside off the server.

Another benefit to non-custodial staking is the ability to pool rewards into a single account. Since each node has to have a distinct operator account, this would previously have resulted in rewards being split across multiple wallets, which is inconvenient for a node runner with many nodes.


The command for staking a node was updated when non-custodial staking was activated. Please see below for the updated command syntax.

Custodial staking:

pocket nodes stake custodial <operatorAddress> <amount> <relayChainIDs> <serviceURI> <networkID> <fee> <isBefore8.0>
pocket nodes stake custodial 0123456789012345678901234567890123456789 15100000000 0001,0021 mainnet 10000 false

Non-custodial staking:

pocket nodes stake non-custodial <operatorPublicKey> <outputAddress> <amount> <RelayChainIDs> <serviceURI> <networkID> <fee> <isBefore8.0>
pocket nodes stake non-custodial 0123456789012345678901234567890123456789012345678901234567890123 0123456789012345678901234567890123456789 15100000000 0001,0021 mainnet 10000 false

Some notes on these commands:

  • The parameter custodial or non-custodial sets this permanently on your node. You can’t change this later unless you unstake.
  • The parameter <isBefore8.0> is boolean. It was set to be a transitional variable to denote whether or not the non-custodial activation has occurred. As this feature is now active, you will need to set this to false.
  • Be aware that the non-custodial command takes the operator public key as the argument (<operatorPublicKey>), not the operator wallet address like in the custodial command. The reason why the public key is used and not the address is for the situation where the owner of the output address is doing the staking, but does not also have ownership of the operator account. In this case, they may only have the public key for that account.
  • The non-custodial command adds <outputAddress> as the recipient of the staking rewards.

For more information on the full usage of these commands, including all parameters, please see the Pocket Core docs.

Important for existing nodes

If you have a node that was staked prior to the activation of non-custodial staking, you have only one opportunity to switch to non-custodial staking.

Any Pocket node command successfully issued (for example, to adjust the stake) will “lock” the node into custodial, unless a non-custodial command is issued with a valid output address. Following this, the only way to switch between custodial and non-custodial is to unstake/restake the node (and recall that there is a 21 day unstake period).

Important for all nodes

Be very careful entering the output address. You cannot change the output address after it is set. If you accidentally mistype the output address, your funds and your stake will be sent to that address and will be lost forever.

If you wish to change your output address, you can first unstake the node, and the rewards will be sent to that address. Then you can restake the node with a new output address.


Make sure the operator account has some POKT left after staking, as it will still be responsible for ongoing claim and proof transactions, which each carry a 0.01 POKT transaction fee.


The unstaking process is the same using custodial or non-custodial staking.

pocket nodes unstake <operatorAddr> <fromAddr> <networkID> <fee> <isBefore8.0>
pocket nodes unstake 0123456789012345678901234567890123456789 0123456789012345678901234567890123456789 mainnet 10000 false

During the unstaking process, a transaction is not generated when sending the staked POKT to the output address. This is intended behavior, and is similar to how proofs work on the blockchain.


This lack of transaction happens regardless of whether you are using custodial or non-custodial staking, but in the case of custodial staking, there is no ambiguity on where the staked POKT is being sent.

In order to verify that your POKT is where it should be, we recommend querying the blockchain directly, instead of relying on a block explorer service that may not interpret the results accurately.

You can use the interactive API Docs to query the balance for an address at a given block height. Try it here.

More information


LeanPocket (sometimes stylized as “LeanPOKT”) is a configuration that enables multiple Pocket instances to run on a single process, allowing node runners to consolidate resources, resulting in better scalability and reduced hardware costs.

LeanPocket is a feature available from version 0.9.2 and above.


Pocket Core is a multi-threaded application, however, historically it has only allowed for one node per process. This means that if you wanted to run multiple Pocket nodes on the same server, each node, running its own isolated process, would each use their own resources: RAM, disk space, network throughput, etc. As many aspects of nodes use shared resources (copies of the blockchain, most notably) this was deemed very inefficient.

For example, at the time of writing, a Pocket node requires a minimum of 500GB of disk space and 16GB of RAM, and that’s not including the requirements of the other chains the node may be servicing.

LeanPocket is an optimization to the core client to allow nodes to share resources, significantly reducing resource requirements. This is a non-consensus-breaking change to the client.

The following charts show the benefits of implementing LeanPocket in your node fleet, though individual results will vary.

Storage requirements: LeanPocket versus normal client

RAM usage: LeanPocket versus normal client


LeanPocket is specifically geared toward multiple nodes running on the same server. If you are running a single node, or wish to keep each of your nodes running on different servers, LeanPocket will not have any benefit or effect.


To enable LeanPocket:

  1. Create a new lean_nodes_keys.json file inside your Pocket configuration directory (typically .pocket).

  2. Format the file with a JSON array of your node’s private keys:

      { "priv_key": "<PRIVATE_KEY_1>" },
      { "priv_key": "<PRIVATE_KEY_2>" }
  3. Set/update your validators:

    pocket accounts set-validators <path/to/lean_nodes_keys.json>

    Note the plural form in the command. The option set-validators is distinct from set-validator and is only relevant for LeanPocket.

  4. Edit your node’s config.json file to add lean_pocket: "true"; in the pocket_config block.


    In some cases, the lean_pocket option may already be added to your config.json file, so make sure to search for it before potentially adding a duplicate value. If you find lean_pocket: "false"; change it to "true".

  5. If you run a script that starts the Pocket service, add --keybase=false to the pocket start command.

  6. Edit your proxy settings such that the /v1 endpoint is publicly accessible for every one of your nodes.


    Failure to do this will prevent your nodes from broadcasting the correct version, which will interfere with consensus-related upgrades. When properly configured, all of your nodes should output the current version of Pocket Core on the /v1 endpoint.

  7. Restart your Pocket service, making sure to add the --keybase=false option.


  • Using --forceSetValidators as an argument when starting Pocket will ensure that your validators are updated every time the process starts. If using this argument, you won’t have to use the set-validators command when you update your lean_node_keys.json file.

  • Do not use --useCache as an argument when starting Pocket, as it can delay restarting your node.

  • You can get a list of node with the get-validators command:

    pocket accounts get-validators
  • You can add metadata to your lean_node_keys.json file for organizational purposes:

          "priv_key": "<PRIVATE_KEY_1>",
          "node_name": "first example"


When the Pocket Core process first starts, if LeanPocket is activated, it will try to initialize an evidence and session cache for each node.

Therefore, you will see output like this in the logs:

Initializing {node address 1} session and evidence cache
Initializing {node address 2} session and evidence cache
Initializing {node address 3} session and evidence cache
Initializing {node address 4} session and evidence cache

Considerations and Risks

  • Because your nodes are commingling resources with LeanPocket, there is a risk of downtime on all of your nodes simultaneously. Depending on your risk for downtime, we recommend that you institute some form of failover system for your nodes, or perhaps divide your nodes into multiple LeanPocket-managed groups.
  • Since all LeanPocket nodes use the same configuration, it is not possible to serve different groups of chains on each individual node. Each node uses the same chains.json file.
  • If you are converting your node fleet into using fewer servers (or just one), you will want to ensure that your server open file limit (ulimit and fd on Linux-based systems) is sufficient, as these values still scale linearly with each additional node.
  • We don’t recommend running Validator nodes via LeanPocket at this time, because of the increased importance of the consensus state on the network.
  • Be aware that without LeanPocket, there is a one-to-one correlation between a node and its Peering ID, so when you use set validator, it will set the Peering ID to be the validator. However, with LeanPocket, the first node in the list is your Peering ID for every node managed by LeanPocket.

Updating Your Node

It is very important, both for network security and for performance of your own node, to keep your Pocket node up-to-date with the latest version of the Pocket software. The following steps will show you how to update your Pocket node.

Release-specific changes

Each release may have specific modifications you need to make. This is just a general guideline for the steps you’ll typically take to update your node. Check the release notes for release-specific details.

Shutdown Pocket Core

Stop your Pocket Core instance running by submitting the shutdown command.

pocket stop

Once you shutdown Pocket Core, you will have 4 blocks (60 minutes) to complete the update and start Pocket Core again before your node gets jailed for downtime.

Backup blockchain data

Backing up your blockchain data will ensure a faster resync when you restart your node.

Navigate inside your $HOME/.pocket/ dir and save data/ (the entire directory):

cp -r ~/.pocket/data ~/backup/data

In the event of a corrupted database you can delete the bad data rm -r ~/.pocket/data and replace it with your backup cp -r ~/backup/data ~/.pocket/data.


If you don’t have a backup, a temporary backup datadir may be provided alongside a release.

Ensure the latest Go version

Check your golang version. The release notes will specify which version it should be.

go version

If you need to update Go, use this guide.

Alternatively, if you use g, you can just run

sudo apt-get update
g install <version number>

Checkout latest Pocket Core


Navigate into pocket-core directory

cd ~/go/src/

Check out the latest release:

git pull
git checkout tags/RC-0.9.2

Rebuild the binary:

go build -o $GOPATH/bin/pocket ./app/cmd/pocket_core/main.go


Pull the latest tap:

brew upgrade pokt-network/pocket-core/pocket


Pull the latest container image:

docker pull poktnetwork/pocket-core:RC-0.9.2
docker pull poktnetwork/pocket:RC-0.9.2

Update config.json

Run the update-configs command, which creates a new config file ($HOME/.pocket/config/config.json) and backs up the old config file ($HOME/.pocket/config/config.json.bk).

pocket util update-configs

You’ll need to manually compare your backup file with the new file to copy over your personal config details.

Start Pocket

Start pocket running again.

pocket start

You can then test your node.

Automated Deployments

The following services can help automate your node deployments:

Warning: Use at your own risk. These links are not directly associated with Pocket Network and do not constitute an endorsement, guarantee, warranty, or recommendation by Pocket Network, Inc., Pocket Network Foundation, or the Pocket DAO. Do conduct your own due diligence before deciding to use any third party services.

Node-Hosting Services

If you are interested in staking your POKT in a node but don’t have the time or technical know-how, below you will find a link to the available options to have your node operated by a third-party.

If you don’t have enough POKT for the minimum node stake, you should consult this Overview of Pooling Services.

Warning: Use at your own risk. The appearance of third party descriptions and hyperlinks on the above linked sites does not constitute an endorsement, guarantee, warranty, or recommendation by Pocket Network, Inc., Pocket Network Foundation, or the Pocket DAO. Do conduct your own due diligence before deciding to use any third party services.


Seed nodes enable newly configured Pocket nodes to find peers on the network and store them in their local address book.

You can use the --seeds flag when starting the Pocket process to set the seeds for your Pocket node. Alternatively, you can set the seeds in your config.json file under the "P2P" block.



To start Pocket Core on mainnet, using all the above seeds:

pocket start --seeds=",,,,,,,,,,," --mainnet



To start Pocket Core on testnet, using all the above seeds:

pocket start --seeds=",,,,,,," --testnet

Pocket Node FAQ

The following sections contain common questions regarding running Pocket nodes.

Node Configuration

Node Troubleshooting

Maximizing your Pocket rewards

Node Configuration

Does my blockchain node need to be synced before I start my Pocket node?

Yes. Every node on the Pocket Network needs to have the most up to date information of the blockchain they are supporting. If you start joining sessions before your node has caught up to the current block height, you will be returning incorrect data, and if incorrect data is being returned, your node will be slashed.

How many blockchains can one node support?

Your node can support up to the number of chains defined by the MaximumChains parameter. This limit is not definitive and can be changed by the DAO.

Can I add a load balancer address in my chains.json if I have multiple blockchains under one domain?

Yes you can! Just make sure you have the necessary ports open to be able to successfully send relays to the proper network.

How can I add more blockchains to my node?

Add the new RelayChainIDs to your chains.json file, then run the stake command again for your node. Since you’re already staked, running the command “updates” your staking configuration.

Find the RelayChainIDs here.

Can I continue earning POKT while I’m unstaking?

No, for the duration of the unstaking process as determined by the UnstakingTime parameter, your node will not be eligible for sessions.

Do each of my nodes need a unique IP address?

You need a dedicated domain for each node, but the nodes can be on the same machine, behind the same IP address. It would take properly configuring your Reverse Proxy and Firewall/Router, but it can be done.

How do I set my ulimit?

As a best practice, do not use root to run the pocket process. When you set the ulimit for your instance, it’s important to set it in the user profile that is running the pocket-core instance.


Make sure that you’re setting the ulimit for the specific account that’s running the pocket process.

Configuring the ulimit system-wide might vary depending on your OS. Here’s a basic tutorial on increasing the open files limit on Linux.

To calculate the ulimit, you will have to define a few parameters as shown below:

({ulimit -Sn} >= {MaxNumInboundPeers} + {MaxNumOutboundPeers} + {GRPCMaxOpenConnections} + {MaxOpenConnections} + {Desired Concurrent Pocket RPC connections} + {100 (Constant number of wal, db and other open files)}


  • ulimit -Sn: = is a soft number of open files that need to be open
  • GRPCMaxOpenConnections = is the number of RPC connections connections your node can relay
  • MaxOpenConnections = max number of connections you want your node to service

You will need to increase your ulimit to the calculated number. To do so, go into your .bashrc in your $HOME dir and enter:

ulimit -Sn 16384

Once you save your file, enter:

source ~/.bashrc

What do I do if my node needs to go down for an extended period, such as during a machine migration?

To opt out of being selected for work, you should deliberately jail your node, which lets the network know you are not ready to receive any relays. Once the machine is back up and running, you can unjail your node again.

Can I change the output address for my node when doing non-custodial staking?

You can’t edit an existing output address for your node stake. You will have to instead unstake your node and then restake with a different output address. Keep in mind that when you unstake, your staked POKT will be sent to the output address you originally set when staking your node, so make sure you have access to that account. Learn more about non-custodial staking.

Why don’t I see a transaction on the blockchain when I unstake my non-custodial node? How do I know my POKT is being sent to the output address?

Unstaking a node will not yield a separate transaction on the blockchain, so to verify that the POKT was sent to the output address, you will need to query the blockchain manually. Learn more.

Node Troubleshooting

Why is my node not earning POKT?

See the section below on Maximizing your POKT earnings.

How do I check my Pocket node status?

Make sure your node is connected to the network by executing:

curl http://<your node ip>:26657/status

Lookout for latest_block_height and latest_block_time to make sure it’s updated to the current time in UTC.

Example Output:

  "jsonrpc": "2.0",
  "id": "",
  "result": {
    "node_info": {
      "protocol_version": {
        "p2p": "7",
        "block": "10",
        "app": "0"
      "id": "4930289621aefbf9252c91c4c729b7f685e44c4b",
      "listen_addr": "tcp://",
      "network": "pocket-testet-playground",
      "version": "0.32.7",
      "channels": "4020212223303800",
      "moniker": "pocket-core-testnet-55f59f6c8-5njbx",
      "other": {
        "tx_index": "on",
        "rpc_address": "tcp://"
    "sync_info": {
      "latest_block_hash": "090C3B9C3B9F1BB10C6825D5230A45759E19A9BCC1503B80314F93B69162C712",
      "latest_app_hash": "AB5838AA434FD36B48B759E62C596F4145F4C086B07FB45D2CCFCFFF21F5F937",
      "latest_block_height": "49",
      "latest_block_time": "2020-02-10T23:17:59.161691821Z",
      "catching_up": false
    "validator_info": {
      "address": "4930289621AEFBF9252C91C4C729B7F685E44C4B",
      "pub_key": {
        "type": "tendermint/PubKeyEd25519",
        "value": "9i9322nUSMG1bzVAxjPylNI8za8AK/azdtBYoAtRz6o="
      "voting_power": "1000"

I keep getting “too many open files” when my node is syncing? What does this mean?

This means that your ulimit is set too low on your node. Find instructions on how to set your ulimit above.

Why does my node keep crashing?

Your node can crash due to the following reasons:

  1. Having too many open files: Make sure your ulimit is set correctly on your user profile. Find instructions on how to set your ulimit above.
  2. Resource limitations: Make sure your node meets the minimum hardware requirements for both a Pocket node and the blockchain nodes you’re servicing. Details are above on this page.

Will my node be slashed for downtime?

There are negligible burns at this stage of the network, determined by the SlashFractionDowntime parameter. As the network matures, the rate will probably be increased to push for better service.

Maximizing your Pocket rewards

So you’ve spun up your Pocket node but you’re not earning as much as you thought you would. On this page, we debunk some common misconceptions and explain how to maximize your earnings.

My node is functional but doesn’t seem to be earning POKT - is it configured incorrectly?

There are a couple of reasons why your node may not be rewarding you with POKT. There are many great community members and Pocket teammates that are eager to help you triage this, but first, ask yourself, “is your node configured correctly?”. Don’t assume it is. Use the troubleshooting steps listed above.

The next thing to check is if your node is offline or jailed…or both. Reasons include:

  • Returning incorrect data
  • Missing blocks
  • Being offline
  • serviceURI is not publicly reachable

If you suspect that this may be happening to your node, you can do a historical search on your nodes. We have a great community member who created this script to help you determine how long you were jailed for a specific period of time.

Checking your node status is one of the first steps towards maximizing your POKT earnings.

Conversely, how will I know if my node is working correctly?

Checking the block height is the easiest way to know if you’re synced up to the network. You can simply query your node to get this height and compare it to the latest block displayed on the Explorer.

pocket query height

The above command tells you if your Pocket node is synced up, but you’re probably running at least one other node for the external blockchains (referred to on this page as blockchain data nodes) that you’re serving to apps. You should make sure these are also synced up to their respective networks.

For example, you can check the block height of your Geth Ethereum node by submitting this query to your node, which returns the latest height of geth-mainnet known by the node.

curl --request POST --header 'Content-Type: application/json' --data-raw '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":83}' --user [authentication] [GETH NODE URL]

When will I find out if I have made POKT rewards?

To check if you’re earning rewards, you can simply monitor the balance of your node.

pocket query balance <address>

This way is very manual and you would need to track your balance over time to understand the change in the amounts.

The good news is there are several options for tracking your node rewards such as POKT ROKT, which tracks the last 24 hours of earnings in its CLI dashboard, or Sandwalker which tracks historical rewards by day and month.

Why don’t I just connect my Pocket node to [insert third-party provider here]?

On the surface, this seems like a great idea. Use a free tier of another service (e.g. Infura) and you don’t have to pay for any blockchain data node costs.

First off, free tiers by third-party providers are capped, which limits your upside. To make matters worse, if you use a third-party provider instead of running your own blockchain data node, you won’t make enough POKT to cover the server costs of your Pocket node.

Plus, that doesn’t jive with our ethos now, does it?

Why wouldn’t I make enough POKT with a third-party?

Using third-party providers slows you down. Slower nodes make less revenue.

Why does the third-party slow you down? Increasing the distance between your Pocket node and the third-party blockchain data node increases the number and length of hops that an end-user’s request has to make.

Here is an illustration:

In this example, the Pocket nodes (pink) are on the other side of the US from the Blockchain data nodes (orange). The end-user is using the Portal to communicate with the network. The path the end-user’s request must take is: End-user → Portal → Pocket Node → Blockchain Data Node → Pocket Node → Portal → End-user

The end-user’s request must hop back and forth across the US 4 times and that’s not including the hops between the user and the Portal. As a result, it may take up to 1 second for a user to receive something as simple as a balance query. That’s not very good service.

Aren’t there data centers around the world for this exact reason?

Correct. However, this works against you in this scenario.

Most third-party providers will have their servers in standard cloud regions situated around the world labeled such as East, West, EU, and Singapore. Load balancers are standard. For example, if a user is in Australia, they will be redirected to the nearest server in Singapore.

The challenge with using a third-party provider for your blockchain data node is that, by default, your Pocket Node will not always be in the same data center or machine as the third-party blockchain data node. If your Pocket Node is in US West, while you may have lesser latency from users who are hitting those servers, your node will never be as fast as it could be.

Your node will likely be in a different datacenter, where even a couple of hops will add somewhere between 30ms - 50ms. This becomes exacerbated when a user is coming from US East or the EU. With a full node on US West, you’re adding up to 200ms per request for these users.

Why does the latency matter?

While Pocket Network doesn’t discriminate (yet) between the speed of requests, the Portal does. The Portal filters out slow nodes to ensure the protocol is providing the best service possible to apps.

The vast majority of the requests on the network today come through the Portal. This means that faster nodes = more POKT.

In the long run, your setup matters not only for your earnings but also for ensuring a quality service for end-users (which will ultimately be crucial for the growth of the network).

Then how can I maximize my node revenue?

The following are some best practices that will give you an edge over the majority of node runners.

  • Know where the users are located… and locate your nodes accordingly. The Pocket Portal is currently in US-West-2, US-East-2, EU-West-1, AP-SE-1. The most underserved geographic area on Pocket is currently the Asia Pacific region.
  • Minimize the distance between your Pocket Nodes and your blockchain data nodes. Having your blockchain data nodes next to your Pocket nodes in the same rack is ideal.
  • Load-balance your blockchain data nodes.
  • Use a Peering Tower to reduce P2P gossip on the network. Visit the 🤖node-runner channel on Discord for more information.
  • Use physical hardware at home or data centers; you will have faster nodes and lower costs over time by owning your hardware and co-locating it.
  • Monitor your nodes for both health and sync – being online is only the first step, you must keep your blockchain data nodes in sync or they will not service relays.
  • Use services like the Performance Explorer to monitor your node’s performance in comparison to other nodes.

Why does the balance of an address change when there are no transactions in a given block?

This happens when an address is also a Validator. Validators earn block rewards when they are a proposer for a given block. Block rewards aren’t claimed through transactions, but instead are sent directly to the address.

This is inherited behavior from Tendermint and the Cosmos SDK, from which Pocket was originally derived. It is considered “core business logic” for the chain, and therefore does not need to be a transaction. That said, there are plans to change this behavior in v1 to increase transparency and visibility into block rewards.

To see how this works, take the address 85efd04b9bad9da612ee2f80db9b62bb413e32fb. At block height 4406, the balance for that address was 1848.257793 POKT, as you can test below using cURL (or using the API docs):

curl -H "Content-Type: application/json" -d '{"height": 4406, "address": "85efd04b9bad9da612ee2f80db9b62bb413e32fb"}' -X POST
 "balance": 1848257793

But for the subsequent block, the balance was 1853.342684 POKT:

curl -H "Content-Type: application/json" -d '{"height": 4407, "address": "85efd04b9bad9da612ee2f80db9b62bb413e32fb"}' -X POST
 "balance": 1853342684

You can verify that there are no transactions associated with that address in block 4406.


There isn’t a straighforward way to do this natively within Pocket at the moment. You would have to query all of the transactions for a given block and then search through them for the address in question. We plan to make this easier in the future.

Finally, you can see that this address was the proposer for block 4406:

curl -H "Content-Type: application/json" -d '{"height": 4406}' -X POST | jq '.block.header.proposer_address'

So in this case, the balance of the address is altered, but without a visible transaction.

Node Tutorials

This section contains tutorials for various actions a typical node user may wish to undertake.

The following tutorial, Zero To Node, wlil show you a step-by-step way to set up a Pocket Node on hosted hardware.

Zero To Node

Welcome to Zero To Node! This is a step-by-step guide for setting up a Pocket node. While there are many different ways to set up a node, the focus of this tutorial is on keeping things simple and with the minimum of steps, while still focusing on security and stability.

This guide is broken down into five parts:


The main utility of a Pocket node is to relay transactions to other blockchains. So, Pocket nodes need access to other nodes for the blockchains they’ll be relaying to. However, the focus of this guide is just on setting up a Pocket node that will relay to the Pocket network, essentially, through itself. Setting up nodes for other blockchains such as Harmony, Ethereum, or any of the other supported blockchains is beyond the scope of this guide.

After completing the steps outlined here, you’ll have a fully functional Pocket node up and running. If you choose, you can also opt to stake your node and earn rewards. We’ll cover that here, but staking is not required unless you want to earn rewards.

Who is this guide for?

This guide is for anyone interested in running Pocket nodes. While the goal is to keep things simple, the assumption is that you have some general blockchain and computer networking knowledge, and some Linux terminal experience.

What you’ll need

In order to complete this guide, you’ll need:

  1. A server connected to the internet
  2. A domain name
  3. The ability to add DNS records for your domain
  4. 15,100 POKT (if you want to stake your node)
  5. About 2-4 hours to complete and test everything

Part 1 – Server setup

This section will help you set up and configure a server to prepare it for being a Pocket node.

Setup a server

The first thing you’ll need to run a Pocket node is a server. For this guide, we’ll be using a virtual machine on the Linode cloud service, but you can use any cloud service you like, or run a server of your own.


Pocket has no affiliation with Linode and does not recommend any one provider over another. The general steps outlined here should work for most cloud providers.

Let’s start by creating a Linode instance (a virtual machine).

Create a Linode instance

To create a Linode instance, do the following:

  1. Sign up for a Linode account and login.

  2. Create a new Linode with the following specifications:

    • Image / Distribution: Ubuntu 20.04 LTS
    • Region: Atlanta, GA
    • Linode Plan: Dedicated 16 GB - 8 CPU, 320 GB Storage, 16 GB RAM
    • Linode Label: pokt001
  3. Wait for the Linode to be created and show up as running in the web interface.


For a more detailed guide on setting up a Linode instance, see the Linode docs. Also, note that the Atlanta, GA region was selected for this guide because it supports NVMe storage which is preferable for running nodes. Check to see which other regions support NVMe storage.

Add a storage volume

The Pocket blockchain is very large and growing all the time, and the snapshot we’ll be downloading in a later step is too large to fit on this Linode instance.

Because of this, we’ll need to create a secondary storage volume. We recommend a size of at least 500GB, but as this requirement will keep growing, a larger volume size (or a dynamically adjustable disk size) will be important.

  1. In your Linode account, click Volumes and then Create Volume.

  2. Create a volume with the following specifications:

    • Label: poktuserdir
    • Size: 800GB
    • Region: [Same as your instance]
    • Linode: pokt001

Configure DNS

Now that the Linode instance is created and running, you’ll need to set up a DNS record that points to the IP address of the Linode instance.

Pocket nodes require a DNS name. DNS (Domain Name Service) names are used to map an IP address to more human-friendly names. So rather than referencing a server with an address like we can use a name like


Most domain registrars allow you to add DNS records. Please refer to the DNS setup documentation for your provider.

Specifically, you’ll need to add an A record for the domain name. For the exact steps, consult the DNS documentation for your provider. Then create a record with the following information:

  • Name: pokt001
  • Type: A
  • Value: [Linode_IP_Address]
  • TTL: 300

After setting up your DNS record, wait a few minutes for the DNS to propagate. Then use the following command to check that the DNS record is working:


The examples in this tutorial will use pokt001 as the server on the domain, so will be used as the DNS name. Please replace this throughout with your own server and domain name.

ping -c 3

You should see a response that looks something like this:

64 bytes from icmp_seq=0 ttl=47 time=92.403 ms
64 bytes from icmp_seq=1 ttl=47 time=142.828 ms
64 bytes from icmp_seq=2 ttl=47 time=182.456 ms

If the IP address matches the IP address of your Linode instance, you’re all set!


It can sometimes take longer than a minute for the DNS to propagate. So, be patient if things don’t seem to work right away.

Login with SSH

Now that we have a DNS record setup, we will look at using SSH to log in and continue the setup process.

The Secure Shell Protocol (SSH) is a secure way to connect to your Linode instance from a remote machine, like your local computer. We’ll be using SSH to complete the remainder of the setup process.

SSH from Mac or Linux

If you’re using a Mac, or Linux, on your local computer, you can SSH into your node by doing the following:

  • Open a terminal

  • SSH into your node using the following command:


Don’t forget to replace with your DNS name.

You’ll be prompted for your password. This is the root password that you set when you created your Linode.

SSH from Windows

Windows 10 and later have a built-in SSH client. You can use SSH on Windows by doing the following:

  • Open the Windows terminal

  • SSH into your node using the following command:


Don’t forget to replace with your DNS name.

If you’re using an older version of Windows, you might need to install PuTTY or some other SSH client.

Set the hostname

At this point you should be logged into your node as the root user.

In a previous step, we set the DNS name for the node. Now we’ll use the same name for the hostname on the server.

To set the server hostname use the following steps:

  1. Open the /etc/hostname file with the following command:

    nano /etc/hostname
  2. Change the localhost value to the fully qualified hostname of your node (for example,

  3. Save the file with Ctrl+O and then Enter.

  4. Exit nano with Ctrl+X.

  5. Reboot the server with the following command:

  6. Wait for the server to reboot then ssh back in as the root user before continuing on.

Create a Pocket user account

For security reasons it’s best not to use the root user. Instead, it’s better to create a new user and add the user to the sudo group.

To create a new user, enter the following commands:

  1. Create a new user named pocket, add it to the sudo group, and set the default shell to bash. If you want to specify the location of the home directory, you can use the -d option followed by the path to the home directory:

    useradd -m -g sudo -s /bin/bash pocket && passwd pocket
  2. For the rest of this guide, we’ll be using the pocket user. So now that the pocket user is created, you can switch from using root to the pocket user with the following command:

    su - pocket

Mount the volume

Next we want to mount the secondary storage volume that we created in a previous step.

  1. Verify that the volume is attached to your instance.

    sudo fdisk -l
    Disk /dev/sdc: 800 GiB, 858993459200 bytes, 1677721600 sectors
    Disk model: Volume
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes

  2. Create a new partition. If the previous command shows a file path different from /dev/sdc, use that instead in the commands below:

    sudo mkfs.ext4 /dev/sdc
  3. Create a new mount point:

    sudo mkdir /mnt/data
  4. Mount the new partition:

    sudo mount /dev/sdc /mnt/data
  5. Verify that the partition was created by running the following command:

    sda  /dev/sda 319.5G  289.5G     3% /
    sdb  /dev/sdb   512M                [SWAP]
    sdc  /dev/sdc   800G    328G    53% /mnt/data

  6. Set the volume to be mounted automatically. Open /etc/fstab:

    sudo nano /etc/fstab
  7. Add the following line to the bottom of the file:

    /dev/sdc /mnt/data ext4 defaults,noatime,nofail 0 2
  8. Save the file with Ctrl+O and then Enter.

  9. Exit nano with Ctrl+X.

Move the home directory

Many Pocket commands assume a data directory path of ~/.pocket. While it is possible to specify a different data directory with every command, it will be much easier to change the location of the pocket user home directory. For this tutorial, we will be putting the Pocket data directory at /mnt/data/.pocket.

To change the home directory of the pocket user:

sudo usermod -d /mnt/data pocket

Configure SSH Key Login (Optional):

While not required, using an SSH key provides a more secure means of accessing your server.

Using an SSH key removes the ability for credentials to be sniffed in the login process, and removes the pitfalls that can often come with user generated passwords since the key will truly be random.

One important thing to understand, is that without access to the ssh key, you won’t be able to log into your node. If you intend on accessing your node from multiple computers, it’s recommended that you repeat the Generate Key and Upload Key steps from each computer that you intend to access your node from before moving on to the Disable Root Login and Password Authentication step.

  1. Log Out

    At the terminal you’ll need to enter the logout command twice. The first logout logs you out of the pocket user, back to the root user, and the second logout logs you out of the server and back to your terminal.

  2. Generate Key

    Next, we’ll generate an ssh key. To do that you’ll run the ssh-keygen command. You’ll be prompted to specify the file you want to save the key to, and for a password. Specifying a password means that if someone has access to your key, they’d still need to know the password to be able to use it to login. To create the key, do the following:

    • Run the ssh-keygen command

      ssh-keygen -t rsa -b 4096
    • Enter file in which to save the key (~/.ssh/id_rsa)

    • Enter a passphrase (empty for no passphrase)

    • Enter same passphrase again

    The results should looking something like the following:

    The key fingerprint is:
    The key's randomart image is:
    +---[RSA 4096]----+
    |         o+o     |
    |      . oo. .    |
    |       o ..o . . |
    |       .  . o.+  |
    |        S  oo= . |
    |    ...B o..+.B..|
    |    .o=.B  ..E...|
    |    +.o*.o .o o  |
    |   . +o.*+.      |
  3. Upload Key

    Now we’re going to upload the key so that we can use it to log into the pocket user. If you choose a different path for the ssh key, it’s important to replace the ~/.ssh/id_rsa with the key you used.

    ssh-copy-id -i ~/.ssh/id_rsa
    Windows users may not have access to this command. If you don't have access to a Bash shell, you can use PowerShell to mimic this command. [See these instructions for more details.](
  4. Disable Root Login and Password Authentication

    Now we’re now going to configure ssh to no longer allow root logins, and to not allow any password based login attempts. Meaning without access to the ssh key for the pocket user, no one will be able to log into the server.

    First we’ll need to log back into the server:


    From there, we’ll want to open the /etc/ssh/sshd_config file to make some changes to the default configuration:

    sudo nano /etc/ssh/sshd_config

    Once there, we’ll need to find and change the following lines:

    • #PermitRootLogin prohibit-password -> PermitRootLogin no
    • #PubkeyAuthentication yes -> PubkeyAuthentication yes
    • #PasswordAuthentication yes -> PasswordAuthentication no

    Once changed, Ctrl-O followed by Enter will save the changes, and Ctrl-X will exit nano back to the terminal.

    Then we’ll need to restart the ssh server for these changes to take effect:

    sudo systemctl restart sshd.service
  5. Verify Everything Works

    The last step is to log out of the server, and try logging back in. If you’re no longer prompted for a password, then everything is working as expected.

    ssh -i C:\Users\<USER>\.ssh\id_rsa -l pocket
    ssh -i ~\.ssh\id_rsa

That’s it for the server setup! Continue on to install the necessary software.

Part 2 – Software installation

This section will help you install all the necessary software for your node.

Install dependencies

Now let’s move on to the Pocket CLI installation.

At this point you should be logged in via SSH as the pocket user that we set up in a previous step. Before we install the Pocket software, we need to update the existing system packages and add a few dependencies.

Updating system packages

  1. Update the repository index with the following command:
    sudo apt update
  2. Update the distribution with the following command:
    sudo apt dist-upgrade -y

After the update completes, we’re ready to install the dependencies.

Installing dependencies

There are a handful of dependencies but installing them won’t take long. Also, some might already be installed. So if one of the dependencies exists, you can just move on to the next one.


sudo apt-get install git -y

build tools

sudo apt-get install build-essential -y


sudo apt-get install curl -y


sudo apt-get install file -y


sudo apt install nginx -y


sudo apt install certbot -y


sudo apt-get install python3-certbot-nginx -y


sudo apt install jq -y

Install Go

After installing the dependencies, there is one more dependency we’ll need to add, and that’s Go. Go (sometimes known as “Golang”) is the programming language that the Pocket software was written in.

We could install Go using apt, but we want to get the latest stable version which probably isn’t available by default in the apt repository. So, we’ll use the steps below to install Go.

  1. Make sure you’re in the pocket home directory.
    cd ~
  2. Find the latest version of Go from then download it with the following command. (Make sure to change the link below to point to the correct version of Go.)
  3. Extract the archive:
    sudo tar -xvf go1.19.2.linux-amd64.tar.gz
  4. Set permissions on the extracted files:
    sudo chown -R pocket ./go
  5. Add Go to the PATH:
    echo 'export PATH=$PATH:$HOME/go/bin' >> ~/.profile
  6. Set the GOPATH and GOBIN environment variables:
    echo 'export GOPATH=$HOME/go' >> ~/.profile
    echo 'export GOBIN=$HOME/go/bin' >> ~/.profile
  7. Reload your .profile:
    source ~/.profile
  8. Verify the installation:
    go version
    go version go1.19.2 linux/amd64

    Make sure the version number matches the version you downloaded. If the go version command doesn’t work, try logging out and logging back in.

  9. Verify the GOPATH and GOBIN variables are set correctly:
    go env

Install Pocket

After you can verify that you have the latest stable version of Go, we’re ready to install the Pocket software.

We’ll be downloading Pocket Core from GitHub and then compiling it with Go to get it fully installed.

To download and install Pocket Core, do the following:

  1. Create a project directory:

    sudo mkdir -p $GOPATH/src/
  2. Change to the project directory:

    cd $GOPATH/src/
  3. Clone the Pocket Core repository:

    sudo git clone
  4. Change to the code directory:

    cd pocket-core
  5. Checkout the latest version. You can find the latest tag by going to

    sudo git checkout tags/RC-0.9.2

    You may see a warning about being in a “detached HEAD” state. This is normal.

  6. Build project code:

    go build -o $GOPATH/bin/pocket $GOPATH/src/
  7. Test that the build succeeded:

    pocket version
    AppVersion: RC-0.9.2

That’s it for the software installation. Now let’s move on to the Pocket core configuration.

Part 3 – Pocket configuration

This section will help you configure your instance of Pocket.

Download snapshot

Rather than synchronizing your Pocket node from block zero (which could take weeks), you can use a snapshot. A snapshot of the Pocket blockchain is taken every 12 hours and can be downloaded using the instructions on the Pocket Snapshots Repository page.


As of this writing, the snapshots are refreshed every 12 hours. In the GitHub repo you can look at when the file was last updated to determine when the last snapshot was taken. It’s best to download the snapshot that is less than a few hours old.

Downloading a snapshot will likely take a few hours, so we’re going to use the screen command so that the download can run in the background, allowing you to perform other tasks.

To download the most recent snapshot:

  1. Create a screen instance:
    Press Enter to get back to a prompt.
  2. Change into the .pocket directory.
    cd ~/.pocket
  3. Create a directory named data and change into it:
    mkdir data && cd data
  4. Download the latest snapshot using the following command:
    wget -qO- | tar xvfz -

While the snapshot is downloading, press Ctrl-A and then d to let the process run in the background and be returned to a prompt.

To return to your screen instance to see how things are going:

screen -r

You can also check on the status of the download by watching your disk usage:

df -h

Once your download is completed, make the pocket user the owner of the data directory:

sudo chown -R pocket ~/.pocket/data

And when you’re done with your screen instance, you can exit out of it:


Create a Pocket wallet account

Pocket nodes are associated with a Pocket wallet account. This is the account that will be used to send and receive transactions from the node. You can either create a new account using the Pocket CLI we just installed, or you can use an existing account. For this guide, we’ll be creating a new account.

Creating an account

To create an account, run the following command:

pocket accounts create

You’ll be prompted to set a passphrase for the account. You can use any passphrase you like but for security reasons, it’s best to use a passphrase that is at least 12 characters long, preferably longer.


If you already have a Pocket account that you’d like to use to run the node, you can import it here. Upload the JSON file associated with your account to the server and run the following command:

pocket accounts import-armored <armoredJSONFile>

You will be prompted for the decryption passphrase of the file, and then for a new encryption passphrase to store in the keybase.

Listing accounts

After you’ve created the account you can use the pocket accounts list command to confirm that the account was added successfully.

pocket accounts list

Setting the validator address

Next, set the account as the one the node will use with the following command:

pocket accounts set-validator [YOUR_ACCOUNT_ADDRESS]

Confirm the validator address

Finally, you can confirm that the validator address was set correctly by running the following command:

 pocket accounts get-validator

Create config.json

The Pocket core software uses a config file to store configuration details. By default the config file is located at ~/.pocket/config/config.json. In this step we’ll look at how to create a new config file.

To create a new config file:

  1. Run the following command, which will create the default config.json file, add the seeds, set port 8081 to 8082, and increase the RPC timeout value:

    echo $(pocket util print-configs) | jq '.tendermint_config.P2P.Seeds = ",,,,,,,,,,"' | jq '.pocket_config.rpc_timeout = 15000' | jq '.pocket_config.rpc_port = "8082"' | jq '.pocket_config.remote_cli_url = "http://localhost:8082"' | jq . > ~/.pocket/config/config.json

    This is a long command! Make sure you’ve copied it completely.

  2. Verify the config.json file setting by viewing the contents of the file:

    cat ~/.pocket/config/config.json
      "tendermint_config": {
        "RootDir": "/mnt/data/.pocket",
        "ProxyApp": "tcp://",
        "Moniker": "",
        "FastSyncMode": true,
        "DBBackend": "goleveldb",
        "LevelDBOptions": {
          "block_cache_capacity": 83886,
          "block_cache_evict_removed": false,
          "block_size": 4096,
          "disable_buffer_pool": true,
          "open_files_cache_capacity": -1,
          "write_buffer": 838860

Create chains.json

Pocket nodes relay transactions to other blockchains. So, you’ll need to configure the chains your node can relay to. For this guide, we’ll just be setting up our node to relay to the Pocket mainnet blockchain, essentially through itself.

To maximize your rewards, you’ll want to relay to other chains. We’ll cover that in more detail later but here is a list of other blockchains you could relay to.

Generating a chains.json file with the CLI

You can use the Pocket CLI to generate a chains.json file for your node by running the following command:

pocket util generate-chains

This will prompt you for the following information:

  • Enter the ID of the Pocket Network RelayChain ID:
  • Enter the URL of the local network identifier.
  • When you’re prompted to add another chain, enter n for now.

By default the chains.json file will be created in ~/.pocket/config. You can use the --datadir flag to create the chains.json file in an alternate location. For example: pocket util generate-chains --datadir "/mnt/data/.pocket".

Create genesis.json

Now that we have a chains.json file set up, so we can move on to test our node.

When you start a Pocket node for the first time, it will need to find other nodes (peers) to connect with. To do that we use a file named genesis.json with details about peers the node should connect to get on the network.

To create a JSON file with the genesis information:

  1. Change to the .pocket/config directory:
    cd ~/.pocket/config
  2. Use the following command to get the genesis.json file from GitHub:
    wget genesis.json

Set open file limits

Ubuntu and other UNIX-like systems have a ulimit shell command that’s used to set resource limits for users. One of the limits that can be set is the number of open files a user is allowed to have. Pocket nodes will have a lot of files open at times, so we’ll want to increase the default ulimit for the pocket user account.

Increasing the ulimit

  1. Before increasing the ulimit, you can check the current ulimit with the following command:
    ulimit -n
  2. Increase the ulimit to 16384. The -Sn option is for setting the soft limit on the number of open files:
    ulimit -Sn 16384
  3. Check the new ulimit to confirm that it was set correctly. The -n option is for getting the limit for just the number of open files:
    ulimit -n

Permanent settings

Using the above method for setting the ulimit only keeps the change in effect for the current session. To permanently set the ulimit, you can do the following:

  1. Open the /etc/security/limits.conf file.
    sudo nano /etc/security/limits.conf
  2. Add the following line to the bottom of the file:
    pocket           soft    nofile          16384
  3. Save the file with Ctrl+O and then Enter.
  4. Exit nano with Ctrl+X.

After permanently setting the ulimit, the next thing we’ll do is download a snapshot of the Pocket blockchain.

Configure systemd

Next, we’ll configure the Pocket service using systemd, a Linux service manager. This will enable the Pocket node to run and restart even when we’re not logged in.

Creating a systemd service in Linux

To setup a systemd service for Pocket, do the following:

  1. Open nano and create a new file called pocket.service:

    sudo nano /etc/systemd/system/pocket.service
  2. Add the following lines to the file:

    Description=Pocket service mnt-data.mount systemd-networkd-wait-online.service
    ExecStart=/home/pocket/go/bin/pocket start
    ExecStop=/home/pocket/go/bin/pocket stop
  3. Make sure the User is set to the user that will run the Pocket service.

  4. Make sure the ExecStart and ExecStop paths are set to the path for the Pocket binary.

  5. Save the file with Ctrl+O and then return.

  6. Exit nano with Ctrl+X.

  7. Reload the service files to include the pocket service:

    sudo systemctl daemon-reload
  8. Start the pocket service:

    sudo systemctl start pocket.service
  9. Verify the service is running:

    sudo systemctl status pocket.service
    pocket.service - Pocket service
      Loaded: loaded (/etc/systemd/system/pocket.service; enabled; vendor preset: enabled)
      Active: active (running) since Fri 2022-10-07 00:07:05 UTC; 1 weeks 0 days ago

  10. Stop the pocket service:

    sudo systemctl stop pocket.service
  11. Verify the service is stopped:

    sudo systemctl status pocket.service
  12. Set the service to start on boot:

    sudo systemctl enable pocket.service
  13. Verify the service is set to start on boot:

    sudo systemctl list-unit-files --type=service | grep pocket.service
    pocket.service                             enabled         enabled

  14. Start the pocket service:

    sudo systemctl start pocket.service

Other systemctl commands

  • Restart the Pocket service:
    sudo systemctl restart pocket.service
  • Prevent the service from starting on boot:
    sudo systemctl disable pocket.service
  • View mounted volumes:
    sudo systemctl list-units --type=mount

Viewing the logs

  • View the logs for the Pocket service:

    sudo journalctl -u pocket.service
  • View just the last 100 lines of the logs (equivalent to the tail -f command):

    sudo journalctl -u pocket.service -n 100 --no-pager

Finding Errors

You can use grep to find errors in the logs.

sudo journalctl -u pocket.service | grep -i error

In case you skipped the step above while the snapshot was downloading, once your download is completed, make the pocket user the owner of the data directory:

sudo chown -R pocket ~/.pocket/data

And when you’re done with your screen instance, you can exit out of it:


We’re just about done. We just need to setup an HTTP proxy and we’ll be ready to go live. We’ll setup the proxy next.

Part 4 – Proxy configuration

This section will help you set up the proxy setting on your node.

Setup SSL

Pocket requires that nodes have an SSL certificate for secure communications. SSL (Secure Sockets Layer) is a layer of security that sits on top of TCP/IP. It’s used to encrypt the data sent between a client and a server. To use SSL, you need to have a certificate and a key. Thankfully, getting an SSL certificate is straightforward and free.

To get a certificate, we’ll be using Let’s Encrypt which is a service that issues SSL certificates for free. We’ll also be using software called certbot to register, install, and renew the certificate.

Registering an SSL certificate

We installed certbot in a previous step so we just need to use it to request a certificate.

To get a certificate, we’ll need to use the certbot command with the following options:

  • --register-unsafely-without-email: This option is required to get a certificate without an email address.
  • --agree-tos: This option is required to agree to the Let’s Encrypt Terms of Service.
  • --nginx: This option is required to use the nginx plugin.
  • --no-redirect: This option is required to disable the redirect to the Let’s Encrypt website.
  • --domain: This option is required to specify the domain name.

Here’s an example of how to request a certificate. Just replace $HOSTNAME with the DNS name of your node:

sudo certbot --nginx --domain $HOSTNAME --register-unsafely-without-email --no-redirect --agree-tos
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/default

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

The output from this command should confirm that the certificate was successfully registered.

Testing your certificate

To be sure, you’ll also want to test that the certificate is working.

There is a command that certbot provides to test your certificate. It’s used for testing the auto-renewal of the certificate but it also confirms that the certificate is working. You can run it using the following command:

sudo certbot renew --dry-run
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/ (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

The resulting output should confirm that the certificate is working.

Configure Nginx

Nginx is a web server. We installed it in a previous step but we need to do some additional configuration.

Nginx uses config files to define servers and routes for incoming requests. For Pocket nodes, nginx needs to relay public requests to a local HTTP server that pocket core is running. This is referred to as the proxy. We’ll also need to proxy requests made by the Pocket CLI. For example, when we run the command pocket query height, the CLI makes an http request to the node’s local HTTP server.

Config files

The nginx configuration files we’re interested in are located in the /etc/nginx/sites-available/ directory. In that directory there is a default configuration file named default. This is the configuration that is created when you install nginx, but we’ll be creating our own for our node.

To configure nginx:

  1. Confirm the name of your SSL certificate:
    sudo ls /etc/letsencrypt/live/
  2. Create a new config file with nano:
    sudo nano /etc/nginx/sites-available/pocket
  3. Add the following code, making sure to change the hostname values ( to your node’s DNS hostname in the three places found below:
    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        root /var/www/html;
        index index.html index.htm index.nginx-debian.html;
        server_name _;
        location / {
            try_files $uri $uri/ =404;
    server {
        add_header Access-Control-Allow-Origin "*";
        listen 80 ;
        listen [::]:80 ;
        listen 8081 ssl;
        listen [::]:8081 ssl;
        root /var/www/html;
        index index.html index.htm index.nginx-debian.html;
        location / {
            try_files $uri $uri/ =404;
        listen [::]:443 ssl ipv6only=on;
        listen 443 ssl;
        ssl_certificate /etc/letsencrypt/live/;
        ssl_certificate_key /etc/letsencrypt/live/;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
        access_log /var/log/nginx/reverse-access.log;
        error_log /var/log/nginx/reverse-error.log;
        location ~* ^/v1/client/(dispatch|relay|challenge|sim) {
            add_header Access-Control-Allow-Methods "POST, OPTIONS";
            allow all;
        location = /v1 {
            add_header Access-Control-Allow-Methods "GET";
            allow all;
  4. Save the change with Ctrl+O.
  5. Exit nano with Ctrl+X.
  6. Stop nginx with:
    sudo systemctl stop nginx
  7. Disable the default configuration:
    sudo rm /etc/nginx/sites-enabled/default
  8. Enable our new configuration:
    sudo ln -s /etc/nginx/sites-available/pocket /etc/nginx/sites-enabled/pocket
  9. Start nginx:
    sudo systemctl start nginx

Enable UFW

We’re almost done, but before we finish we’ll make our server more secure by setting firewall rules to limit network exposure. The Uncomplicated Firewall (UFW) is a security tool that makes configuring the firewall reasonably simple. We’ll use it to disable unnecessary ports.

Ports you need to open

For running a Pocket node, you’ll need to open the following ports:

  • 22: SSH
  • 80: HTTP
  • 443: HTTPS
  • 8081: For the Pocket HTTP API
  • 26656: For the Pocket RPC API

Use UFW to disable unnecessary ports

To use UFW to configure the firewall:

  1. Enable UFW. When prompted, press y to confirm:

    sudo ufw enable
  2. Set the default to deny all incoming connections:

    sudo ufw default deny
  3. Allow the SSH port:

    sudo ufw allow ssh
  4. Allow port 80:

    sudo ufw allow 80
  5. Allow port 443:

    sudo ufw allow 443
  6. Allow port 8081:

    sudo ufw allow 8081
  7. Allow port 26656:

    sudo ufw allow 26656

That’s it for the UFW setup. Let’s just check the status to confirm the ports are open. To do that, run the following command:

sudo ufw status

After confirming only the necessary ports are open, you can move on to the final steps.

Part 5 – Going live

This section will details the final steps in going live with your node.

Test everything

At this point your Pocket node should be up and running!

But you’ll want to test it to confirm. The following are some of the things you can do to test your Pocket Node.

Make sure the Pocket process is running

The first thing to check is that the pocket service is running. You can do that by running the following command:

top -b -n 1 | grep pocket

You should see output similar to the following:

  44871 root      20   0 1018268  33948  21448 S   0.0   0.4   0:00.17 pocket

Block height

You’ll want to check that the node is fully synced with the Pocket blockchain. The easiest way is to run the following command:

pocket query height

The result should look something like the following.

    "height": 48161

Network status

Another way to see if your node is fully synced is to check the status with the following command:


The result should look something like the following. Note the highlighted property catching_up which indicates if the node is catching up with the blockchain or fully synced. In the example below, the node is fully synced.

  "jsonrpc": "2.0",
  "id": -1,
  "result": {
    "node_info": {
      "protocol_version": {
        "p2p": "7",
        "block": "10",
        "app": "0"
      "id": "80b80c106115259349df8ef06267cff7bbabd194",
      "listen_addr": "tcp://",
      "network": "mainnet",
      "version": "0.33.7",
      "channels": "4020212223303800",
      "moniker": "localhost",
      "other": {
        "tx_index": "on",
        "rpc_address": "tcp://"
    "sync_info": {
      "latest_block_hash": "F39BBF5C64D9E02E28DDBB8640F84A22CFAE1727CFBC72537982EF5914E4BB25",
      "latest_app_hash": "6198835747411135C1F812CB45FA5621D5ADB63342EC0678C20879D7D39F03B5",
      "latest_block_height": "50021",
      "latest_block_time": "2022-02-04T12:16:10.77575197Z",
      "earliest_block_hash": "7D551967CB8BBC9F8C0EAE78797D0576951DDA25CE63DF1801C020478C0B02F8",
      "earliest_app_hash": "",
      "earliest_block_height": "1",
      "earliest_block_time": "2020-07-28T15:00:00Z",
      "catching_up": false
    "validator_info": {
      "address": "80B80C106115259349DF8EF06267CFF7BBABD194",
      "pub_key": {
        "type": "tendermint/PubKeyEd25519",
        "value": "ee+o9bKqCbAO13FgWTLmJdi9hhfYg8AHsif5430uz8A="
      "voting_power": "0"

Make sure your node is visible to other nodes

You’ll also want to make sure your node is accessible to other nodes.

To test and confirm your node is visible to other nodes on the public network, you’ll make an HTTP request using the public DNS name for the node. You can use the following command to make that request:


As always, don’t forget to change to the DNS name for your node.

This should return the following. This is the version of pocket-core that is running.


Staking your node

To earn POKT rewards, you’ll need to stake at least 15,000 POKT. That said, you should stake at least 15,100 POKT or more to be safe. This provides a little extra room in case your node gets slashed (penalized) for some reason.


Please make sure that you understand the risks associated with staking POKT and running a Pocket node.

If you’re using the Pocket CLI to fund an account, keep in mind that the CLI uses uPOKT (the smallest unit of POKT) for its calculations. The formula for converting POKT to uPOKT is: uPOKT = POKT * 10^6. So, multiplying 15050 POKT by 10^6 (one million) will result in 15050000000 uPOKT.

Also keep in mind that there is a cost for every transaction you send. At the moment, that cost is a flat fee of 0.01 POKT, or 10000 uPOKT, but this may be subject to change.

  1. List your accounts:
    pocket accounts list
  2. Confirm the validator account is set:
    pocket accounts get-validator
  3. Confirm the validator account has enough POKT. This should be at least 15,101 POKT. You’ll want 15,100 to stake and a bit more for network fees:
    pocket query balance [YOUR_VALIDATOR_ADDRESS]
  4. Stake your node, making sure to enter the correct details for your setup:
    pocket nodes stake custodial [YOUR_VALIDATOR_ADDRESS] 15100000000 [CHAIN_IDS] https://[HOSTNAME]:443 mainnet 10000 false

The [CHAIN_IDS] placeholder should be a list of relay chain IDs that are defined in your ~/.pocket/config/chains.json file. In this guide we only set up 0001, but if you were relaying to multiple chains, each id would be separated by a comma. For example, 0001,0022,0040.


As of RC- there are two staking methods: custodial and non-custodial. The custodial method is used in the example above.

After you send the stake command, you’ll be prompted for your passphrase, then you should see something like this:

    "logs": null,
    "txhash": "155D46196C69F75F85791C4190D384B8BAFFBBEFCC5D1311130C54A1C54435A7"

The actual time it takes to stake will vary depending on when the last block was processed, but generally, it should take less than 15 minutes.

Confirm your node is live

After you’ve staked your node, you can confirm it’s live by running the following command:

pocket query node [YOUR_VALIDATOR_ADDRESS]

If you see something like the following, it just means your node is not live yet:

the http status code was not okay: 400, and the status was: 400 Bad Request, with a response of {"code":400,"message":"validator not found for 07f5084ab5f5246d747fd1154d5d4387ee5a7111"}

If this happens, please wait a few minutes and try again.

Tutorial complete

Congratulations! You’ve successfully set up a Pocket node.

There’s more to running a Pocket node than this, such as maintenance, upgrades, and other administrative tasks, but hopefully this has gotten you started and on the right path. Thank you for doing your part to help decentralize Web3!