# Connect to PostgreSQL

<Image
  src={postgresIcon}
  alt="PostgreSQL logo"
  width={100}
  height={100}
  class:list={'float-inline-left icon'}
  data-zoom-off
/>

This page describes how consuming apps connect to a PostgreSQL resource that's already modeled in your AppHost. For the AppHost API surface — adding a PostgreSQL server, databases, pgAdmin, pgWeb, volumes, and more — see [PostgreSQL Hosting integration](../postgres-host/).

When you reference a PostgreSQL resource from your AppHost, Aspire injects the connection information into the consuming app as environment variables. Your app can either read those environment variables directly — the pattern works the same from any language — or, in C#, use the Aspire PostgreSQL client integration for automatic dependency injection, health checks, and telemetry.

## Connection properties

Aspire exposes each property as an environment variable named `[RESOURCE]_[PROPERTY]`. For instance, the `Uri` property of a resource called `postgresdb` becomes `POSTGRESDB_URI`.

### PostgreSQL server

The PostgreSQL server resource exposes the following connection properties:

| Property Name          | Description |
| ---------------------- | ----------- |
| `Host`                 | The hostname or IP address of the PostgreSQL server |
| `Port`                 | The port number the PostgreSQL server is listening on |
| `Username`             | The username for authentication |
| `Password`             | The password for authentication |
| `Uri`                  | The connection URI in postgresql:// format, with the format `postgresql://{Username}:{Password}@{Host}:{Port}` |
| `JdbcConnectionString` | JDBC-format connection string, with the format `jdbc:postgresql://{Host}:{Port}`. User and password credentials are provided as separate `Username` and `Password` properties. |

**Example connection strings:**

```
Uri: postgresql://postgres:p%40ssw0rd1@localhost:5432
JdbcConnectionString: jdbc:postgresql://localhost:5432
```

### PostgreSQL database

The PostgreSQL database resource inherits all properties from its parent server resource and adds:

| Property Name          | Description |
| ---------------------- | ----------- |
| `Uri`                  | The connection URI with the database name, with the format `postgresql://{Username}:{Password}@{Host}:{Port}/{DatabaseName}` |
| `JdbcConnectionString` | JDBC connection string with database name, with the format `jdbc:postgresql://{Host}:{Port}/{DatabaseName}`. User and password credentials are provided as separate `Username` and `Password` properties. |
| `DatabaseName`         | The name of the database |

**Example connection strings:**

```
Uri: postgresql://postgres:p%40ssw0rd1@localhost:5432/catalog
JdbcConnectionString: jdbc:postgresql://localhost:5432/catalog
```

## Connect from your app

Pick the language your consuming app is written in. Each example assumes your AppHost adds a PostgreSQL database resource named `postgresdb` and references it from the consuming app.

For C# apps, the recommended approach is the Aspire PostgreSQL client integration. It registers an [`NpgsqlDataSource`](https://www.npgsql.org/doc/api/Npgsql.NpgsqlDataSource.html) through dependency injection and adds health checks and telemetry automatically. If you'd rather read environment variables directly, see the [Read environment variables](#read-environment-variables-in-c) section at the end of this tab.

#### Install the client integration

