DEV Community

Alex Spinov
Alex Spinov

Posted on

Neon Has a Free API That Gives You Serverless PostgreSQL With Branching

Neon is serverless PostgreSQL that separates storage from compute. The killer feature? Database branching — like git branches, but for your database.

What Is Neon?

Neon is a fully managed serverless PostgreSQL with autoscaling, branching, and a generous free tier. Your database scales to zero when idle and wakes up instantly on query.

The Neon API

Authentication

export NEON_API_KEY="your-api-key"

# List projects
curl -s 'https://console.neon.tech/api/v2/projects' \
  -H "Authorization: Bearer $NEON_API_KEY" | jq '.projects[].name'
Enter fullscreen mode Exit fullscreen mode

Create a Project

curl -s -X POST 'https://console.neon.tech/api/v2/projects' \
  -H "Authorization: Bearer $NEON_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"project": {"name": "my-saas", "region_id": "aws-eu-central-1"}}'
Enter fullscreen mode Exit fullscreen mode

Database Branching

This is where Neon shines. Create instant copy-on-write branches:

# Create a branch (instant, zero-cost copy)
curl -s -X POST 'https://console.neon.tech/api/v2/projects/PROJECT_ID/branches' \
  -H "Authorization: Bearer $NEON_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"branch": {"name": "feature-auth", "parent_id": "main-branch-id"}}'

# Each branch gets its own connection string
# Perfect for: preview deployments, testing migrations, staging
Enter fullscreen mode Exit fullscreen mode

Real Use Case: PR Preview Databases

import requests
import os

NEON_API = "https://console.neon.tech/api/v2"
API_KEY = os.environ["NEON_API_KEY"]
PROJECT_ID = "your-project-id"

def create_preview_db(pr_number: int):
    resp = requests.post(
        f"{NEON_API}/projects/{PROJECT_ID}/branches",
        headers={"Authorization": f"Bearer {API_KEY}"},
        json={"branch": {"name": f"pr-{pr_number}"}}
    )
    branch = resp.json()["branch"]

    # Get connection string
    endpoints = requests.get(
        f"{NEON_API}/projects/{PROJECT_ID}/branches/{branch['id']}/endpoints",
        headers={"Authorization": f"Bearer {API_KEY}"}
    ).json()

    return endpoints["endpoints"][0]["host"]

def delete_preview_db(pr_number: int):
    # List branches and find by name
    branches = requests.get(
        f"{NEON_API}/projects/{PROJECT_ID}/branches",
        headers={"Authorization": f"Bearer {API_KEY}"}
    ).json()

    for branch in branches["branches"]:
        if branch["name"] == f"pr-{pr_number}":
            requests.delete(
                f"{NEON_API}/projects/{PROJECT_ID}/branches/{branch['id']}",
                headers={"Authorization": f"Bearer {API_KEY}"}
            )
            break

# GitHub Actions: on PR open
host = create_preview_db(42)
print(f"Preview DB: postgresql://user:pass@{host}/mydb")
Enter fullscreen mode Exit fullscreen mode

Neon Free Tier

Feature Free Launch ($19/mo)
Storage 0.5 GB 10 GB
Compute 0.25 CU 1 CU
Branches 10 Unlimited
Projects 1 10
Autoscaling Yes Yes
API access Full Full

Connect from Anywhere

import { neon } from '@neondatabase/serverless'

const sql = neon(process.env.DATABASE_URL!)

const posts = await sql`
  SELECT id, title, created_at
  FROM posts
  WHERE published = true
  ORDER BY created_at DESC
  LIMIT 10
`
Enter fullscreen mode Exit fullscreen mode

Works in Vercel Edge, Cloudflare Workers, Deno Deploy — anywhere with fetch.


Need to populate your Neon database with web data? Scrapfly scrapes any site at scale. Email spinov001@gmail.com for scraping-to-database pipelines.

Top comments (0)