Back to articles
Technology Insight

Building a High-Availability Database Layer: Deploying Real-Time Distributed SQLite with rqlite on Oracle Cloud Free Tier ARM VPS

June 7, 2026

Introduction to High-Availability Database Architecture on a Budget

In modern cloud architecture, achieving high availability (HA) and fault tolerance typically demands a significant financial investment. Enterprises routinely allocate substantial budgets to managed database services to ensure seamless failover and data consistency. However, the convergence of two powerful technologies—Oracle Cloud Infrastructure (OCI) Free Tier ARM Ampere Compute and rqlite, the distributed relational database—presents a disruptive alternative. This combination allows engineers to architect and deploy a robust, real-time distributed database cluster entirely within a generous free-tier allocation.

While standard SQLite is renowned for its lightweight footprint and exceptional single-node read performance, its lack of native network access and clustering mechanisms makes it unsuitable for distributed microservices. This is where rqlite steps in. By wrapping the core SQLite engine in a Raft consensus protocol layer, rqlite transforms an embedded database into a highly available, replicated, and network-accessible system. In this comprehensive technical guide, we will walk through the exact steps required to deploy a multi-node rqlite cluster across Oracle's powerful ARM-based virtual private servers (VPS).

Understanding the Core Technologies: rqlite and OCI ARM Ampere

Before diving into the deployment phase, it is crucial to understand the architectural pillars that make this setup both viable and incredibly performant.

The Power of Oracle Cloud ARM Free Tier

Oracle Cloud Infrastructure stands out in the cloud landscape by offering up to 4 Ampere Altra ARM CPUs and 24 GB of RAM for free, which can be allocated across up to 4 distinct VPS instances. Unlike traditional x86 micro-instances offered by other cloud providers, these ARM cores provide dedicated, predictable performance and substantial memory overhead, making them ideal hosts for running distributed stateful applications like database nodes.

How rqlite Solves the Distributed State Challenge

rqlite is not a distributed SQL engine in the vein of CockroachDB or Google Spanner; rather, it is an open-source, lightweight, distributed relational database that uses SQLite as its storage engine. It provides the following key advantages:

  • Raft Consensus: Utilizing the HashiCorp Raft implementation, rqlite ensures that every write operation is committed across a quorum of nodes before being acknowledged, preventing data divergence.
  • Real-time Replication: Transactions are replicated across all cluster members in real time, guaranteeing that backup nodes are always synchronized.
  • Simplified Operations: It is compiled as a single static binary with no external dependencies, vastly simplifying deployment and maintenance on Linux systems.
  • HTTP API: Applications interact with the cluster via a clean, performant HTTP/HTTPS API, abstracting away the underlying database connection pooling complexities.

Prerequisites and Infrastructure Provisioning

To follow this guide successfully, you will need an active Oracle Cloud account. We will provision a three-node cluster to achieve an optimal fault-tolerant quorum (capable of surviving the loss of a single node without service interruption).

1. Provisioning the Virtual Machines

Log into your OCI Console and navigate to Compute > Instances. Create three instances with the following specifications:

  • Image: Ubuntu 22.04 LTS or Ubuntu 24.04 LTS (Minimal preferred)
  • Shape: VM.Standard.A1.Flex (ARM-based Ampere Altra)
  • Resource Allocation: 1 OCPU and 6 GB RAM per instance (utilizing 3 OCPUs and 18 GB RAM out of your total free tier allowance)
  • Networking: Assign a public IP to each instance and place them within the same Virtual Cloud Network (VCN).

2. Network Security and Firewalls

rqlite requires two distinct network ports to function correctly:

  1. 4001: The HTTP API endpoint used by client applications to execute queries.
  2. 4002: The internal Raft communication port used for node-to-node synchronization and consensus voting.

Go to your OCI Virtual Cloud Network (VCN), select your regional Security List, and add Ingress Rules to allow TCP traffic on ports 4001 and 4002 from within your VCN's CIDR block. For maximum security, do not expose port 4002 to the public internet.

Next, update the local iptables or ufw configuration on each of your Ubuntu nodes to permit traffic on these ports:

sudo ufw allow 4001/tcp
sudo ufw allow 4002/tcp
sudo ufw reload

Step-by-Step Deployment of rqlite on ARM Nodes

For the purpose of this guide, let us assume your three nodes have the following internal IP addresses:

  • Node 1: 10.0.0.11
  • Node 2: 10.0.0.12
  • Node 3: 10.0.0.13

Step 1: Downloading the ARM64 Binary

