# Run an archive liteserver (https://docs-dmpho5eos-ton-core-docs.vercel.app/llms/ecosystem/nodes/cpp/run-archive-liteserver/content.md)



This guide describes how to set up an archive liteserver using MyTonCtrl, with ZFS for storage compression and snapshots.

An archive liteserver node stores the entire block history of the TON blockchain. For applications requiring access to historical data, such as blockchain explorers or indexers, running an archive liteserver node is the recommended approach.

## Prerequisites [#prerequisites]

* A server meeting the [minimal hardware requirements](#1-1-minimal-hardware-requirements)
* An OS meeting the [software requirements](#1-2-os-and-system-requirements)

## Step 1: Prepare environment [#step-1-prepare-environment]

### 1.1 Minimal hardware requirements [#11-minimal-hardware-requirements]

Running an archive liteserver requires large storage and network capacity:

* 16-core CPU
* 128 GB RAM
* NVMe Gen4+ SSD storage (Enterprise grade preferred), sustaining at least 64,000 provisioned IOPS:
  * at least 16 TB with ZFS [`lz4`](https://en.wikipedia.org/wiki/LZ4_\(compression_algorithm\)) compression enabled, or
  * at least 20 TB without compression
* 1 Gbit/s symmetric connectivity (both inbound and outbound), \~16 TB/month at peak load
* Fixed (static) public IP address

<Callout type="caution">
  If non-Enterprise SSDs are used, Autonomous Power State Transition (APST) must be disabled on the SSD and the `performance` PCIe ASPM policy enabled at the system level:

  ```bash
  echo performance | sudo tee /sys/module/pcie_aspm/parameters/policy
  ```
</Callout>

### 1.2 OS and system requirements [#12-os-and-system-requirements]

* [Ubuntu](https://ubuntu.com/download/server) 22.04/24.04 LTS or [Debian](https://www.debian.org/distrib/) 11/12
* Python 3.10 or higher
* Open Files Limit must be set above 4,000,000

### 1.3 Subscribe to official channels [#13-subscribe-to-official-channels]

Subscribe and follow the announcements provided for liteservers in the following Telegram channels:

| Channel                                        | Network     |
| ---------------------------------------------- | ----------- |
| [`@tonstatus`](https://t.me/tonstatus)         | TON Mainnet |
| [`@testnetstatus`](https://t.me/testnetstatus) | TON Testnet |

### 1.4 Install ZFS and prepare volume [#14-install-zfs-and-prepare-volume]

Archive nodes benefit from ZFS due to its native compression and snapshot capabilities.

#### 1.4.1 Install ZFS [#141-install-zfs]

```bash
sudo apt update
sudo apt install -y zfsutils-linux
```

#### 1.4.2 Verify physical block size [#142-verify-physical-block-size]

For NVMe drives, ZFS pool sector size must align with the drive's physical block size to avoid performance degradation. Most modern NVMe drives use 4K blocks. Verify the physical block size:

```bash
# Replace nvme0n1 with the target device name
cat /sys/block/nvme0n1/queue/physical_block_size
```

If the result is `4096`, the `-o ashift=12` parameter must be used during pool creation.

#### 1.4.3 Create a storage pool [#143-create-a-storage-pool]

Create a ZFS pool named `data`. Use `-o ashift=12` for 4K blocks (standard for most NVMe drives):

<CodeGroup>
  <CodeBlockTabs defaultValue="Single drive">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="Single drive">
        Single drive
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Multiple drives (Stripe)">
        Multiple drives (Stripe)
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="Single drive">
      ```bash
      # Replace <DISK> with the device identifier (e.g., /dev/nvme1n1)
      sudo zpool create -o ashift=12 data <DISK>
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Multiple drives (Stripe)">
      ```bash
      # Combine multiple disks to increase capacity and performance
      sudo zpool create -o ashift=12 data <DISK1> <DISK2> <DISK3>
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

There,

* `<DISK>` is the target disk device identifier, e.g., `/dev/nvme1n1`;
* `<DISK1>`, `<DISK2>`, and `<DISK3>` are additional disk device identifiers.

<Callout type="caution">
  Combining disks in a stripe (JBOD) increases the total capacity but also the risk of data loss: if a single drive fails, the entire pool is lost. If sufficient disks are available, consider using `mirror` or `raidz` for redundancy.
</Callout>

#### 1.4.4 Enable compression [#144-enable-compression]

Enable `lz4` compression to save disk space with minimal CPU overhead:

```bash
sudo zfs set compression=lz4 data
```

#### 1.4.5 Create dataset and mount point [#145-create-dataset-and-mount-point]

Create the dataset for TON data and set the mount point to `/var/ton-work`:

```bash
sudo zfs create data/ton-work
sudo zfs set mountpoint=/var/ton-work data/ton-work
```

### 1.5 Prepare the operator account [#15-prepare-the-operator-account]

To create a dedicated operator user and switch to it before installing MyTonCtrl:

1. Create a non-root user:

   ```bash
   # Create a non-root operator user
   sudo adduser <USERNAME>
   sudo usermod -aG sudo <USERNAME>
   ```

2. Switch to the new operator account by reconnecting via SSH:

   <CodeGroup>
     <CodeBlockTabs defaultValue="Standard port">
       <CodeBlockTabsList>
         <CodeBlockTabsTrigger value="Standard port">
           Standard port
         </CodeBlockTabsTrigger>

         <CodeBlockTabsTrigger value="Custom SSH port">
           Custom SSH port
         </CodeBlockTabsTrigger>
       </CodeBlockTabsList>

       <CodeBlockTab value="Standard port">
         ```bash
         # Option 1: Reconnect using the standard port
         exit
         ssh <USERNAME>@<SERVER_IP>
         ```
       </CodeBlockTab>

       <CodeBlockTab value="Custom SSH port">
         ```bash
         # Option 2: Reconnect using the custom SSH port
         exit
         ssh <USERNAME>@<SERVER_IP> -p <SSH_PORT>
         ```
       </CodeBlockTab>
     </CodeBlockTabs>
   </CodeGroup>

### 1.6 Benchmark server performance [#16-benchmark-server-performance]

Before installing, verify that the server meets performance requirements. Inadequate disk or network performance is the most common cause of node instability.

#### 1.6.1 Network latency [#161-network-latency]

Check latency to TON beacon nodes. Expect approximately 50 milliseconds to the nearest beacon and up to 300 milliseconds to the farthest:

```bash
ping beacon-eu-01.toncenter.com -c 6
ping beacon-apac-01.toncenter.com -c 6
```

#### 1.6.2 Disk IOPS [#162-disk-iops]

Install `fio` and run a random read/write benchmark:

```bash
sudo apt install -y fio
fio --randrepeat=1 --ioengine=psync --direct=1 --gtod_reduce=1 --name=tlstest --bs=4k --iodepth=1 --size=40G --readwrite=randrw --numjobs=1 --group_reporting --filename=/tmp/ton-testfile --time_based=1 --runtime=60 --refill_buffers --buffer_compress_percentage=0
rm /tmp/ton-testfile
```

The `--refill_buffers` and `--buffer_compress_percentage=0` flags force incompressible data. Without them, LZ4 on the `data/ton-work` dataset collapses `fio`'s zero-filled writes and reports IOPS far above what the archive import sustains.

The minimum acceptable result is 10,000 IOPS for both read and write operations. If disk performance falls below these thresholds, the liteserver may fail to keep up with network traffic. Upgrade storage before proceeding.

#### 1.6.3 Network bandwidth [#163-network-bandwidth]

Verify network throughput with `speedtest-cli`:

```bash
sudo apt install -y speedtest-cli
speedtest-cli
```

Ensure download and upload speeds meet the [1 Gbit/s requirement](#1-1-minimal-hardware-requirements).

### 1.7 Harden server security [#17-harden-server-security]

Apply security hardening steps before exposing the server to the network:

* [SSH hardening](#ssh-hardening)
* [Firewall configuration](#firewall-configuration)
* [Additional security measures](#additional-security-measures)

#### SSH hardening [#ssh-hardening]

<Callout type="caution" title="Avoid locking yourself out">
  Disabling password login, changing the SSH port, and restricting access by `Match Address` can lock the operator out of a remote server. Keep the current SSH session open and confirm a new login succeeds in a second session before closing the first one.
</Callout>

Apply the following SSH configuration changes in `/etc/ssh/sshd_config`:

* Enable key-based authentication and disable password login:

  ```text
  PasswordAuthentication no
  PubkeyAuthentication yes
  ```

* Disable root login:

  ```text
  PermitRootLogin no
  ```

* Change the default SSH port, e.g., to `2222`:

  ```text
  Port <SSH_PORT>
  ```

* Restrict SSH access to specific permitted IP addresses using the `Match Address` directive:

  ```text
  Match Address <ALLOWED_IP>
    AllowUsers <USERNAME>
  ```

  There, `<USERNAME>` is the name of the operator user.

Restart the SSH service after changes:

```bash
sudo systemctl restart sshd
```

#### Firewall configuration [#firewall-configuration]

Enable the firewall and allow only the SSH port. The node UDP port and liteserver port are added after installation in [open the node UDP port and the liteserver port](#2-2-1-open-the-node-udp-port-and-the-liteserver-port).

```bash
sudo apt install -y ufw
sudo ufw allow <SSH_PORT>
sudo ufw enable
sudo ufw status
```

#### Additional security measures [#additional-security-measures]

* Use a unique, strong password for the root user.

* Set a GRUB bootloader password to prevent unauthorized boot modifications.

* Enable Fail2ban for SSH brute-force protection:

  ```bash
  sudo apt install -y fail2ban
  sudo systemctl enable fail2ban
  sudo systemctl start fail2ban
  ```

* Configure two-factor authentication for SSH using `libpam-google-authenticator` or a similar PAM module.

## Step 2: Archive liteserver installation [#step-2-archive-liteserver-installation]

The installation process consists of three stages (in total, this can take up to a week):

* Download historical blocks from TON Storage and install the archive liteserver
* Import downloaded data into the archive liteserver database
* Final synchronization of the archive liteserver

### 2.1 Download historical blocks from TON Storage and install the archive liteserver [#21-download-historical-blocks-from-ton-storage-and-install-the-archive-liteserver]

This process can take from one to several days depending on the internet connection speed.

#### 2.1.1 Install prerequisites and download MyTonCtrl installer [#211-install-prerequisites-and-download-mytonctrl-installer]

```bash
sudo apt update
sudo apt install -y curl wget git ca-certificates python3-pip
wget https://raw.githubusercontent.com/ton-blockchain/mytonctrl/master/scripts/install.sh
```

#### 2.1.2 Run archive liteserver installation [#212-run-archive-liteserver-installation]

Run the installer from the operator account with `sudo` so it can create system users and services:

<CodeGroup>
  <CodeBlockTabs defaultValue="Mainnet">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="Mainnet">
        Mainnet
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Testnet">
        Testnet
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="Mainnet">
      ```bash
      sudo -v && nohup sudo bash install.sh -m liteserver -n mainnet --archive > mytonctrl_installation.log 2>&1 &
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Testnet">
      ```bash
      sudo -v && nohup sudo bash install.sh -m liteserver -n testnet --archive > mytonctrl_installation.log 2>&1 &
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

Installation runs in the background.

Monitor the progress using the following command:

```bash
tail -f mytonctrl_installation.log
```

During the download process, the log contains entries like the following:

```text
[info]    24.04.2026, 14:26:47.609 (UTC)  <ThreadPoolExecutor-0_3>STARTING DOWNLOADING e88e7e805dfa16dc6e7d3864fcc00159a1ee70edde7b421428783c2164453875
[info]    24.04.2026, 14:27:07.611 (UTC)  <ThreadPoolExecutor-0_3>DOWNLOADING e88e7e805dfa16dc6e7d3864fcc00159a1ee70edde7b421428783c2164453875 0% (0.0 / 4296.493726 MB), speed: 0.0 MB/s
[info]    24.04.2026, 14:27:07.623 (UTC)  <ThreadPoolExecutor-0_2>DOWNLOADING 7683b6bc2c19e007fc6d363dc233ff9a405c0fee7533c2904c06943f759c155f 3% (130.766577 / 4295.81461 MB), speed: 15.078028 MB/s
[info]    28.04.2026, 11:43:00.687 (UTC)  <ThreadPoolExecutor-0_1>DOWNLOADING fd41a820efc4f459bb1518c45fcc23023b0a95d9446c683705802bfb9d50a0c9 95% (4072.892954 / 4296.3534 MB), speed: 28.962779 MB/s
[info]    28.04.2026, 11:43:20.700 (UTC)  <ThreadPoolExecutor-0_1>DOWNLOADED fd41a820efc4f459bb1518c45fcc23023b0a95d9446c683705802bfb9d50a0c9
```

Upon successful completion of the installation, the following line appears in the log:

```text
[5/5] Mytonctrl installation completed
```

### 2.2 Import downloaded data into the archive liteserver database [#22-import-downloaded-data-into-the-archive-liteserver-database]

This process starts automatically after installation and can take from one to several days depending on server performance.

Monitor the progress from the MyTonCtrl console. Open the console:

```bash
mytonctrl
```

At the `MyTonCtrl>` prompt, run:

```text
MyTonCtrl> status
```

Check the `Local validator initial sync status` field. The value indicates how old the last imported block was and should decrease over time.

#### 2.2.1 Open the node UDP port and the liteserver port [#221-open-the-node-udp-port-and-the-liteserver-port]

At this stage, the node UDP port and liteserver port should be opened to make the archive liteserver available for syncing blocks from other nodes.

Identify the node UDP port and liteserver port from the `config.json` file:

```bash
sudo grep -A5 '"addrs"' -n /var/ton-work/db/config.json | grep '"port"' | head -1
sudo grep -A5 '"liteservers"' -n /var/ton-work/db/config.json | grep '"port"' | head -1
```

Update security groups or configure `ufw` on bare-metal hosts:

```bash
sudo ufw allow <NODE_UDP_PORT>
sudo ufw allow <LITESERVER_PORT>
sudo ufw status
```

There,

* `<NODE_UDP_PORT>` is the UDP port of the validator engine;
* `<LITESERVER_PORT>` is the TCP port of the liteserver.

### 2.3 Final synchronization of archive liteserver [#23-final-synchronization-of-archive-liteserver]

This process starts automatically after the importing process finishes and can take from one to several days depending on server performance.

Monitor the progress from the MyTonCtrl console. Open the console:

```bash
mytonctrl
```

At the `MyTonCtrl>` prompt, run:

```text
MyTonCtrl> status
```

While initial sync continues, the `Local validator initial sync status` field reports how old the last imported block was, decreasing over time. Once initial sync completes, that line disappears and freshness is reported by the `Local validator out of sync` field. On a fully synchronized node, out-of-sync time stays below 20 seconds.

## Step 3: Maintenance [#step-3-maintenance]

### 3.1 Set up alerting [#31-set-up-alerting]

Set up alerting in MyTonCtrl to get a notification of critical issues with the archive liteserver. For more information, see [MyTonCtrl private alerting bot](/llms/ecosystem/nodes/cpp/mytonctrl/alerting/content.md).

### 3.2 Set up monitoring [#32-set-up-monitoring]

Set up monitoring dashboards for RAM, disk, network, CPU usage, and other metrics.

It is critical to use the monitoring system to:

* monitor server stability;
* monitor synchronization parameters;
* check for memory leaks.

For system-level metrics, [integrate Prometheus with `node_exporter` with MyTonCtrl](/llms/ecosystem/nodes/cpp/integrating-with-prometheus/content.md).

For technical assistance, contact [`@mytonctrl_help_bot`](https://t.me/mytonctrl_help_bot).

### 3.3 Perform software updates [#33-perform-software-updates]

<Callout type="note">
  Follow the [`@tonstatus`](https://t.me/tonstatus) channel, turn on notifications, and be prepared for urgent updates.
</Callout>

Before performing updates, create a ZFS snapshot of the data. This allows a quick rollback if the update process fails or corrupts the database.

```bash
sudo zfs snapshot data/ton-work@before-update-$(date +%Y-%m-%d)
```

Update the node software and MyTonCtrl from the console. Open the console:

```bash
mytonctrl
```

At the `MyTonCtrl>` prompt, update MyTonCtrl to the tip of the `master` branch:

```text
MyTonCtrl> update master
```

The console exits when `update` finishes. Reopen it with `mytonctrl` and upgrade the TON node binaries to the tip of the `master` branch:

```text
MyTonCtrl> upgrade master
```

These commands check for new versions of MyTonCtrl and the TON node binaries, download them, and apply the updates. The update process may cause temporary node downtime as the binaries are replaced and services are restarted.

Once the update is verified as successful and the node is running correctly, delete the snapshot to reclaim disk space.

### 3.4 ZFS snapshots [#34-zfs-snapshots]

ZFS creates snapshots for easy rollbacks if data corruption occurs.

#### Create a snapshot [#create-a-snapshot]

Snapshots can be created under a unique identifier without stopping the node :

```bash
sudo zfs snapshot data/ton-work@<SNAPSHOT_NAME>
```

#### List snapshots [#list-snapshots]

To see all existing snapshots for the `data/ton-work` dataset:

```bash
sudo zfs list -t snapshot data/ton-work
```

#### Roll back to a snapshot [#roll-back-to-a-snapshot]

<Callout type="caution" title="Data loss risk">
  Rolling back to a snapshot overwrites all database changes made since the snapshot was created. Stop the validator service before performing the rollback:

  ```bash
  # Stop the service
  sudo systemctl stop validator.service

  # Roll back to the snapshot
  sudo zfs rollback data/ton-work@<SNAPSHOT_NAME>

  # Start the service
  sudo systemctl start validator.service
  ```
</Callout>

#### Delete a snapshot [#delete-a-snapshot]

Delete the snapshot when it is no longer needed:

```bash
sudo zfs destroy data/ton-work@<SNAPSHOT_NAME>
```

### 3.5 Archive ZFS snapshots [#35-archive-zfs-snapshots]

Creating a snapshot is instantaneous and occurs on the same physical disks where the data is stored. To protect against hardware failure, export the snapshots to external storage or a remote server using `zfs send`.

#### Export a snapshot to a file [#export-a-snapshot-to-a-file]

Before exporting, estimate the size of the snapshot:

```bash
sudo zfs send -pc -nv data/ton-work@<SNAPSHOT_NAME>
```

Expected output:

```text
full send of data/ton-work@<SNAPSHOT_NAME> estimated size is 4.07T
total estimated size is 4.07T
```

To save the snapshot to a file, use the `-c` flag to preserve LZ4 compression. Without it, the file expands to the uncompressed size of the dataset:

```bash
# Ensure the destination directory exists and has enough free space!
sudo zfs send -c data/ton-work@<SNAPSHOT_NAME> > <BACKUP_PATH>
```

Example destination path on the external storage: `/mnt/backup/backup_ton_work.zfs`

<Callout type="note">
  Exporting large datasets can take several hours. For example, a 4.07 TB snapshot may take approximately 2 hours to export, depending on disk throughput.
</Callout>

#### Transfer a snapshot via SSH [#transfer-a-snapshot-via-ssh]

Stream a snapshot directly to a remote ZFS-enabled server:

```bash
sudo zfs send -c data/ton-work@<SNAPSHOT_NAME> | ssh <REMOTE_USER>@<REMOTE_HOST> "sudo zfs recv <REMOTE_POOL>/ton-work"
```

There,

* `<REMOTE_USER>` is the username on the remote host;
* `<REMOTE_HOST>` is an IP address or hostname of the remote host;
* `<REMOTE_POOL>` is the name of the remote ZFS pool.

## Troubleshooting [#troubleshooting]

### Monitor import logs [#monitor-import-logs]

To see detailed logs of the block import process, increase the log verbosity from the MyTonCtrl console. Open the console:

```bash
mytonctrl
```

At the `MyTonCtrl>` prompt, run:

```text
MyTonCtrl> installer set_node_argument --verbosity 3
```

Then follow the log file from a separate terminal:

```bash
tail -f /var/ton-work/log*
```

Expected log entries:

```text
[ 2][t49][2025-01-01 00:00:00.632][import-db-slice-local.cpp:629][!archiveimport] Imported archive in 2.75s : mc_seqno=761229 shard_seqno=761229
```

Set verbosity back to `1` after checking logs to avoid excessive disk I/O overhead. At the `MyTonCtrl>` prompt, run:

```text
MyTonCtrl> installer set_node_argument --verbosity 1
```

### Performance issues [#performance-issues]

Logs containing `"Importing archive for masterchain seqno #... from net"` accompanied by timeout errors indicate insufficient storage performance. Ensure the disk meets the IOPS requirements listed in [Minimal hardware requirements](#1-1-minimal-hardware-requirements).

To verify disk and system performance, run the built-in `mytonctrl` benchmark:

1. Stop the validator service, since the benchmark refuses to run while it is active:

   ```bash
   sudo systemctl stop validator.service
   ```

2. Open the MyTonCtrl console:

   ```bash
   mytonctrl
   ```

   At the `MyTonCtrl>` prompt, run:

   ```text
   MyTonCtrl> benchmark
   ```

   The benchmark spins up a local test network and requires `uv`. If `uv` is not installed, the console prompts to install it. For stable liteserver operation, the reported `Avg TPS` and `Avg blocks/s` should each reach at least 70% of their expected values.

3. Restart the validator service once the benchmark finishes:

   ```bash
   sudo systemctl start validator.service
   ```

## Support [#support]

For technical assistance, join the official support channel: [`@ton_node_help`](https://t.me/ton_node_help).

## See also [#see-also]

* [Run a liteserver node with MyTonCtrl](/llms/ecosystem/nodes/cpp/run-liteserver/content.md)
* [Run a validator node with MyTonCtrl](/llms/ecosystem/nodes/cpp/run-validator/content.md)
* [Set up a node with MyTonCtrl](/llms/ecosystem/nodes/cpp/setup-mytonctrl/content.md)
* [TON node types](/llms/ecosystem/nodes/overview/content.md)
