Set up your database

Create a PostgreSQL database to store logs.

Database config

Note some steps are optional best practices (e.g. creating a scoped velvet db user).


Create your database and Velvet user

*️⃣

Admin user

Run these commands as your admin user

Create the new velvet database

CREATE DATABASE velvet;

Create the velvet_user role and permissions to only allow the user to manage the velvet db

-- Create the role
CREATE ROLE velvet_user WITH LOGIN PASSWORD 'your_secure_password';

-- Grant privileges on the database
GRANT ALL PRIVILEGES ON DATABASE velvet TO velvet_user;

-- Grant usage and create privileges on the schema
GRANT USAGE, CREATE ON SCHEMA public TO velvet_user;

-- Grant privileges on existing objects
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO velvet_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO velvet_user;
GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public TO velvet_user;
GRANT TRIGGER ON ALL TABLES IN SCHEMA public TO velvet_user;

-- Grant privileges on future objects
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO velvet_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO velvet_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON FUNCTIONS TO velvet_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT TRIGGER ON TABLES TO velvet_user;

Create the table, function, and trigger

*️⃣

Velvet user

Run these commands as the velvet_user

Create the table, function, and trigger with the velvet_user so they implicitly have access to the database objects.

Create the llm_logs table.

create table if not exists llm_logs (
  id text primary key not null,
  serial_id serial not null,
  request jsonb,
  response jsonb,
  metadata jsonb,
  created_at timestamp with time zone default now(),
  updated_at timestamp with time zone
);

Create function update_timestamps. This provides a handy, uniform way of setting the updated_at column.

create or replace function update_timestamps()
returns trigger
as $$
begin
  new.updated_at = now();
  return new;
end;
$$
language plpgsql
security definer;

Create trigger for update_timestamps. This sets a trigger to run update_timestamps() on llm_logs table.

drop trigger if exists llm_logs_update_timestamps on llm_logs;

create trigger llm_logs_update_timestamps
before update on llm_logs
for each row
execute procedure update_timestamps();

Get your database connection string URI

*️⃣

Connection string URI

While in Beta, the Velvet team can help you configure your database connection string. Email [email protected] if you want help.

DATABASE_URI=postgresql://velvet_user:your_password@yourdbhost:5432/postgres

Configuration complete ✅

If you've followed all the steps below, you should be good to go.

Configuration checklist:

  • App code is configured
  • Database migrations have been run
  • Database connection string added to Vercel and redeployed

OpenAI requests will be logged to your database. Email [email protected] with any questions.


What’s Next

Use our AI SQL editor to query your logs (optional)