DEV Community

Alex Spinov
Alex Spinov

Posted on

Nile Has a Free API: A Serverless PostgreSQL Built for Multi-Tenant SaaS

Nile is a serverless PostgreSQL database designed for multi-tenant SaaS applications. It provides tenant isolation, per-tenant databases, and built-in user management — all on top of standard PostgreSQL.

Why Nile Matters

Building multi-tenant SaaS on PostgreSQL requires: tenant isolation, row-level security, per-tenant metrics, and user management. Nile provides all of this as a database feature.

What you get for free:

  • Standard PostgreSQL with tenant-aware features
  • Virtual tenant databases (isolation without separate instances)
  • Built-in user authentication and management
  • Per-tenant resource controls
  • Serverless scaling (pay per use)
  • Compatible with any PostgreSQL client

Quick Start

# Sign up at console.thenile.dev
# Get your connection string

# Connect with any PostgreSQL client
psql postgresql://user:pass@db.thenile.dev/mydb
Enter fullscreen mode Exit fullscreen mode

Tenant-Aware Tables

-- Create tenant-aware table
CREATE TABLE todos (
    id UUID DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL,
    title TEXT NOT NULL,
    completed BOOLEAN DEFAULT false,
    created_at TIMESTAMPTZ DEFAULT now(),
    CONSTRAINT pk_todos PRIMARY KEY (tenant_id, id),
    CONSTRAINT fk_tenant FOREIGN KEY (tenant_id) REFERENCES tenants(id)
);

-- Set tenant context — all queries are automatically scoped
SET nile.tenant_id = 'tenant-uuid-123';

-- This only returns data for tenant-uuid-123
SELECT * FROM todos;

-- Insert is automatically scoped
INSERT INTO todos (title) VALUES ('Buy groceries');
Enter fullscreen mode Exit fullscreen mode

Node.js Integration

import { Nile } from "@niledatabase/server";

const nile = new Nile({
  databaseId: process.env.NILE_DB_ID,
  user: process.env.NILE_USER,
  password: process.env.NILE_PASSWORD,
});

// Set tenant context
nile.tenantId = request.params.tenantId;

// Queries are automatically scoped to tenant
const todos = await nile.db.query("SELECT * FROM todos");

// Create tenant
const tenant = await nile.api.tenants.create({
  name: "Acme Corp",
});

// Create user for tenant
const user = await nile.api.users.create({
  email: "admin@acme.com",
  password: "secure-password",
  tenantId: tenant.id,
});
Enter fullscreen mode Exit fullscreen mode

Built-in Auth

// User signup
const result = await nile.api.auth.signUp({
  email: "user@example.com",
  password: "password123",
});

// Login
const token = await nile.api.auth.login({
  email: "user@example.com",
  password: "password123",
});

// Protected route
app.get("/api/todos", async (req, res) => {
  const user = await nile.api.auth.verifyToken(req.headers.authorization);
  nile.tenantId = user.tenantId;
  const todos = await nile.db.query("SELECT * FROM todos");
  res.json(todos.rows);
});
Enter fullscreen mode Exit fullscreen mode

Links


Building multi-tenant SaaS? Check out my developer tools on Apify or email spinov001@gmail.com for custom solutions.

Top comments (0)