Yugabyte’s Smart Drivers (Java, Python, Go, etc.) handle load balancing, leader routing, etc.
C++, however, doesn’t yet have that…
But we can use libpq (PostgreSQL C client) to distribute connections across multiple hosts with minimal effort, starting from PostgreSQL client 16+, via load_balance_hosts=random. And because YSQL is wire-compatible with PostgreSQL, this just works with YugabyteDB. Let’s see how.
Install Prereqs
•
g++(C++ compiler)•
libpq(PostgreSQL client libraries v16+)•
libpqxx(C++ wrapper for libpq)
Ubuntu / Debian
sudo apt update
sudo apt install -y g++ libpq-dev libpqxx-dev
pg_config --version # should say 16.x or newer
macOS (Homebrew)
brew install libpq libpqxx
echo 'export PATH="/opt/homebrew/opt/libpq/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
pg_config --version
AlmaLinux / RHEL 9
# Enable PostgreSQL 16 repo
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm
# Install base deps
sudo dnf install -y gcc-c++ make pkg-config
# Install libpq 16 and headers
sudo dnf install -y postgresql16-devel
# libpqxx (C++ wrapper)
sudo dnf install -y libpqxx-devel || {
echo "If not available, enable EPEL or build libpqxx from source:"
echo " sudo dnf install -y epel-release && sudo dnf install -y libpqxx-devel"
}
# Verify
/usr/pgsql-16/bin/pg_config --version
Quick Cluster Check
for H in 127.0.0.1 127.0.0.2 127.0.0.3; do
PGPASSWORD=yugabyte ysqlsh "host=$H port=5433 dbname=yugabyte user=yugabyte" \
-c "SELECT split_part(version(), '-', 3) yb_version, inet_server_addr();"
done
Example:
[root@localhost ~]# for H in 127.0.0.1 127.0.0.2 127.0.0.3; do
PGPASSWORD=yugabyte ysqlsh "host=$H port=5433 dbname=yugabyte user=yugabyte" \
-c "SELECT split_part(version(), '-', 3) yb_version, inet_server_addr();"
done
yb_version | inet_server_addr
------------+------------------
2025.1.0.0 | 127.0.0.1
(1 row)
yb_version | inet_server_addr
------------+------------------
2025.1.0.0 | 127.0.0.2
(1 row)
yb_version | inet_server_addr
------------+------------------
2025.1.0.0 | 127.0.0.3
(1 row)
Create a simple table to query later:
PGPASSWORD=yugabyte ysqlsh \
"host=127.0.0.1 port=5433 dbname=yugabyte user=yugabyte" \
-c "CREATE TABLE IF NOT EXISTS lb_demo(id INT PRIMARY KEY, note TEXT);
INSERT INTO lb_demo VALUES (1, 'Hello from YB!');"
Minimal C++ Program
Save as yb_lb_demo.cpp:
#include
#include
int main() {
const std::string conninfo =
"host=127.0.0.1,127.0.0.2,127.0.0.3 "
"port=5433 dbname=yugabyte user=yugabyte password=yugabyte "
"sslmode=disable load_balance_hosts=random target_session_attrs=any";
try {
pqxx::connection c{conninfo};
pqxx::work tx{c};
auto r = tx.exec(
"SELECT inet_server_addr()::TEXT AS server_ip, inet_server_port() AS server_port, "
"(SELECT note FROM lb_demo WHERE id = 1) AS note");
tx.commit();
std::cout << "Connected to: "
<< r[0]["server_ip"].c_str() << ":" << r[0]["server_port"].as()
<< " | note=" << r[0]["note"].c_str() << "\n";
} catch (const std::exception &e) {
std::cerr << "Error: " << e.what() << "\n";
return 1;
}
return 0;
}
Build it:
g++ -std=c++17 yb_lb_demo.cpp $(pkg-config --cflags --libs libpqxx) -o yb_lb_demo
Run It
for i in {1..12}; do ./yb_lb_demo; done
Example:
[root@localhost ~]# for i in {1..12}; do ./yb_lb_demo; done
Connected to: 127.0.0.1/32:5433 | note=Hello from YB!
Connected to: 127.0.0.3/32:5433 | note=Hello from YB!
Connected to: 127.0.0.3/32:5433 | note=Hello from YB!
Connected to: 127.0.0.2/32:5433 | note=Hello from YB!
Connected to: 127.0.0.2/32:5433 | note=Hello from YB!
Connected to: 127.0.0.1/32:5433 | note=Hello from YB!
Connected to: 127.0.0.2/32:5433 | note=Hello from YB!
Connected to: 127.0.0.2/32:5433 | note=Hello from YB!
Connected to: 127.0.0.1/32:5433 | note=Hello from YB!
Connected to: 127.0.0.3/32:5433 | note=Hello from YB!
Connected to: 127.0.0.2/32:5433 | note=Hello from YB!
Connected to: 127.0.0.2/32:5433 | note=Hello from YB!
Each run shows a different IP, connections are load balanced across your cluster.
Why It Matters
✅ Uses stock PostgreSQL client libs
✅ Works with YugabyteDB’s PostgreSQL-compatible YSQL API
✅ Balances connections across nodes
✅ Perfect for apps with connection pooling
Wrap-Up
Even without a dedicated Smart Driver for C++, you can still achieve simple, effective connection load balancing against a YugabyteDB cluster using libpq v16+ and libpqxx.
Have Fun!
