# Connect a service to a database

A service connects to a database with a **connection variable**: a [variable](/docs/configuration/variables) you declare on the consuming service whose value is one of the database's published connection details. You name the variable, point it at the database, and your code reads it as an ordinary environment variable.

Outside the [quickstart](/docs/get-started/quickstart) wizard — whose database toggles declare this variable for you — nothing happens automatically. Creating a database next to a web service wires nothing: there is no attach step, and no variable appears on its own. Each consumer declares its own connection variable; that declaration is the entire model.

The variable references the database **by name** in the same environment. Delete a database and recreate one with the same name, and the wiring reconnects on its own.

## Your first connection

This walkthrough assumes a web service and a [Postgres database](/docs/databases/postgres) named `db` in the same environment.

1. 
2. 
3. 
4. 
5. 
6. 
7.

For a [Redis database](/docs/databases/redis) the flow is identical — name the variable `REDIS_URL` and pick the Redis entry.

## Read it in your code

Your service reads the variable from its environment like any other. With node-postgres:

```js
import pg from "pg";

const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });
const { rows } = await pool.query("SELECT now()");
```

With node-redis:

```js
import { createClient } from "redis";

const redis = createClient({ url: process.env.REDIS_URL });
await redis.connect();
```

Every language works the same way: read `DATABASE_URL` or `REDIS_URL` from the environment and hand it to your client library.

## Wire individual keys

The full URL is one of several published keys. A consumer can wire any single key as its own variable — useful for clients that take host and password separately, for example a `PGHOST` variable pointing at the `HOST` key.

Postgres publishes:

Redis publishes:

A connection variable's sensitivity is derived from its key — the URL and `PASSWORD` keys are sensitive automatically, and you cannot set it yourself. Sensitive values are withheld from ordinary reads and revealed only through an audited action.

## Share one database between services

Every consumer that needs the database declares its own connection variable: three services, three declarations, one database.

To declare it once, define the connection variable at **environment scope** instead. Every service in the environment then resolves it, and a service-scoped variable of the same name still wins — resolution is nearest-wins across the project → environment → service chain.

One service can hold `DATABASE_URL` and `REDIS_URL` side by side — one variable per database it uses.

## Use it from the API and CLI

A connection variable is one JSON body on the [Variables API](/api/variables):

```json
{ "name": "DATABASE_URL", "connection": { "service": "db" } }
```

`connection.key` is optional and defaults to the engine's URL key (`DATABASE_URL` / `REDIS_URL`); set it to wire an individual key instead.

A service create can carry its variables atomically: pass `variables[]` on the create body and the service never boots without them — see the [Services API](/api/services).

In scripts, create the database before its consumers. A connection variable resolves by name, so a consumer created first runs without the variable until the database exists.

The [CLI](/docs/developers/cli) sets literal variables only — declare connection variables in the console or through the API.

## One database per environment

A connection variable can only point at a database in the same environment — there is no cross-environment wiring. Each environment runs its own databases, and the name-keyed wiring is what keeps environments portable; see [Use databases across environments](/docs/databases/databases-across-environments).

## Troubleshoot a connection

- 
- 
- 
- 
- 
-
