> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.hyjal.cloud/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.hyjal.cloud/_mcp/server.

# Connect Postgres

> Connect a Neon Postgres database to a Hyjal Resource with a connection secret and an egress allowlist, then run your first query.

This tutorial connects the `api` Resource to a [Neon](https://neon.tech)
Postgres database over Neon's HTTPS serverless driver. You store the connection
string as a secret, allowlist the database hostname for egress, and run a query
from your code.

Time: about ten minutes. You need the [`hyjal` CLI](/reference/cli), a
logged-in session, and a Neon project with a connection string.

## Why the HTTP driver

Instances have no ambient network access and hold no TCP connections. Neon's
serverless driver speaks HTTPS, so it works from any lane once the hostname is
on the Resource's egress allowlist. This is the recommended default for
databases on Hyjal. For classic TCP databases, use the
[Database Door](/data/database-door) instead, covered at the end of this page.

## 1. Get the connection string

In the Neon console, copy the pooled connection string. It looks like:

```
postgresql://acme_owner:npg_xxx@ep-cool-block-123.us-east-2.aws.neon.tech/acme?sslmode=require
```

Note the hostname: `ep-cool-block-123.us-east-2.aws.neon.tech`. You allowlist
that exact host in step 3.

## 2. Store the connection string as a secret

Set the connection string as a Project secret. Secrets are injected into the
instance environment per request and never live in `hyjal.toml` or in git.

```bash
$ hyjal secrets set DATABASE_URL "postgresql://acme_owner:npg_xxx@ep-cool-block-123.us-east-2.aws.neon.tech/acme?sslmode=require"
Set secret DATABASE_URL for project acme
```

Confirm it is stored (values are never printed back):

```bash
$ hyjal secrets list
DATABASE_URL   set 2026-07-13
```

## 3. Allowlist the database host and reference the secret

In [`hyjal.toml`](/deploy/hyjal-toml), add the Neon hostname to the `api`
Resource's egress allowlist and reference the secret with `@secret`.

```toml
[resource.api]
lane = "go"
public = false

[resource.api.env]
DATABASE_URL = "@secret"

[resource.api.egress]
hosts = ["ep-cool-block-123.us-east-2.aws.neon.tech"]
```

The `@secret` marker tells the platform to resolve `DATABASE_URL` from the
secret store at request time. Outbound HTTPS is permitted only to hosts on the
`egress` list; every other destination is refused with
[`HYJ-NET001`](/reference/errors).

## 4. Query from your code

Use Neon's serverless driver, reading `DATABASE_URL` from the environment.

```go
// api/main.go
package main

import (
	"encoding/json"
	"net/http"
	"os"

	"github.com/neondatabase/serverless-go" // HTTPS driver
)

func handler(w http.ResponseWriter, r *http.Request) {
	db := neon.Connect(os.Getenv("DATABASE_URL"))
	rows, _ := db.Query(r.Context(), "SELECT now() AS ts")

	var ts string
	rows.Scan(&ts)

	w.Header().Set("content-type", "application/json")
	json.NewEncoder(w).Encode(map[string]string{"time": ts})
}
```

## 5. Deploy and run the first query

```bash
$ hyjal deploy
Building resource api (lane: go)...
  tinygo build -target=wasip2 ✓
Uploading artifact... digest sha256:b83f10…4ce9
Applying policy... ✓
Flipping route... ✓

Deployed acme/api
```

Call the endpoint. The response carries a timestamp straight from Postgres:

```bash
$ curl https://api--acme.hyjal.cloud
{"time":"2026-07-13T16:58:04.221Z"}
```

If the query fails with an egress error, confirm the allowlisted hostname
exactly matches the host in your connection string.

## Using the Database Door instead

If your database only speaks the raw Postgres TCP protocol, route through the
[Database Door](/data/database-door). The platform holds pooled, TLS-verified
connections host-side; your code sends parameterized queries over HTTP and gets
JSON rows back. Credentials are stored as Project secrets, and instances never
hold a raw TCP connection: the pooling is the platform's job, which keeps
instance-per-request safe against connection storms.

## What you built

* A Neon Postgres connection string stored as a Project secret.
* An egress allowlist scoped to the database hostname.
* A deployed `api` Resource that runs a live query per request.

## Next steps

* Store state without an external database: [Hyjal Tables tutorial](/get-started/tutorials/hyjal-tables-tutorial)
* Read the data model: [Data overview](/data/overview)
* Route TCP databases through the Door: [Database Door](/data/database-door)