Neon
Store analytics in Neon's serverless Postgres. Auto-scaling, branching, and instant provisioning for your analytics data.
Nextlytics is a server-side analytics library for Next.js. No client JavaScript, no cookies, GDPR compliant. Learn more →
Configuration
import { Nextlytics } from "@nextlytics/core/server";
import { neonBackend } from "@nextlytics/core/backends/neon";
export const { middleware, analytics } = Nextlytics({
backends: [
neonBackend({
// Required. Your Neon database URL.
// Find it: Neon Console -> Connection Details
databaseUrl: process.env.DATABASE_URL!,
// Optional. Table name (default: "analytics")
tableName: "analytics",
}),
],
});How It Works
The Neon backend uses @neondatabase/serverless to insert events directly into your Neon Postgres
database. It's optimized for serverless environments with connection pooling.
Table Schema
On first use, if the table doesn't exist, Nextlytics will print the required CREATE TABLE statement. Run it in your Neon SQL editor:
CREATE TABLE IF NOT EXISTS analytics (
timestamp TIMESTAMPTZ NOT NULL,
type TEXT NOT NULL,
host TEXT,
path TEXT,
method TEXT,
user_id TEXT,
anonymous_user_id TEXT,
user_email TEXT,
user_name TEXT,
ip INET,
referer TEXT,
user_agent TEXT,
locale TEXT,
event_id TEXT PRIMARY KEY,
parent_event_id TEXT,
server_context JSONB,
client_context JSONB,
user_traits JSONB,
properties JSONB
);
CREATE INDEX idx_analytics_timestamp ON analytics(timestamp DESC);
CREATE INDEX idx_analytics_type ON analytics(type);
CREATE INDEX idx_analytics_user_id ON analytics(user_id);If you're using Prisma, add this model to your schema.prisma instead:
model Analytics {
timestamp DateTime @db.Timestamptz()
type String
host String
path String
method String
user_id String?
anonymous_user_id String?
user_email String?
user_name String?
ip String? @db.Inet
referer String?
user_agent String?
locale String?
event_id String @id
parent_event_id String?
server_context Json? @db.JsonB
client_context Json? @db.JsonB
user_traits Json? @db.JsonB
properties Json? @db.JsonB
@@index([timestamp(sort: Desc)])
@@index([type])
@@index([user_id])
@@map("analytics")
}Then run npx prisma db push or add a migration with npx prisma migrate dev.
Event Updates
Neon backend supports event updates. When client context becomes available (after the initial server-side event), Nextlytics can update the event with additional data:
// Initial event (server-side)
{ event_id: "abc", path: "/products", client_context: null }
// After client context update
{ event_id: "abc", path: "/products", client_context: { userAgent: "...", ... } }Querying Your Data
-- Page views by path
SELECT path, COUNT(*) as views
FROM analytics
WHERE type = 'pageView'
GROUP BY path
ORDER BY views DESC;
-- Events with properties
SELECT
type,
properties->>'product' as product,
properties->>'value' as value
FROM analytics
WHERE type = 'purchase';
-- User journey
SELECT type, path, timestamp
FROM analytics
WHERE user_id = 'user_123'
ORDER BY timestamp;Branching
Neon's branching feature works great for analytics:
- Create a branch to test schema changes
- Branch production data for local development
- Instant point-in-time recovery
# Create a branch from production
neon branch create --name analytics-dev --parent mainConnection Pooling
For high-traffic sites, use Neon's connection pooling:
neonBackend({
// Use the pooled connection string
databaseUrl: process.env.DATABASE_URL_POOLED!,
});Limitations
- Requires @neondatabase/serverless: Install with
npm install @neondatabase/serverless - Postgres only: This backend is specific to Neon's serverless Postgres
- Cold starts: First request may have slightly higher latency due to connection setup
Ready to add server-side analytics?
Get started with Nextlytics in 3 simple steps.