1---
2layout: "language"
3page_title: "Backend Type: pg"
4sidebar_current: "docs-backends-types-standard-pg"
5description: |-
6  Terraform can store state remotely in a Postgres database with locking.
7---
8
9# pg
10
11**Kind: Standard (with locking)**
12
13Stores the state in a [Postgres database](https://www.postgresql.org) version 10 or newer.
14
15This backend supports [state locking](/docs/language/state/locking.html).
16
17## Example Configuration
18
19```hcl
20terraform {
21  backend "pg" {
22    conn_str = "postgres://user:pass@db.example.com/terraform_backend"
23  }
24}
25```
26
27Before initializing the backend with `terraform init`, the database must already exist:
28
29```
30createdb terraform_backend
31```
32
33This `createdb` command is found in [Postgres client applications](https://www.postgresql.org/docs/10/reference-client.html) which are installed along with the database server.
34
35We recommend using a
36[partial configuration](/docs/language/settings/backends/configuration.html#partial-configuration)
37for the `conn_str` variable, because it typically contains access credentials that should not be committed to source control:
38
39```hcl
40terraform {
41  backend "pg" {}
42}
43```
44
45Then, set the credentials when initializing the configuration:
46
47```
48terraform init -backend-config="conn_str=postgres://user:pass@db.example.com/terraform_backend"
49```
50
51To use a Postgres server running on the same machine as Terraform, configure localhost with SSL disabled:
52
53```
54terraform init -backend-config="conn_str=postgres://localhost/terraform_backend?sslmode=disable"
55```
56
57## Data Source Configuration
58
59To make use of the pg remote state in another configuration, use the [`terraform_remote_state` data source](/docs/language/state/remote-state-data.html).
60
61```hcl
62data "terraform_remote_state" "network" {
63  backend = "pg"
64  config {
65    conn_str = "postgres://localhost/terraform_backend"
66  }
67}
68```
69
70## Configuration Variables
71
72The following configuration options or environment variables are supported:
73
74 * `conn_str` - (Required) Postgres connection string; a `postgres://` URL
75 * `schema_name` - Name of the automatically-managed Postgres schema, default `terraform_remote_state`.
76 * `skip_schema_creation` - If set to `true`, the Postgres schema must already exist. Terraform won't try to create the schema, this is useful when it has already been created by a database administrator.
77 * `skip_table_creation` - If set to `true`, the Postgres table must already exist. Terraform won't try to create the table, this is useful when it has already been created by a database administrator.
78 * `skip_index_creation` - If set to `true`, the Postgres index must already exist. Terraform won't try to create the index, this is useful when it has already been created by a database administrator.
79
80## Technical Design
81
82This backend creates one table **states** in the automatically-managed Postgres schema configured by the `schema_name` variable.
83
84The table is keyed by the [workspace](/docs/language/state/workspaces.html) name. If workspaces are not in use, the name `default` is used.
85
86Locking is supported using [Postgres advisory locks](https://www.postgresql.org/docs/9.5/explicit-locking.html#ADVISORY-LOCKS). [`force-unlock`](https://www.terraform.io/docs/cli/commands/force-unlock.html) is not supported, because these database-native locks will automatically unlock when the session is aborted or the connection fails. To see outstanding locks in a Postgres server, use the [`pg_locks` system view](https://www.postgresql.org/docs/9.5/view-pg-locks.html).
87
88The **states** table contains:
89
90 * a serial integer `id`, used as the key for advisory locks
91 * the workspace `name` key as *text* with a unique index
92 * the Terraform state `data` as *text*
93