# Databases (/docs/composer/databases)

> For the complete Prisma documentation index, see [llms.txt](https://www.prisma.io/docs/llms.txt). A markdown version of any docs page is available by appending `.md` to its URL.

Give a service a Postgres database, either as a plain connection or typed by a Prisma 8 contract with managed migrations.

Location: Composer > Databases

There are two ways for a service to get a [Prisma Postgres](https://www.prisma.io/docs/postgres) database, depending on how much you want the framework to do. Both are dependencies: the service declares the need, the module provisions the resource, and your code receives the result from `service.load()`.

> [!NOTE]
> Two kinds of contract
> 
> Composer's [service contracts](https://www.prisma.io/docs/composer/services-and-contracts) describe an RPC API between services. A Prisma 8 **data contract** describes a database schema. This page uses both: `postgres()` ties a database dependency to a Prisma 8 data contract.

## rawPostgres(): bring your own client [#rawpostgres-bring-your-own-client]

Declare `rawPostgres()` when you want to build the client yourself. The dependency delivers connection config, `{ url }`, and nothing else. In your server entry, build the client you already know (`pg`, Bun's `SQL`, an ORM):

```ts title="src/auth/service.ts"
import { compute, rawPostgres } from '@prisma/composer-prisma-cloud';

export default compute({
  name: 'auth',
  deps: { db: rawPostgres() },
  // ...
});
```

```ts title="src/auth/server.ts"
import { SQL } from 'bun';

const { db } = service.load();
const sql = new SQL({ url: db.url, max: 1, idleTimeout: 10 });
```

Those pool settings matter. Prisma Compute scales to zero and closes idle connections, so keep the pool small and reconnect-friendly. See [Deploying](https://www.prisma.io/docs/composer/deploying#production-behavior).

The module that owns the database provisions it:

```ts title="module.ts"
const db = provision(rawPostgres({ name: 'database' }));
provision(authService, { deps: { db } });
```

## postgres(): a Prisma 8-typed database [#postgres-a-prisma-8-typed-database]

If you want typed queries and managed migrations, make the database a [Prisma 8](https://www.prisma.io/docs/prisma-orm) one. `load()` then returns `{ url, client }`: the raw connection string, plus a client generated from your data contract. Queries like `db.client.orm.public.Product.where({ id }).first()` are compile-time checked, with no SQL strings and no row mapping. The client is constructed only on first access, so a service that brings its own Postgres client can still read `db.url` and keep contract-checked wiring and deploy-time migrations.

The schema workflow runs once per schema change, using the [Prisma 8 CLI commands](https://www.prisma.io/docs/cli):

1. Edit `contract.prisma`, your schema.
2. Run `contract emit` to regenerate `contract.json` and `contract.d.ts` from it.
3. Run `migration plan` to author the migration into `migrations/`.
4. Deploy. The deploy applies `migrations/` before the service starts. There is no `CREATE TABLE IF NOT EXISTS` anywhere in app code.

In your app, wrap the emitted contract once. Both the resource and every service that queries it reference that one value:

```ts title="src/data.ts"
import { dataContract } from '@prisma/composer-prisma-cloud/orm';
import type { Contract } from '../contract.d.ts';
import contractJson from '../contract.json' with { type: 'json' };

export const catalogData = dataContract<Contract>(contractJson);
```

You call `postgres()` on both sides of the wiring, and what you pass it tells the two apart. Passing the contract alone declares the dependency, the service saying what it queries:

```ts
deps: { db: postgres(catalogData) }
```

Passing an options object declares the resource. The module that owns the database provisions it, naming the `prisma.config.ts` path (relative to the module file) so the deploy can find `migrations/`:

```ts
const db = provision(
  postgres({ name: 'database', contract: catalogData, config: './prisma.config.ts' }),
);
```

Because both ends share the contract value, the deploy refuses to wire a service against a database whose schema does not match.

For complete working versions, see [`examples/orm-demo`](https://github.com/prisma/composer/tree/main/examples/orm-demo) (one service, one typed database) and [`examples/store`](https://github.com/prisma/composer/tree/main/examples/store) (the full pattern inside a reusable Module) in the Composer repository.

## Local databases [#local-databases]

`dev` provisions real local Postgres instances for both kinds, so you can migrate and query them exactly as you would in production, with no cloud credentials. The data persists across restarts until you pass `--fresh`. See [Local development](https://www.prisma.io/docs/composer/local-development).

## Next steps [#next-steps]

* [Object storage](https://www.prisma.io/docs/composer/object-storage): the other stateful resource, an S3-compatible bucket.
* [Apps and Modules](https://www.prisma.io/docs/composer/apps-and-modules): keep a database private inside a Module.
* [Prisma 8 CLI reference](https://www.prisma.io/docs/cli): the contract and migration commands in detail.

## Related pages

- [`Apps and Modules`](https://www.prisma.io/docs/composer/apps-and-modules): How services, resources, and Modules compose into a Prisma App, and how provision() wires them together.
- [`Building blocks`](https://www.prisma.io/docs/composer/building-blocks): Compose the ready-made cron, storage, and streams Modules instead of building scheduled jobs, blob storage, or event streams yourself.
- [`Core concepts`](https://www.prisma.io/docs/composer/core-concepts): The ideas every Composer declaration and command builds on: services, resources, Modules, ports, contracts, stages, and the deploy model.
- [`Deploying`](https://www.prisma.io/docs/composer/deploying): Deploy a Prisma App to production or an isolated stage, run it in CI, and tear environments down safely.
- [`Getting started`](https://www.prisma.io/docs/composer/getting-started): Build a two-service Prisma App from an empty directory and run it on your machine with one command.