Generic Nodes
Polkadot, in a similar to many other decentralized ledger technologies, uses a peer-to-peer (p2p) network topology. This arrangement allows the flexible addition or removal of individual nodes with minimal affectation to the operations of the whole network, that is, the system is inherently more resilient than alternative solutions.
What is a Node
We can see every node as a point of connection between peers in a network.
In the Polkadot / Substrate ecosystem, the nodes serve a common purpose (interconnection) but can also serve specific objectives: as either validators, bootnodes, archivists, etc. some could even mix a couple of these goals at the same time (e.g. archivist + bootnode functions in the same node is not uncommon).
It is recommended that a node acting as a validator is not tasked additional functions as bootnode or archivists, to avoid it become too overwhelmed with these additional functions in detriment of the most important task of validating the blocks for the blockchain
If you see a Polkadot node closely, you will see the following components:
In this diagram you isolated one of the nodes from the network, which is now drawn as a "cloud" of peers on the top of the diagram. From these peers, several p2p connections will be maintained for the Polkadot Node that is running inside the machine.
And the node is actually a program (a binary) that is being executed with the help of a service provided by the machine's operating system, and all activities of this node are stored to / retrieved from a local database.
We can also see that the node is an abstract concept, an instance of a program that is running in the RAM of a computer, so if it wasn't for the local database, the node was completely volatile. Finally, see that given the ephemeral concept of the node allows for running several nodes hosted in the same machine:
Hosting several nodes in one machine is often reserved for test networks, but not recommended for validators of live blockchains (e.g.mainnet).
Working components of a Node:
In the following subtitles you will configure the necessary aspects of your generic node, these will be the exact same aspects needed for a validator, bootnode or archivist node, but for the fine details on the operations of those kind of nodes, please refer to the relevant chapters.
- Firewall ports: Open only what is needed.
- Executing User: do not use
root. - Executable Binary: where is the program?.
- Blockchain Database: where to store local copy of the blockchain.
- Blockchain Specifications: what network do you want to connect to?
systemdService: Putting it all together
Firewall Ports
A Polkadot generic node, running alone in one machine, uses the TCP port 30333 as default, so make sure you have it open for incoming connections.
That means in the most cases:
- Open the ports at the router (or ISP) level --> please refer to your router (or ISP) instructions.
- Open the ports at the machine level:
If you followed the instructions of the servers chapter, now you only need to open the additional port with ufw:
# Open the p2p port
sudo ufw allow proto tcp from any to any port 30333 comment 'p2p port'
# Check the port is open and the firewall is enabled
sudo ufw status verbose
and the output should look like
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp ALLOW IN 200.xxx.xxx.12 # SSH port
30333/tcp ALLOW IN Anywhere # p2p port
Executing User
It is highly advisable not to use the root user to run any services, this is in line with the best practice of always using the method of least privilege rather than least resistance.
So, lets create a new user dedicated only to run Polkadot services:
# create a limited user and group to run Polkadot
sudo adduser --disabled-login --no-create-home -gecos "Polkadot" polkadot
# Check that the user now exists
sudo tail /etc/passwd
The results should look like:
messagebus:x:101:101::/nonexistent:/usr/sbin/nologin
syslog:x:102:102::/nonexistent:/usr/sbin/nologin
systemd-resolve:x:991:991:systemd Resolver:/:/usr/sbin/nologin
uuidd:x:103:103::/run/uuidd:/usr/sbin/nologin
(...)
polkadot:x:1003:1003:Polkadot,,,:/home/polkadot:/usr/sbin/nologin
Executable Binary
Now let's install the program. As a convention, we will use the Linux standard directory /usr/local/bin to store our executable (binary) files.
One benefit of using this directory, is that Ubuntu already lists it as part of the environment paths to search when executing commands. Thus, we do not need to memorize the full path when invoking.
You can find the latest binary at the polkadot-sdk github repository of Paritytech.
# Change to the (bin)aries directory
cd /usr/local/bin
# download the binary
sudo wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2509-2/polkadot
# (optional) download and print the checksum declaration
sudo wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2509-2/polkadot.sha256
cat polkadot.sha256
# (optional) calculate the actual checksum of the downloaded binary
# visually check that both checksums match before progressing to next steps
sudo sha256sum polkadot
# Assign ownership to the custom user and amend file permissions
sudo chown polkadot:polkadot polkadot
sudo chmod 755 polkadot
If you want to know how does the visual checks for the checksums look like, please see the next terminal output, where it is evident that the intended file polkadot throws the exact checksum as declared but the Github repository, so at least the download was reliably done:
$ cat polkadot.sha256
dfa15b124b59c5f3a741a741d9cc76b32f6ad66227d00186951c1d43b1c1b2f2 polkadot
$ sudo sha256sum polkadot
dfa15b124b59c5f3a741a741d9cc76b32f6ad66227d00186951c1d43b1c1b2f2 polkadot
Blockchain Database
It is time now to create the directories where the local database will be stored.
Once again, following best practices, we will use the Linux standard /var/lib directory for that, inside we will start the organization by creating one folder with the same name of the application or binary (i.e. polkadot) and nested inside another folder with the name of our node (e.g. polkadot1).
# Create all (parent) directories until the most nested one
sudo mkdir -p /var/lib/polkadot/polkadot1
# Assign ownership (recursively) to the custom user
sudo chown -R polkadot:polkadot /var/lib/polkadot
Blockchain Specifications
The binary above is a program, and, as such, it can take parameters which can change its behavior.
One of the most important of these parameters is the blockchain specifications, often called the chainspec file. This file contains key information to be able to connect to the correct network and that such network starts with the correct arguments or values for its "genesis" and "state".
Polkadot and Kusama have built-in chainspecs, meaning that the binary retrieves the specifications automatically with the flag --chain=polkadot or --chain=kusama, respectively, but other chains (like Paseo), may require the download of a separate chainspec file
This is the example procedure for a Paseo node:
# change directory to the database
cd /var/lib/polkadot/paseo1
# Download the chainspec for the relevant network (i.e. mainnet)
sudo wget https://paseo-r2.zondax.ch/chain-specs/paseo.raw.json
# Assign ownership to the custom user and amend file permissions
sudo chown polkadot:polkadot paseo.raw.json
sudo chmod 644 paseo.raw.json
systemd Service
Finally, the node is ready to receive the final instruction on how to start running the node.
In Ubuntu linux, this is most easily achieved via a systemd service. These are specified via a .service configuration file in the /etc/systemd/system directory.
Let's create our file like this:
# Create a new polkadot1.service file
sudo nano /etc/systemd/system/polkadot1.service
The minimal node configuration to run a Polkadot node would look like this one below, feel free to paste in your polkadot1.service file:
[Unit]
Description=Polkadot Node
After=network-online.target
Wants=network-online.target
[Service]
User=polkadot
Group=polkadot
ExecStart=/usr/local/bin/polkadot \
--name MY_POLKADOT_NODE \
--base-path '/var/lib/polkadot/polkadot1' \
--chain polkadot
Restart=always
RestartSec=120
[Install]
WantedBy=multi-user.target
This configuration uses most of the default settings for a Polkadot node.
Once this file is saved to storage, you can control it with the following commands:
# Start the polkadot1 service
sudo systemctl start polkadot1
# Query the status of the polkadot1 service
sudo systemctl status polkadot1
# Stop the polkadot1 service
sudo systemctl stop polkadot1
# Enable the autostart of the polkadot1 service after reboots
sudo systemctl enable polkadot1
# Disable the autostart of the polkadot1 service after reboots
sudo systemctl disable polkadot1
# Show continuously the logs of the polkadot1 service, starting with the last 100 entries
sudo journalctl -fn 100 -u polkadot1
for your reference, this is what the sudo systemctl status polkadot1 returns:
● polkadot1.service - Polkadot Node
Loaded: loaded (/etc/systemd/system/polkadot1.service; enabled; preset: enabled)
Active: active (running) since Mon 2025-11-17 20:53:01 UTC; 5 days ago
Main PID: 59064 (polkadot)
Tasks: 102 (limit: 76026)
Memory: 23.4G (peak: 24.6G)
CPU: 1d 2h 47min 20.776s
CGroup: /system.slice/polkadot1.service
└─59064 /usr/local/bin/polkadot --name MY_POLKADOT_NODE --chain polkadot --base-path /va>
Nov 22 21:36:41 my_machine polkadot[59064]: 2025-11-22 21:36:41 maintain txs=(0, 0) a=1 i=2 views=[(2>
Nov 22 21:36:42 my_machine polkadot[59064]: 2025-11-22 21:36:42 🏆 Imported #28756860 (0xd8d3…91fa → >
Nov 22 21:36:42 my_machine polkadot[59064]: 2025-11-22 21:36:42 maintain txs=(0, 0) a=1 i=3 views=[(2>
(...)
Nov 22 21:36:48 my_machine polkadot[59064]: 2025-11-22 21:36:48 ♻️ Reorg on #28756861,0x4fac…f343 to >
Nov 22 21:36:48 my_machine polkadot[59064]: 2025-11-22 21:36:48 🏆 Imported #28756861 (0xc6d9…2ea9 → >
Nov 22 21:36:48 my_machine polkadot[59064]: 2025-11-22 21:36:48 maintain txs=(0, 0) a=2 i=3 views=[(2>
and you can exit back to the system prompt pressing the Q key.
On the other hand, the output of the sudo journalctl -fn 100 -u polkadot1 command should look like this right after the node starts:
Nov 22 21:41:18 my_machine systemd[1]: Started polkadot1.service - Polkadot Node.
Nov 22 21:41:18 my_machine polkadot[116553]: 2025-11-22 21:41:18 Parity Polkadot
Nov 22 21:41:18 my_machine polkadot[116553]: 2025-11-22 21:41:18 ✌️ version 1.20.2-7304752b478
Nov 22 21:41:18 my_machine polkadot[116553]: 2025-11-22 21:41:18 ❤️ by Parity Technologies <admin@parity.io>, 2017-2025
Nov 22 21:41:18 my_machine polkadot[116553]: 2025-11-22 21:41:18 📋 Chain specification: Polkadot
Nov 22 21:41:18 my_machine polkadot[116553]: 2025-11-22 21:41:18 🏷 Node name: MY_POLKADOT_NODE
Nov 22 21:41:18 my_machine polkadot[116553]: 2025-11-22 21:41:18 👤 Role: FULL
Nov 22 21:41:18 my_machine polkadot[116553]: 2025-11-22 21:41:18 💾 Database: ParityDb at /var/lib/polkadot/polkadot1/chains/polkadot/paritydb/full
Nov 22 21:41:21 my_machine polkadot[116553]: 2025-11-22 21:41:21 Local node identity is: 12D3KooWHxxxxxxxxxxxxxxxmVZe4NsfZ8yd6PVDHnfos
Nov 22 21:41:21 my_machine polkadot[116553]: 2025-11-22 21:41:21 Running litep2p network backend
Nov 22 21:41:21 my_machine polkadot[116553]: 2025-11-22 21:41:21 💻 Operating system: linux
Nov 22 21:41:21 my_machine polkadot[116553]: 2025-11-22 21:41:21 💻 CPU architecture: x86_64
Nov 22 21:41:21 my_machine polkadot[116553]: 2025-11-22 21:41:21 💻 Target environment: gnu
Nov 22 21:41:21 my_machine polkadot[116553]: 2025-11-22 21:41:21 💻 CPU: AMD Ryzen 9 7950X 16-Core Processor
Nov 22 21:41:21 my_machine polkadot[116553]: 2025-11-22 21:41:21 💻 CPU cores: 16
Nov 22 21:41:21 my_machine polkadot[116553]: 2025-11-22 21:41:21 💻 Memory: 63435MB
Nov 22 21:41:21 my_machine polkadot[116553]: 2025-11-22 21:41:21 💻 Kernel: 6.8.0-87-generic
Nov 22 21:41:21 my_machine polkadot[116553]: 2025-11-22 21:41:21 💻 Linux distribution: Ubuntu 24.04.3 LTS
Nov 22 21:41:21 my_machine polkadot[116553]: 2025-11-22 21:41:21 💻 Virtual machine: no
Nov 22 21:41:21 my_machine polkadot[116553]: 2025-11-22 21:41:21 📦 Highest known block at #28756904
Nov 22 21:41:21 my_machine polkadot[116553]: 2025-11-22 21:41:21 〽️ Prometheus exporter started at 0.0.0.0:9615
Nov 22 21:41:21 my_machine polkadot[116553]: 2025-11-22 21:41:21 Running JSON-RPC server: addr=127.0.0.1:9944,[::1]:9944
Nov 22 21:41:21 my_machine polkadot[116553]: 2025-11-22 21:41:21 🏁 CPU single core score: 1.67 GiBs, parallelism score: 1.66 GiBs with expected cores: 8
Nov 22 21:41:21 my_machine polkadot[116553]: 2025-11-22 21:41:21 🏁 Memory score: 17.07 GiBs
Nov 22 21:41:21 my_machine polkadot[116553]: 2025-11-22 21:41:21 🏁 Disk score (seq. writes): 2.26 GiBs
Nov 22 21:41:21 my_machine polkadot[116553]: 2025-11-22 21:41:21 🏁 Disk score (rand. writes): 862.58 MiBs
Nov 22 21:41:21 my_machine polkadot[116553]: 2025-11-22 21:41:21 🥩 BEEFY gadget waiting for BEEFY pallet to become available...
Nov 22 21:41:21 my_machine polkadot[116553]: 2025-11-22 21:41:21 Starting main subsystem loop
Nov 22 21:41:21 my_machine polkadot[116553]: 2025-11-22 21:41:21 Successfully persisted AddrCache on disk
Nov 22 21:41:23 my_machine polkadot[116553]: 2025-11-22 21:41:23 🥩 BEEFY pallet available: block 28756902 beefy genesis 20351234
Nov 22 21:41:23 my_machine polkadot[116553]: 2025-11-22 21:41:23 maintain txs=(0, 0) a=1 i=0 views=[(28756904, 0, 0)] event=Finalized { hash: 0x54fcb1e98877d4c51b4afd736f3d2aa050fc765154bb5cfce8b08014380f702d, tree_route: [] } duration=231.766µs
Nov 22 21:41:23 my_machine polkadot[116553]: 2025-11-22 21:41:23 🥩 run BEEFY worker, best grandpa: #28756902.
Nov 22 21:41:23 my_machine polkadot[116553]: 2025-11-22 21:41:23 🏆 Imported #28756905 (0xc62a…5e18 → 0x9ae7…81c5)
Nov 22 21:41:23 my_machine polkadot[116553]: 2025-11-22 21:41:23 maintain txs=(0, 0) a=1 i=1 views=[(28756905, 0, 0)] event=NewBestBlock { hash: 0x9ae73c1377266844c015776dc7d74c1d8aaa893f13cb417227ee62f78dd081c5, tree_route: None } duration=629.112µs
Nov 22 21:41:23 my_machine polkadot[116553]: 2025-11-22 21:41:23 🏆 Imported #28756906 (0x9ae7…81c5 → 0xd6c3…0f32)
(...)
If you can see these logs progressing, you are syncing your database with the public blockchain!.. Congratulations!
You can now stop it and decide what do you want to do with this node, in the next chapter you will find information to change it to serve the network as a validator, a bootnode, or an archivist.
Godspeed!