---
title: "Connecting to HeliosDB"
---

# Connecting to HeliosDB


This guide covers all the ways to connect to HeliosDB using different protocols, programming languages, and tools.

---

## Table of Contents

1. [Connection Protocols](#connection-protocols)
2. [Command-Line Clients](#command-line-clients)
3. [Programming Languages](#programming-languages)
4. [GUI Tools](#gui-tools)
5. [Connection Pooling](#connection-pooling)
6. [Security & Authentication](#security--authentication)
7. [Troubleshooting](#troubleshooting)

---

## Connection Protocols

HeliosDB Full serves several wire protocols from one server; all of them read and
write the same tables.

| Protocol | Default port | Enabled by default | Clients |
|----------|--------------|--------------------|---------|
| **PostgreSQL** | 5432 | Yes (`--no-postgres` disables) | psql, pgAdmin, DBeaver, psycopg, pgx, JDBC, any PostgreSQL driver |
| **HTTP gateway** | 8443 | Yes (`--no-http` disables) | curl, any HTTP client (`POST /api/v1/query`) |
| **MySQL** | 3306 | No (`--enable-mysql`) | mysql CLI, PyMySQL, MySQL Connector/J |
| **Oracle (TNS)** | 1521 | No (`--enable-oracle`) | Oracle thin clients (tested with python-oracledb thin mode) |
| **SQL Server (TDS)** | 1433 | No (`--enable-sqlserver`) | sqlcmd, TDS drivers |
| **MongoDB** | 27017 | No (`--enable-mongodb`) | mongosh, MongoDB drivers |
| **Cassandra (CQL)** | 9042 | No (`--enable-cassandra`) | cqlsh, CQL drivers |
| **Redis** | 6379 | No (`--enable-redis`) | redis-cli, Redis clients |

Each port has a flag and an environment variable: `--postgres-port`
(`HELIOSDB_POSTGRES_PORT`), `--http-port` (`HELIOSDB_HTTP_PORT`), `--mysql-port`
(`HELIOSDB_MYSQL_PORT`), `--oracle-port` (`HELIOSDB_ORACLE_PORT`), `--sqlserver-port`,
`--mongodb-port`, `--cassandra-port`, `--redis-port` (with matching `HELIOSDB_*_PORT`
variables). All listeners bind `--bind-addr` (default `127.0.0.1`); any other address
also needs `--allow-external`.

### Credentials per listener

| Listener | User | Password | Notes |
|----------|------|----------|-------|
| PostgreSQL | `postgres`, or a role from `CREATE ROLE ... LOGIN PASSWORD` | `HELIOSDB_SUPERUSER_PASSWORD`, or the role's password | SCRAM-SHA-256 |
| MySQL | a role from the role catalog (same roles as PostgreSQL) | see the warning below | `caching_sha2_password` or `mysql_native_password`; the user name is checked, the password is not yet verified |
| Oracle | any user name | `HELIOSDB_ORACLE_NATIVE_PASSWORD`; if it is unset, the password is the user name (for example `scott`/`scott`), so always set it | O5LOGON; one password for the listener |
| SQL Server | `HELIOSDB_SQLSERVER_USER` | `HELIOSDB_SQLSERVER_PASSWORD` | Logins denied until both are set |
| MongoDB | `HELIOSDB_MONGODB_USER` | `HELIOSDB_MONGODB_PASSWORD` | Logins denied until both are set |
| Cassandra | `HELIOSDB_CASSANDRA_USER` | `HELIOSDB_CASSANDRA_PASSWORD` | Logins denied until both are set |
| Redis | `AUTH <role> <password>` | not verified yet | the role name must exist in the role catalog; keep the listener on a trusted network |
| HTTP | — | `HELIOSDB_API_KEY` (`Authorization: Bearer` or `X-API-Key`) | Health and status routes need no key |

:::caution[MySQL and Redis listeners: passwords are not verified yet]
In the current release the MySQL listener checks that the user name exists in the
role catalog and that the client sent a non-empty password, but it does not verify
the password itself: any non-empty password is accepted for an existing role
(including `postgres`). The Redis listener likewise accepts `AUTH` for any existing
role name without checking the password. Enable `--enable-mysql` and `--enable-redis` only on a loopback address or a
private network where every client is trusted, and use the PostgreSQL listener for
anything that needs real authentication. Empty MySQL passwords are rejected.
:::

If `HELIOSDB_SUPERUSER_PASSWORD` is not set, the server generates a password for
`postgres` and prints it once in its log. `--auth-mode trust` (no credentials) is
accepted only when the server is bound to a loopback address.

### TLS

:::caution[TLS: planned]
HeliosDB Full listeners do not terminate TLS; put a TLS-terminating proxy in
front. Native PostgreSQL TLS (with post-quantum key exchange preferred) is
planned; the `--tls-cert`, `--tls-key` and `--tls-require` flags in this section
describe that planned feature.
:::

The PostgreSQL listener supports TLS: `--tls-cert`, `--tls-key` and, to refuse
plaintext sessions, `--tls-require`. The other listeners and the HTTP gateway are
plaintext; keep them on a private network or put a TLS proxy in front.

### Example: enable PostgreSQL, MySQL and Oracle for a private network

```bash
export HELIOSDB_SUPERUSER_PASSWORD=...          # from your secrets store
export HELIOSDB_ORACLE_NATIVE_PASSWORD=...
heliosdb-full --data-dir /var/lib/heliosdb \
  --bind-addr 10.0.0.12 --allow-external \
  --tls-cert /etc/heliosdb/tls/server.crt --tls-key /etc/heliosdb/tls/server.key \
  --enable-mysql --enable-oracle
```

HeliosDB Full has no gRPC client API: application code connects over one of the
protocols above. Every flag is described in the
[Server Configuration Reference](/docs/full/reference/configuration/).

---

## Command-Line Clients

### 1. psql (PostgreSQL Client) (Recommended)

HeliosDB Full speaks the PostgreSQL wire protocol, so the standard `psql` client works
directly.

```bash
# Install (if not already installed)
sudo apt install postgresql-client     # Ubuntu/Debian
brew install libpq                     # macOS

# Connect as the built-in superuser
psql -h localhost -p 5432 -U postgres -d postgres

# Password from the environment (avoid it on the command line)
PGPASSWORD="$HELIOSDB_SUPERUSER_PASSWORD" psql -h localhost -U postgres

# Connection string with an application role
psql "postgresql://app@localhost:5432/postgres"

# With TLS (server started with --tls-cert/--tls-key)
psql "postgresql://app@db.internal:5432/postgres?sslmode=verify-full&sslrootcert=/path/to/ca.crt"
```

**Useful psql commands**:
```sql
\dt                 -- List tables
\d users            -- Describe table
\du                 -- List roles
\timing on          -- Show query execution time
\x on               -- Expanded display
\q                  -- Quit
```

HeliosDB-specific status statements such as `SHOW SERVER STATUS`, `SHOW PROTOCOLS`
and `SHOW CONNECTIONS` also work from `psql`.

### 2. mysql CLI

Start the server with `--enable-mysql`, then connect with a role from the role
catalog (for example `postgres`, or a role you created). The listener does not verify
MySQL passwords yet (see [Credentials per listener](#credentials-per-listener)), so keep
it on a trusted network:

```bash
# Install
sudo apt install mysql-client

# Connect
mysql -h localhost -P 3306 -u postgres -p postgres

# Connection parameters
mysql --host=localhost --port=3306 --user=app --password --database=postgres
```

```python
import os, pymysql

conn = pymysql.connect(host="localhost", port=3306, user="app",
                       password=os.environ["APP_PASSWORD"], database="postgres")
with conn.cursor() as cur:
    cur.execute("SELECT name FROM users WHERE id = %s", (1,))
    print(cur.fetchall())
conn.commit()
```

The MySQL listener runs SQL on the same engine as the PostgreSQL listener; MySQL-only
functions and syntax may need small changes.

### 3. Oracle clients

Start the server with `--enable-oracle` and set `HELIOSDB_ORACLE_NATIVE_PASSWORD`.
Clients log on with any user name and that password; the service name is not checked.

```python
import os, oracledb   # python-oracledb, thin mode

conn = oracledb.connect(user="app", password=os.environ["HELIOSDB_ORACLE_NATIVE_PASSWORD"],
                        dsn="localhost:1521/heliosdb")
conn.autocommit = True
cur = conn.cursor()
cur.execute("SELECT name FROM users WHERE id = :id", id=1)
print(cur.fetchall())
```

JDBC thin URL: `jdbc:oracle:thin:@//localhost:1521/heliosdb`.

Statements run on the same SQL engine as the PostgreSQL listener, without Oracle
dialect translation, and each statement commits as it runs. Driver
`commit()`/`rollback()` calls are not supported yet, so enable autocommit, and open a
new cursor for each statement. See the
[Oracle Quick Start](/docs/full/quick-starts/protocols/oracle_quick_start/) for what
runs over the Oracle listener today.

---

## Programming Languages

### Python

#### Install Client

HeliosDB Full speaks the PostgreSQL wire protocol, so use a standard PostgreSQL
driver such as [psycopg](https://www.psycopg.org/):

```bash
pip install "psycopg[binary]"

# Or the older psycopg2 driver
pip install psycopg2-binary
```

#### Synchronous Connection (psycopg 3)

```python
import psycopg

with psycopg.connect(
    host="localhost",
    port=5432,
    user="app",
    password="mysecretpassword",
    dbname="myapp",
) as conn:
    rows = conn.execute("SELECT * FROM users WHERE id = %s", (1,)).fetchall()
    for row in rows:
        print(row)
# Connection closed (and the transaction committed) on exit
```

#### Async Connection (psycopg 3)

```python
import asyncio
import psycopg

async def main():
    async with await psycopg.AsyncConnection.connect(
        "postgresql://app:mysecretpassword@localhost:5432/myapp"
    ) as conn:
        cur = await conn.execute("SELECT * FROM users LIMIT 10")
        async for row in cur:
            print(row)

asyncio.run(main())
```

#### Using psycopg2 (PostgreSQL Driver)

```python
import psycopg2

# Connect
conn = psycopg2.connect(
    host="localhost",
    port=5432,
    user="app",
    password="mysecretpassword",
    database="myapp"
)

# Create cursor
cur = conn.cursor()

# Execute query
cur.execute("SELECT * FROM users WHERE email = %s", ("alice@example.com",))

# Fetch results
rows = cur.fetchall()
for row in rows:
    print(row)

# Commit transaction
conn.commit()

# Close
cur.close()
conn.close()
```

### JavaScript/TypeScript

#### Install Client

HeliosDB Full speaks the PostgreSQL wire protocol, so use the standard
[node-postgres](https://node-postgres.com/) driver. (There is no HeliosDB
package on npm — the unrelated `heliosdb` npm package is not ours.)

```bash
npm install pg

# Or with TypeScript types
npm install pg @types/pg
```

#### Node.js Connection

```javascript
const { Client } = require('pg');

// Create client
const client = new Client({
  host: 'localhost',
  port: 5432,
  user: 'app',
  password: 'mysecretpassword',
  database: 'myapp'
});

// Connect
await client.connect();

// Execute query
const result = await client.query('SELECT * FROM users WHERE id = $1', [1]);

console.log(result.rows);

// Close
await client.end();
```

#### TypeScript with Type Safety

```typescript
import { Client, QueryResult } from 'pg';

interface User {
  id: number;
  username: string;
  email: string;
  created_at: Date;
}

const client = new Client({
  host: 'localhost',
  port: 5432,
  user: 'app',
  password: 'mysecretpassword',
  database: 'myapp'
});

await client.connect();

const result: QueryResult<User> = await client.query<User>(
  'SELECT * FROM users WHERE id = $1',
  [1]
);

result.rows.forEach((user: User) => {
  console.log(`${user.username}: ${user.email}`);
});

await client.end();
```

#### Connection Pooling with node-postgres

```javascript
const { Pool } = require('pg');

const pool = new Pool({
  host: 'localhost',
  port: 5432,
  user: 'app',
  password: 'mysecretpassword',
  database: 'myapp',
  max: 20, // Connection pool size
  idleTimeoutMillis: 30000
});

// Execute query
const result = await pool.query('SELECT * FROM users WHERE email = $1', ['alice@example.com']);

console.log(result.rows);
```

### Java

#### Add Maven Dependency

Use the standard PostgreSQL JDBC driver (HeliosDB Full speaks the PostgreSQL wire protocol):

```xml
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>42.6.0</version>
</dependency>
```

#### JDBC Connection

```java
import java.sql.*;

public class HeliosDBExample {
    public static void main(String[] args) {
        String url = "jdbc:postgresql://localhost:5432/myapp";
        String user = "app";
        String password = "mysecretpassword";

        try (Connection conn = DriverManager.getConnection(url, user, password)) {
            System.out.println("Connected to HeliosDB!");

            // Execute query
            String sql = "SELECT * FROM users WHERE id = ?";
            PreparedStatement pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, 1);

            ResultSet rs = pstmt.executeQuery();

            while (rs.next()) {
                System.out.println("User: " + rs.getString("username"));
                System.out.println("Email: " + rs.getString("email"));
            }

            rs.close();
            pstmt.close();

        } catch (SQLException e) {
            System.err.println("Connection failed: " + e.getMessage());
        }
    }
}
```

#### Spring Boot Configuration

```yaml
# application.yml
spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/myapp
    username: app
    password: mysecretpassword
    driver-class-name: org.postgresql.Driver
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 30000
```

### Go

HeliosDB Full speaks the PostgreSQL wire protocol, so any standard Go PostgreSQL driver works. The example below uses [pgx](https://github.com/jackc/pgx). (The Go REST client in [HeliosDB-SDKs/sdks/go](https://github.com/HeliosDatabase/HeliosDB-SDKs/tree/main/sdks/go) is for HeliosDB Nano and Lite. It calls `/v1/...` endpoints that Full does not serve, so it does not work with Full.)

#### Install Module

```bash
go get github.com/jackc/pgx/v5
```

#### Connection Example

```go
package main

import (
    "context"
    "fmt"
    "log"

    "github.com/jackc/pgx/v5"
)

func main() {
    ctx := context.Background()
    conn, err := pgx.Connect(ctx, "postgres://app:mysecretpassword@localhost:5432/myapp")
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close(ctx)

    rows, err := conn.Query(ctx, "SELECT id, username, email FROM users WHERE id = $1", 1)
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()

    for rows.Next() {
        var id int
        var username, email string
        if err := rows.Scan(&id, &username, &email); err != nil {
            log.Fatal(err)
        }
        fmt.Printf("User: %s (%s)\n", username, email)
    }
}
```

### Rust

Use a standard PostgreSQL driver such as `tokio-postgres` over the PostgreSQL listener.

#### Add Dependency

```toml
[dependencies]
tokio-postgres = "0.7"
tokio = { version = "1", features = ["full"] }
```

#### Connection Example

```rust
use tokio_postgres::{Error, NoTls};

#[tokio::main]
async fn main() -> Result<(), Error> {
    // Connect over the PostgreSQL listener
    let (client, connection) = tokio_postgres::connect(
        "host=localhost port=5432 user=app password=mysecretpassword dbname=myapp",
        NoTls,
    )
    .await?;
    tokio::spawn(async move {
        if let Err(e) = connection.await {
            eprintln!("connection error: {e}");
        }
    });

    // Execute query
    let rows = client
        .query("SELECT username, email FROM users WHERE id = $1", &[&1i32])
        .await?;

    // Process results
    for row in rows {
        let username: String = row.get("username");
        let email: String = row.get("email");
        println!("User: {} ({})", username, email);
    }

    Ok(())
}
```

---

## GUI Tools

### 1. pgAdmin (PostgreSQL Admin Tool)

**Works with HeliosDB via PostgreSQL protocol**

1. Download from https://www.pgadmin.org/
2. Add new server:
   - Host: localhost
   - Port: 5432
   - Username: postgres (or your application role)
   - Password: (your password)

### 2. DBeaver (Universal Database Tool)

**Cross-platform, supports multiple databases**

1. Download from https://dbeaver.io/
2. Create new connection → PostgreSQL
3. Enter connection details

### 3. DataGrip (JetBrains IDE)

**Professional database IDE**

1. File → New → Data Source → PostgreSQL
2. Configure connection
3. Test connection

---

## Connection Pooling

### Why Use Connection Pooling?

- **Reduce connection overhead**: Reuse existing connections
- **Better concurrency**: Handle more simultaneous requests
- **Resource management**: Limit total connections

### Python Connection Pooling

```python
# pip install "psycopg[binary,pool]"
from psycopg_pool import ConnectionPool

# Create pool
pool = ConnectionPool(
    "host=localhost dbname=myapp user=app password=password",
    min_size=10,      # Minimum connections
    max_size=100,     # Maximum connections
    timeout=30.0      # Seconds to wait for a free connection
)

# Borrow a connection from the pool
with pool.connection() as conn:
    rows = conn.execute("SELECT * FROM users").fetchall()
    print(rows)

# Connection automatically returned to pool
```

### Node.js Connection Pooling

```javascript
const { Pool } = require('pg');

const pool = new Pool({
  host: 'localhost',
  port: 5432,
  user: 'app',
  password: 'mysecretpassword',
  database: 'myapp',
  max: 20,                    // Max connections
  min: 5,                     // Min connections
  idleTimeoutMillis: 30000,   // Close idle connections after 30s
  connectionTimeoutMillis: 2000
});

// Use pool
pool.query('SELECT * FROM users', (err, res) => {
  if (err) throw err;
  console.log(res.rows);
});
```

### Java Connection Pooling (HikariCP)

```java
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

public class DatabasePool {
    private static HikariDataSource dataSource;

    static {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:postgresql://localhost:5432/myapp");
        config.setUsername("app");
        config.setPassword("mysecretpassword");
        config.setMaximumPoolSize(20);
        config.setMinimumIdle(5);
        config.setConnectionTimeout(30000);

        dataSource = new HikariDataSource(config);
    }

    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
}
```

---

## Security & Authentication

### Password authentication

PostgreSQL and MySQL logins use roles:

```sql
-- as postgres
CREATE ROLE app LOGIN PASSWORD 'a-long-random-password' CONNECTION LIMIT 50;
ALTER ROLE app PASSWORD 'rotated-password';
ALTER ROLE app NOLOGIN;
```

Clients can read the password from the environment instead of the command line:

```bash
export PGPASSWORD="$APP_PASSWORD"
psql -h db.internal -U app -d postgres
```

In the current release every role that can log in can read and write all data
(`GRANT`/`REVOKE` return SQLSTATE `0A000`); use separate server instances for data that
must be isolated.

### SSL/TLS encryption

Start the server with `--tls-cert` and `--tls-key` (and `--tls-require` to refuse
plaintext), then:

```bash
psql "postgresql://app@db.internal/postgres?sslmode=require"
psql "postgresql://app@db.internal/postgres?sslmode=verify-full&sslrootcert=/path/to/ca.crt"
```

```python
import psycopg
conn = psycopg.connect(host="db.internal", user="app", password=password, dbname="postgres",
                       sslmode="verify-full", sslrootcert="/path/to/ca.crt")
```

`SHOW CERTIFICATES` reports whether TLS is configured and whether the current session
is encrypted. Client-certificate (mTLS), LDAP and OAuth logins are not offered by the
server; put a proxy that provides them in front if you need them.

---

## Troubleshooting

### Connection refused

```bash
# 1. Is the server running, and which listeners did it open?
journalctl -u heliosdb | grep "listening on"     # or: docker logs heliosdb
# 2. Is the port listening on the address you connect to?
ss -ltnp | grep -E ":(5432|3306|1521|8443) "
# 3. Firewall / published container ports
docker port heliosdb
```

Listeners other than PostgreSQL and HTTP need `--enable-<protocol>`. Remote clients
need `--bind-addr <address> --allow-external`.

### Authentication failed

1. PostgreSQL/MySQL: user `postgres` with `HELIOSDB_SUPERUSER_PASSWORD`, or a role with
   `LOGIN` and a password. `VALID UNTIL` in the past and a reached `CONNECTION LIMIT`
   refuse logins; check with `SHOW ROLES`.
2. Oracle: the password is `HELIOSDB_ORACLE_NATIVE_PASSWORD`.
3. SQL Server, MongoDB, Cassandra: both `HELIOSDB_<PROTOCOL>_USER` and `_PASSWORD` must
   be set on the server.
4. With `--tls-require`, PostgreSQL clients must use `sslmode=require` or stricter.

### Timeout errors

The server closes connections that do not finish the handshake within
`--startup-timeout-secs` (default 30). For long statements, raise `statement_timeout`
for the session; on the client side set a connect timeout, for example
`connect_timeout=10` in the connection string.

### SSL certificate errors

```bash
# Verify against your CA (recommended)
psql "postgresql://app@db.internal/postgres?sslmode=verify-full&sslrootcert=/path/to/ca.crt"
# Encrypt without verification (testing only)
psql "postgresql://app@db.internal/postgres?sslmode=require"
```

The certificate's subject alternative name must match the host name clients use.

---

## Connection String Format

### PostgreSQL DSN Format

```
postgresql://[user[:password]@][host][:port][/dbname][?param1=value1&...]
```

**Examples**:
```bash
# Basic
postgresql://app@localhost/postgres

# With password
postgresql://app:password@localhost:5432/postgres

# With SSL
postgresql://app@localhost/postgres?sslmode=require

# With multiple parameters
postgresql://app@localhost/postgres?sslmode=require&connect_timeout=30&application_name=myapp
```

---


**Next**: [Querying Data](https://www.heliosdb.com/docs/full/guides/user/querying/) →