Install the [📦 Aspire.Npgsql](https://www.nuget.org/packages/Aspire.Npgsql) NuGet package in the client-consuming project:

<InstallDotNetPackage packageName="Aspire.Npgsql" />

#### Add the Npgsql data source

In _Program.cs_, call `AddNpgsqlDataSource` on your `IHostApplicationBuilder` to register an `NpgsqlDataSource`. The `connectionName` must match the PostgreSQL database resource name from the AppHost:

```csharp title="C# — Program.cs"
builder.AddNpgsqlDataSource(connectionName: "postgresdb");
```

Resolve the data source through dependency injection:

```csharp title="C# — ExampleService.cs"
public class ExampleService(NpgsqlDataSource dataSource)
{
    // Use dataSource...
}
```

#### Add keyed Npgsql clients

To register multiple `NpgsqlDataSource` instances with different connection names, use `AddKeyedNpgsqlDataSource`:

```csharp title="C# — Program.cs"
builder.AddKeyedNpgsqlDataSource(name: "chat");
builder.AddKeyedNpgsqlDataSource(name: "queue");
```

Then resolve each instance by key:

```csharp title="C# — ExampleService.cs"
public class ExampleService(
    [FromKeyedServices("chat")] NpgsqlDataSource chatDataSource,
    [FromKeyedServices("queue")] NpgsqlDataSource queueDataSource)
{
    // Use data sources...
}
```

#### Configuration

The Aspire PostgreSQL client integration offers multiple ways to provide configuration.

**Connection strings.** When using a connection string from the `ConnectionStrings` configuration section, pass the connection name to `AddNpgsqlDataSource`:

```csharp title="C# — Program.cs"
builder.AddNpgsqlDataSource("postgresdb");
```

The connection string is resolved from the `ConnectionStrings` section:

```json title="JSON — appsettings.json"
{
  "ConnectionStrings": {
    "postgresdb": "Host=myserver;Database=postgresdb"
  }
}
```

For more information, see [Npgsql connection string parameters](https://www.npgsql.org/doc/connection-string-parameters.html).

**Configuration providers.** The client integration supports `Microsoft.Extensions.Configuration`. It loads `NpgsqlSettings` from _appsettings.json_ (or any other configuration source) by using the `Aspire:Npgsql` key:

```json title="JSON — appsettings.json"
{
  "Aspire": {
    "Npgsql": {
      "ConnectionString": "Host=myserver;Database=postgresdb",
      "DisableHealthChecks": false,
      "DisableTracing": true,
      "DisableMetrics": false
    }
  }
}
```

For the complete PostgreSQL client integration JSON schema, see [Aspire.Npgsql/ConfigurationSchema.json](https://github.com/microsoft/aspire/blob/v9.1.0/src/Components/Aspire.Npgsql/ConfigurationSchema.json).

**Inline delegates.** Pass an `Action<NpgsqlSettings>` to configure settings inline, for example to disable health checks:

```csharp title="C# — Program.cs"
builder.AddNpgsqlDataSource(
    "postgresdb",
     static settings => settings.DisableHealthChecks = true);
```

#### Client integration health checks

Aspire client integrations enable health checks by default. The PostgreSQL client integration adds:

- The [`NpgSqlHealthCheck`](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/blob/master/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs), which verifies that commands can be successfully executed against the underlying PostgreSQL database.
- Integration with the `/health` HTTP endpoint, where all registered health checks must pass before the app is considered ready to accept traffic.

#### Observability and telemetry

The Aspire PostgreSQL client integration automatically configures logging, tracing, and metrics through OpenTelemetry.

**Logging** categories:

- `Npgsql.Connection`
- `Npgsql.Command`
- `Npgsql.Transaction`
- `Npgsql.Copy`
- `Npgsql.Replication`
- `Npgsql.Exception`

**Tracing** activities:

- `Npgsql`

**Metrics**:

- `ec_Npgsql_bytes_written_per_second`
- `ec_Npgsql_bytes_read_per_second`
- `ec_Npgsql_commands_per_second`
- `ec_Npgsql_total_commands`
- `ec_Npgsql_current_commands`
- `ec_Npgsql_failed_commands`
- `ec_Npgsql_prepared_commands_ratio`
- `ec_Npgsql_connection_pools`
- `ec_Npgsql_multiplexing_average_commands_per_batch`
- `ec_Npgsql_multiplexing_average_write_time_per_batch`

Any of these telemetry features can be disabled through the configuration options above.

#### Read environment variables in C\#

If you prefer to read environment variables directly without the client integration:

```csharp title="C# — Program.cs"
var connectionString = Environment.GetEnvironmentVariable(
    "POSTGRESDB_URI");

await using var dataSource = NpgsqlDataSource.Create(connectionString!);
await using var conn = await dataSource.OpenConnectionAsync();
```

Use the `pgx` driver, the most actively maintained PostgreSQL driver for Go:

```bash title="Terminal"
go get github.com/jackc/pgx/v5
```**Note:** [`lib/pq`](https://github.com/lib/pq) is another popular Go PostgreSQL driver, but `pgx` is recommended for new projects because it offers better performance, native PostgreSQL protocol support, and active maintenance.

Read the injected environment variable and connect:

```go title="Go — main.go"
package main

import (
    "context"
    "os"
    "github.com/jackc/pgx/v5"
)

func main() {
    // Read the Aspire-injected connection URI
    connStr := os.Getenv("POSTGRESDB_URI")

    conn, err := pgx.Connect(context.Background(), connStr)
    if err != nil {
        panic(err)
    }
    defer conn.Close(context.Background())
}
```

Install a PostgreSQL driver. This example uses `psycopg`:

```bash title="Terminal"
pip install psycopg[binary]
```

Read the injected environment variable and connect:

```python title="Python — app.py"
import os
import psycopg

# Read the Aspire-injected connection URI
postgres_uri = os.getenv("POSTGRESDB_URI")

async with await psycopg.AsyncConnection.connect(
    postgres_uri, autocommit=True
) as conn:
    # Use conn to query the database...
    pass
```

Install the PostgreSQL client library:

```bash title="Terminal"
npm install pg
```

Read the injected environment variables and connect:

```javascript title="JavaScript — index.js"
import pg from 'pg';

// Read Aspire-injected connection properties
const client = new pg.Client({
    user: process.env.POSTGRESDB_USERNAME,
    host: process.env.POSTGRESDB_HOST,
    database: process.env.POSTGRESDB_DATABASENAME,
    password: process.env.POSTGRESDB_PASSWORD,
    port: process.env.POSTGRESDB_PORT,
});

await client.connect();
```

Or use the connection URI directly:

```javascript title="JavaScript — Connect with URI"
const client = new pg.Client({
    connectionString: process.env.POSTGRESDB_URI,
});

await client.connect();
```**Tip:** If your app expects specific environment variable names different from the Aspire defaults, you can pass individual connection properties from the AppHost. See [Pass custom environment variables](../postgres-host/#pass-custom-environment-variables) in the Hosting integration reference.