High Availability
Overview
High Availability (HA) mode allows the Intelligence Hub to run across multiple nodes, ensuring continuous operation and failover. Only one node is active at a time; standby nodes are ready to take over if the primary node fails. This is managed through heartbeats and file synchronization.
All HA coordination is managed through a PostgreSQL database. Nodes do not communicate directly with each other; instead, each node interacts independently with the PostgreSQL server for heartbeat management, leadership election, and data synchronization.
- Heartbeats: Each node periodically signals its status to the PostgreSQL database. If the primary node stops sending heartbeats, a standby node automatically takes over.
- File Synchronization: Configuration files in appData, which includes Connection and Pipeline State Extension caches, are regularly synced through the PostgreSQL database to ensure a standby node can seamlessly assume the primary role.
The primary and standby hubs can be configured using either the Command Line or Environment Variables.
Command Line
Below are details on the command line arguments to configure and start HA. The primary commands are as follows:
create: Initializes the failover service, syncs initial configuration and state files, and sets the node ID as the preferred primary node.- The preferred primary node is always selected as primary when available.
start: Starts a node in HA mode, joining the failover group.help: Displays usage information.
The basic command syntax looks as follows, with the arguments detailed below. It’s best to run these commands from the runtime directory.
Windows:
java -cp "intelligencehub-runtime.jar;lib/*" com.highbyte.intelligencehub.runtime.HAMain [options] <create|start|help>
Linux/macOS:
java -cp "intelligencehub-runtime.jar:lib/*" com.highbyte.intelligencehub.runtime.HAMain [options] <create|start|help>
| Option | Description | Example Value |
|---|---|---|
-j, --jdbcURI | JDBC URI for the node | jdbc:postgresql://<db-host>:5432/<db-name>?user=<username>&password=<password>env:URI |
-n, --nodeId | Unique node ID for the HA instance | |
-e, --heartbeatExpiration | Set the Heartbeat expiration period. Defaults to 10s. Minimum value of 2. create only | -e 30env:HBE |
create is intended for one-time initialization. It drops and recreates the synchronization tables in the PostgreSQL database and repopulates them from the local files of the node running it. Running create again on an existing cluster discards the synchronized configuration, cache, and state of the cluster.env:<VAR>, which keeps the database credentials off the command line. For example, -j env:URI reads the JDBC URI from the URI environment variable.Command Line Setup
To set up a primary and standby hub using the command line, follow the steps below.
Install or have available a PostgreSQL server.
Install the primary and standby hubs.
On the primary hub, run the
createcommand to initialize the database tables used for synchronization and assign this node as the preferred primary.Windows:
java -cp "intelligencehub-runtime.jar;lib/*" com.highbyte.intelligencehub.runtime.HAMain create -n <primary-name> -j "jdbc:postgresql://<db-host>:5432/<db-name>?user=<username>&password=<password>"Linux/macOS:
java -cp "intelligencehub-runtime.jar:lib/*" com.highbyte.intelligencehub.runtime.HAMain create -n <primary-name> -j "jdbc:postgresql://<db-host>:5432/<db-name>?user=<username>&password=<password>"Copy the
intelligencehub-certificatestore.pkcs12file from the appData of the primary hub to the appData of the standby hub so the standby hub can decrypt the secrets in the synchronized configuration.Start the primary hub with the
startcommand, using the same node ID that was used increate.Windows:
java -cp "intelligencehub-runtime.jar;lib/*" com.highbyte.intelligencehub.runtime.HAMain start -n <primary-name> -j "jdbc:postgresql://<db-host>:5432/<db-name>?user=<username>&password=<password>"Linux/macOS:
java -cp "intelligencehub-runtime.jar:lib/*" com.highbyte.intelligencehub.runtime.HAMain start -n <primary-name> -j "jdbc:postgresql://<db-host>:5432/<db-name>?user=<username>&password=<password>"Start the standby hub with the
startcommand, using a new unique node ID.Windows:
java -cp "intelligencehub-runtime.jar;lib/*" com.highbyte.intelligencehub.runtime.HAMain start -n <standby-name> -j "jdbc:postgresql://<db-host>:5432/<db-name>?user=<username>&password=<password>"Linux/macOS:
java -cp "intelligencehub-runtime.jar:lib/*" com.highbyte.intelligencehub.runtime.HAMain start -n <standby-name> -j "jdbc:postgresql://<db-host>:5432/<db-name>?user=<username>&password=<password>"
Environment Variables
HA mode is enabled by setting three environment variables before starting the hub.
Where the variables are set depends on how the hub runs. See Windows Service, Linux systemd Service, or Docker for specifics. The examples in those sections configure the standby hub. For the primary hub, use its own node ID and HA_INIT until the cluster is initialized.
| Environment Variable | Description |
|---|---|
START_MODE | Controls how the node joins the HA cluster.HA_INIT: Initializes a new HA cluster and starts the node as the primary. Set this on the primary hub only.HA_JOIN: Joins an existing HA cluster. Set this on the standby hub, and on the primary hub once the cluster is initialized. |
HA_NODE_ID | Unique node ID for this HA instance |
HA_POSTGRES_URI | JDBC URI for the PostgreSQL database |
HA_INIT is intended for one-time initialization. It drops and recreates the synchronization tables in the PostgreSQL database and repopulates them from the local files of the node running it. If START_MODE is left set to HA_INIT, every restart of that node discards the synchronized configuration, cache, and state of the cluster. Change START_MODE to HA_JOIN once the cluster is initialized.START_MODE is set to HA_INIT or HA_JOIN and HA_NODE_ID or HA_POSTGRES_URI is missing, the start script reports that both are required and exits without starting the hub. If START_MODE is not set, or is set to any other value, the start script launches a standalone hub without reporting an error. The values are case-sensitive.HA_POSTGRES_URI contains the database user name and password, so prefer a storage location that can be permission restricted, and avoid committing it to source control.create command described in Command Line, then set START_MODE to HA_JOIN on both hubs instead of using HA_INIT.runtime directory read these variables and launch the node in HA mode, so no changes to the scripts themselves are required. This applies to start-windows.bat, start-linux.sh, start-macos.sh, and the start.sh script used by the Docker image.Environment Variables Setup
To set up a primary and standby hub using environment variables, follow the steps below.
Install or have available a PostgreSQL server.
Install the primary and standby hubs.
On the primary and standby hubs, set the environment variables.
Start the primary hub to initialize the database tables used for synchronization, push the initial configuration and state, assign this node as the preferred primary, and then run the node.
Change
START_MODEtoHA_JOINon the primary hub so that a later restart does not reinitialize the cluster.Copy the
intelligencehub-certificatestore.pkcs12file from the appData of the primary hub to the appData of the standby hub so the standby hub can decrypt the secrets in the synchronized configuration. The certificates in this file are synchronized, but the mechanisms used to encrypt and decrypt secrets are not.Start the standby hub.
Windows Service
The HighByte Intelligence Hub Runtime service starts the hub by calling start-windows.bat, so the environment variables must be available to the service process.
Define the three variables as system variables under System Properties, Environment Variables, or add an env element for each variable inside the <service> element of runtime\service\service-installer-windows.xml, which limits the variables to the service:
<env name="START_MODE" value="HA_JOIN"/>
<env name="HA_NODE_ID" value="<standby-name>"/>
<env name="HA_POSTGRES_URI" value="jdbc:postgresql://<db-host>:5432/<db-name>?user=<username>&password=<password>"/>
Restart the HighByte Intelligence Hub Runtime service to apply changes to the env elements.
START_MODE to HA_JOIN. Restarting only the service is not enough, and with HA_INIT still in effect, a service restart reinitializes the cluster.runtime directory, so changes made to service-installer-windows.xml need to be applied again after an upgrade. See Run as a Service for details on the service and its configuration file.Linux systemd Service
Add the environment variables inline to the [Service] section of the unit file:
Environment=START_MODE=HA_JOIN
Environment=HA_NODE_ID=<standby-name>
Environment=HA_POSTGRES_URI=jdbc:postgresql://<db-host>:5432/<db-name>?user=<username>&password=<password>
% in Environment= values as a specifier, so write any % in the password as %%. The EnvironmentFile= form does not need this.Alternatively, point to a separate file that holds them, which can be permission restricted:
EnvironmentFile=/etc/highbyte/ha.env
The /etc/highbyte/ha.env file contains one variable per line:
START_MODE=HA_JOIN
HA_NODE_ID=<standby-name>
HA_POSTGRES_URI=jdbc:postgresql://<db-host>:5432/<db-name>?user=<username>&password=<password>
Reload the unit and restart the service to apply the change:
sudo systemctl daemon-reload
sudo systemctl restart highbyte.service
Docker
When running the Intelligence Hub in Docker, set the environment variables in the container configuration.
docker run -p 45245:45245 -p 1885:1885 -p 8885:8885 -e ACCEPT_EULA=Y --name highbyte \
--mount source=hb_vol,target=/usr/local/highbyte/appData \
--restart=unless-stopped \
-e START_MODE=HA_JOIN \
-e HA_NODE_ID=<standby-name> \
-e HA_POSTGRES_URI="jdbc:postgresql://<db-host>:5432/<db-name>?user=<username>&password=<password>" \
highbyte:X.X.X
The variables are part of the container configuration, so they apply every time the container starts. Include a restart policy such as --restart=unless-stopped so the container comes back after a failure or a host reboot.
To copy intelligencehub-certificatestore.pkcs12 out of the primary hub’s container, run the following on the primary host:
docker cp highbyte:/usr/local/highbyte/appData/intelligencehub-certificatestore.pkcs12 <folder>
To copy the file into a new volume for the standby hub, run the following on the standby host before its first start. It runs the copy with the hub image so the file is owned by the user the container runs as:
docker run --rm --entrypoint cp \
--mount source=hb_vol,target=/usr/local/highbyte/appData \
--mount type=bind,source=<folder>,target=/src \
highbyte:X.X.X /src/intelligencehub-certificatestore.pkcs12 /usr/local/highbyte/appData/
START_MODE=HA_INIT, then recreate it with START_MODE=HA_JOIN and the same appData volume so a restart does not reinitialize the cluster.Failover Behavior
Heartbeat and Lease Management
The HA system uses a heartbeat mechanism to monitor node health and manage leadership:
- Heartbeat interval: Every 5 seconds. If a manual Heartbeat Expiration Period is set, the interval is half that value, rounded down to the nearest second.
- Heartbeat expiration period: 10 seconds
- Typical failover window: 5–15 seconds by default. With a custom Heartbeat Expiration Period, the window ranges from the heartbeat interval to the heartbeat interval plus the expiration period.
- Best case: ~heartbeat interval (standby detects failure on its next heartbeat)
- Worst case: ~heartbeat interval + expiration period (standby waits for next heartbeat after primary heartbeat expires)
The primary node renews its heartbeat in the PostgreSQL database at the heartbeat interval (5 seconds by default). If a primary node fails to check in, the heartbeat expires after the configured Heartbeat Expiration Period (10 seconds by default). Standby nodes also send heartbeats at the same interval, and the first standby to send a heartbeat after the primary’s heartbeat expires is elected as the new primary by the database.
File Synchronization
The following files are maintained and synchronized across all nodes in the HA cluster:
Configuration Files:
intelligencehub-configuration.json- Project configurationintelligencehub-settings.json- System settingsintelligencehub-systemvariables.json- System variablesintelligencehub-remoteconfig.json- Remote configuration settingsintelligencehub-users.json- User accounts, roles, and API keysintelligencehub-secrets.json- Encrypted secretsintelligencehub-certificatestore.pkcs12- Only certificates and private keys are maintained. The mechanisms used for encrypting and decrypting secrets will remain on the local instance. To decrypt secrets across multiple HA instances, copy the pkcs12 file of the primary to each instance.intelligencehub-identityproviders.json- Identity provider configurationsintelligencehub.license- License file
Data Stores:
intelligencehub-cache.db- Cache storeintelligencehub-state.db- State store
Configuration and data stores are synchronized between nodes to ensure a standby can seamlessly take over:
- Primary mode sync interval: Half the Heartbeat Expiration Period, rounded down to the nearest second (5 seconds by default). Pushes changes to the database.
- Standby mode sync interval: Six times the Heartbeat Expiration Period (60 seconds by default). Pulls changes from the database.
- Sync operations:
- Deployment files are compared by hash before transfer. Files are synced when there is a change.
- Cache and state stores only push the most recent 10,000 values per sync attempt
- Data retention:
- Data from the Data Stores are retained on the PostgreSQL database for up to 24 hours
- Each transaction row is tracked relative to its upload time
- Transactions that haven’t been updated and are older than 24 hours are automatically deleted
- To miss data, more than 10,000 unique transactions per 5 seconds would need to occur in the cache or state stores
Promotion Process
When a Standby Becomes Primary
- Pre-promotion sync: Standby performs one final pull to ensure data consistency
- Runtime startup: Starts the main runtime with synchronized data
- Heartbeat confirmation: New primary renews heartbeat at the heartbeat interval
When a Primary Node Fails
- Heartbeat expiration: After the Heartbeat Expiration Period without renewal, the heartbeat expires
- Leadership acquisition: Next heartbeat from a standby (within one heartbeat interval) acquires leadership
- Automatic promotion: Standby node detects acquisition and promotes to primary
- Service continuity: Total downtime falls within the typical failover window
When the Preferred Primary Comes Back Online
The system supports setting a preferred primary node configuration:
- When the preferred primary node comes online, it will take over from the current primary
- This happens during the next heartbeat cycle (within one heartbeat interval)
- The transition follows the same promotion process (sync → promote → start)
Graceful Shutdown
Primary Node Shutdown
- Leadership release: Immediately expires the heartbeat (sets expiration to the Heartbeat Expiration Period in the past)
- Runtime stop: Cleanly shuts down the active runtime
- Connection cleanup: Closes HA database connection
- Fast failover: Because the heartbeat expires immediately, standby nodes can acquire leadership on their next heartbeat (within one heartbeat interval)
Database
Currently, only PostgreSQL is supported for the database.