Since we are utilizing ARM architecture, we must download the appropriate arm64 release of rqlite. SSH into each of your three nodes and execute the following commands:

wget [https://github.com/rqlite/rqlite/releases/download/v8.x.x/rqlite-v8.x.x-linux-arm64.tar.gz](https://github.com/rqlite/rqlite/releases/download/v8.x.x/rqlite-v8.x.x-linux-arm64.tar.gz)
tar -xvf rqlite-v8.x.x-linux-arm64.tar.gz
sudo mv rqlite-v8.x.x-linux-arm64/rqlited /usr/local/bin/
sudo mv rqlite-v8.x.x-linux-arm64/rqlite /usr/local/bin/

Note: Replace v8.x.x with the latest stable production release available on the rqlite GitHub repository.

Step 2: Initializing the Leader Node (Node 1)

The first node acts as the seed node to bootstrap our cluster. Run the following command on Node 1 to initialize the database:

rqlited -node-id node1 \
        -http-addr 10.0.0.11:4001 \
        -raft-addr 10.0.0.11:4002 \
        ~/rqlite-data

This tells rqlited to launch using Node 1's private IP, bind to the correct communication ports, and store its persistent data directory in the user's home directory.

Step 3: Joining Follower Nodes to the Cluster (Nodes 2 & 3)

With the leader running, we can now join the remaining two nodes to form our quorum. On Node 2, execute:

rqlited -node-id node2 \
        -http-addr 10.0.0.12:4001 \
        -raft-addr 10.0.0.12:4002 \
        -join [http://10.0.0.11:4001](http://10.0.0.11:4001) \
        ~/rqlite-data

Similarly, execute the following on Node 3:

rqlited -node-id node3 \
        -http-addr 10.0.0.13:4001 \
        -raft-addr 10.0.0.13:4002 \
        -join [http://10.0.0.11:4001](http://10.0.0.11:4001) \
        ~/rqlite-data

The -join flag directs the new instances to target Node 1's HTTP API. Node 1 coordinates with the Raft subsystem to safely integrate Node 2 and Node 3 into the cluster architecture.

Verifying Cluster Health and Consensus Mechanics

Once all nodes are running, verify that the cluster has successfully formed and elected a leader. You can use the included rqlite CLI tool on any node to check status:

rqlite -H 10.0.0.11 -P 4001

Once connected, run the .status command. You should observe output indicating that there are 3 reachable nodes, with one node designated as the leader and the other two as followers.

To test real-time replication, create a test table via the API or CLI:

CREATE TABLE company (id INTEGER PRIMARY KEY, name TEXT, industry TEXT);
INSERT INTO company (name, industry) VALUES ('Oracle', 'Cloud Infrastructure');

Log into Node 3 and query the database locally. You will observe that the data has been replicated instantaneously down to the millisecond across the physical distance of your cloud subnet.

Production Considerations and Best Practices

Deploying a distributed database cluster in a development environment is straightforward, but running it reliably under production workloads requires careful attention to system design details.

1. Setting Up systemd Services

To ensure rqlite automatically recovers if an underlying Oracle ARM instance reboots or crashes, encapsulate the execution parameters inside a systemd service file located at /etc/systemd/system/rqlite.service. Configure it with Restart=always and ensure it runs under a dedicated, non-root system user.

2. Handling Node Failures and Network Partitions

With a three-node setup, your cluster can tolerate the loss of exactly one node. If one follower goes offline, the remaining two nodes still represent a strict majority (2 out of 3), allowing write operations to proceed normally. If a network partition isolates two nodes, writes will automatically freeze on the isolated node to prevent split-brain scenarios, prioritizing data consistency over availability.

3. Load Balancing Client Traffic

To build an enterprise-grade setup, avoid pointing your microservices directly to a single rqlite node's IP. Instead, deploy an internal load balancer (such as HAProxy or NGINX) in front of the HTTP APIs. Configure the load balancer to poll the rqlite /status endpoint; this ensures that write traffic is always intelligently directed to the current Raft leader, while read traffic can be optionally distributed across follower nodes to maximize read throughput.

Conclusion: High Availability Redefined

Deploying a real-time distributed SQLite cluster using rqlite on Oracle Cloud's Free Tier ARM VPS represents an optimal synergy between cost-efficiency and cutting-edge database engineering. By combining the rock-solid reliability of SQLite with the Raft consensus protocol, developers gain access to a highly available, transactional database layer capable of powering production workloads without incurring massive cloud provider bills. As you scale, this architecture allows you to easily expand your cluster size, ensuring your data layer remains robust, resilient, and perpetually accessible.