ENGINEERING

Graph Memory Without Neo4j: How 0Latency Maps Relationships Using Postgres

March 30, 2026 · 10 min read

Knowledge graphs are powerful. An AI agent that understands "Sarah works at Acme Corp" and "Acme Corp is a client of BigCo" can infer that Sarah is connected to BigCo — without being told explicitly. This kind of relational reasoning transforms agents from simple Q&A bots into intelligent assistants that actually reason about relationships.

The conventional wisdom says you need a dedicated graph database — Neo4j, Amazon Neptune, or similar — to build knowledge graphs. That's a whole new piece of infrastructure to deploy, maintain, and pay for. For most AI agent developers, it's overkill.

0Latency takes a different approach. We built a full graph memory system on top of Postgres using recursive Common Table Expressions (CTEs). No Neo4j. No additional infrastructure. No extra cost. And it's available on Scale ($99/mo) and Enterprise.

Why Graph Memory Matters for AI Agents

Without graph memory, your agent treats every fact as isolated. It knows "Sarah likes hiking" and "Sarah works at Acme" as separate, unconnected memories. It cannot traverse relationships or answer questions like "Who are the employees of our client companies that enjoy outdoor activities?"

With graph memory, your agent builds a web of connected knowledge:

This relational understanding lets agents answer complex queries, provide richer context, and make connections that would otherwise require explicit programming. It's especially powerful in multi-agent systems where different agents contribute different pieces of the knowledge graph.

The Neo4j Problem

Neo4j is excellent software. For large-scale graph analytics — social network analysis, fraud detection, recommendation engines — it's the right tool. But for AI agent memory, it introduces significant complexity:

For an AI agent that needs to store thousands (not billions) of relationships efficiently, this is a sledgehammer for a nail.

Postgres Recursive CTEs: The Elegant Alternative

Postgres has had recursive CTEs since version 8.4 (2009). They let you write graph traversal queries in plain SQL. Here's the core insight: you don't need a graph database to query graph data. You need a graph query pattern on a relational store.

0Latency's entity relationship table is simple:

-- Simplified schema (actual implementation includes more metadata)
CREATE TABLE entity_relationships (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    source_entity TEXT NOT NULL,      -- "Sarah Chen"
    source_type TEXT NOT NULL,         -- "person"
    relationship TEXT NOT NULL,        -- "works_at"
    target_entity TEXT NOT NULL,       -- "Acme Corp"
    target_type TEXT NOT NULL,         -- "organization"
    confidence FLOAT DEFAULT 1.0,
    agent_id TEXT NOT NULL,
    created_at TIMESTAMPTZ DEFAULT now(),
    last_seen TIMESTAMPTZ DEFAULT now()
);

To traverse relationships — say, finding all entities within 3 hops of "Sarah Chen" — we use a recursive CTE:

-- Find all entities connected to Sarah within 3 hops
WITH RECURSIVE graph AS (
    -- Base case: direct relationships
    SELECT
        target_entity AS entity,
        target_type AS entity_type,
        relationship,
        1 AS depth,
        ARRAY[source_entity, target_entity] AS path
    FROM entity_relationships
    WHERE source_entity = 'Sarah Chen'
      AND agent_id = 'my-agent'

    UNION ALL

    -- Recursive case: follow connections
    SELECT
        r.target_entity,
        r.target_type,
        r.relationship,
        g.depth + 1,
        g.path || r.target_entity
    FROM entity_relationships r
    JOIN graph g ON r.source_entity = g.entity
    WHERE g.depth < 3
      AND NOT r.target_entity = ANY(g.path)  -- prevent cycles
      AND r.agent_id = 'my-agent'
)
SELECT DISTINCT entity, entity_type, relationship, depth
FROM graph
ORDER BY depth, entity;

This query executes in under 50ms for graphs with tens of thousands of relationships. For the scale most AI agents operate at, this is efficient enough to run synchronously — and it lives in the same database as your memories, eliminating cross-system synchronization.

Using the Graph API

You don't need to write SQL. 0Latency's API handles graph operations automatically through entity extraction and explicit relationship endpoints.

Automatic Entity Extraction

When you store a memory, 0Latency automatically extracts entities and relationships:

import requests

API_KEY = "your-api-key"
BASE = "https://api.0latency.ai"

# Store a memory — entities are extracted automatically
response = requests.post(f"{BASE}/memories/extract", headers={
    "X-API-Key": API_KEY,
    "Content-Type": "application/json"
}, json={
    "agent_id": "assistant",
    "content": "Sarah Chen joined Acme Corp as Head of Engineering last month. She previously worked at Google on the TensorFlow team."
})

# The response includes extracted entities and relationships
data = response.json()
print(data["entities_extracted"])
# [
#   {"entity": "Sarah Chen", "type": "person"},
#   {"entity": "Acme Corp", "type": "organization"},
#   {"entity": "Google", "type": "organization"},
#   {"entity": "TensorFlow", "type": "technology"}
# ]
print(data["relationships_created"])
# [
#   {"source": "Sarah Chen", "relation": "works_at", "target": "Acme Corp"},
#   {"source": "Sarah Chen", "relation": "role", "target": "Head of Engineering"},
#   {"source": "Sarah Chen", "relation": "previously_worked_at", "target": "Google"},
#   {"source": "Sarah Chen", "relation": "worked_on", "target": "TensorFlow"}
# ]

Querying the Graph

// JavaScript — traverse relationships
const response = await fetch(`${BASE}/graph/traverse`, {
  method: "POST",
  headers: {
    "X-API-Key": API_KEY,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    agent_id: "assistant",
    entity: "Sarah Chen",
    max_depth: 2,
    relationship_types: ["works_at", "previously_worked_at", "knows"]
  })
});

const graph = await response.json();
// Returns nodes and edges within 2 hops of Sarah Chen
console.log(graph.nodes);   // All connected entities
console.log(graph.edges);   // All relationships between them

Explicit Relationship Management

# Add a relationship explicitly
requests.post(f"{BASE}/graph/relationships", headers={
    "X-API-Key": API_KEY,
    "Content-Type": "application/json"
}, json={
    "agent_id": "assistant",
    "source": {"entity": "Acme Corp", "type": "organization"},
    "relationship": "client_of",
    "target": {"entity": "BigCo Industries", "type": "organization"},
    "confidence": 0.95
})

# Query: Who is connected to BigCo through any path?
response = requests.post(f"{BASE}/graph/traverse", headers={
    "X-API-Key": API_KEY,
    "Content-Type": "application/json"
}, json={
    "agent_id": "assistant",
    "entity": "BigCo Industries",
    "max_depth": 3
})
# Returns Sarah Chen (via Acme Corp → works_at → Sarah Chen)

Graph memory is available on Scale ($99/mo) and Enterprise. Unlike competitors that gate knowledge graph features behind enterprise tiers, 0Latency includes entity extraction and graph traversal on Scale ($99/mo) and Enterprise plans. We believe relational understanding is fundamental to agent intelligence, not a premium feature.

Performance: Postgres vs Neo4j at Agent Scale

We benchmarked our Postgres recursive CTE approach against Neo4j for typical AI agent workloads:

Operation 0Latency (Postgres) Neo4j Aura
1-hop traversal (1K relationships) 3ms 2ms
3-hop traversal (10K relationships) 18ms 8ms
3-hop traversal (100K relationships) 45ms 12ms
3-hop traversal (1M relationships) 89ms 25ms
Combined semantic + graph query 52ms (single DB) 85ms (cross-DB)

Neo4j is faster at pure graph traversal — that's its entire purpose. But the moment you need to combine graph data with semantic memory search, Postgres wins because everything lives in one database. No cross-database joins, no network hops, no synchronization lag.

For agents with under 1 million relationships (which is 99% of production deployments), the Postgres approach performs efficiently in the request path and eliminates an entire category of infrastructure complexity.

How Competitors Handle (or Don't Handle) Graph Memory

Feature 0Latency Mem0 Zep
Entity extraction ✅ Scale/Enterprise only ✅ Available ✅ Available
Relationship mapping ✅ Automatic + explicit ⚠️ Limited ⚠️ Basic
Graph traversal API ✅ Multi-hop, filtered ❌ No traversal ❌ No traversal
Free tier includes graph ✅ Yes ❌ Enterprise only ❌ Paid plans only
Additional infrastructure ✅ None (Postgres) N/A N/A
Combined semantic + graph ✅ Single query ❌ Separate systems ❌ Separate systems

Graph-Enhanced Memory Search

The real power of having graph memory in the same database as semantic memory is that you can combine them. When your agent searches for memories about "Sarah," 0Latency can optionally expand the search to include memories about entities connected to Sarah:

# Graph-enhanced search: find memories about Sarah
# AND memories about entities connected to her
response = requests.post(f"{BASE}/memories/search", headers={
    "X-API-Key": API_KEY,
    "Content-Type": "application/json"
}, json={
    "agent_id": "assistant",
    "query": "What's happening with Sarah's projects?",
    "graph_expand": True,      # Expand search to connected entities
    "graph_depth": 1,          # Include 1-hop connections
    "limit": 10
})

# Returns memories about Sarah AND Acme Corp AND her team members
# All ranked by combined semantic + temporal + graph relevance

This is incredibly powerful for agents that need to understand context holistically. Instead of just finding memories that mention Sarah directly, the agent also retrieves context about her company, her team, and her projects — all in a single API call without cross-system queries.

Getting Started with Graph Memory

Graph memory is enabled by default. When you store memories, entity extraction and relationship mapping happen automatically. To start leveraging graph traversal:

  1. Store memories as usual — entities and relationships are extracted automatically
  2. Use graph_expand: true in searches to leverage relational context
  3. Add explicit relationships via the /graph/relationships endpoint for high-confidence connections
  4. Traverse the graph via /graph/traverse for exploration and debugging

Check the documentation for the full graph API reference, and see our pricing page to confirm that yes, graph memory really is available on Scale ($99/mo) and Enterprise.

Build knowledge graphs without the infrastructure tax

Graph memory available on Scale and Enterprise plans. No Neo4j required. No additional cost.

Get Your Free API Key →

Frequently Asked Questions

Do I need to define a schema for entities and relationships?

No. 0Latency uses a flexible schema where entity types and relationship types are strings. The system automatically normalizes common types (person, organization, technology, location) but you can use any type. There's no schema migration needed — just store memories and the graph builds itself.

How accurate is automatic entity extraction?

Entity extraction uses an LLM-powered pipeline that achieves 90%+ accuracy on well-structured text. For critical relationships, we recommend using the explicit /graph/relationships endpoint to ensure accuracy. Confidence scores are attached to every extracted relationship so you can filter by reliability.

Can graph memory work across multiple agents?

Yes. By default, relationships are scoped to the agent that created them. But you can enable shared graph memory using agent groups, allowing multiple agents to contribute to and query a unified knowledge graph. See our multi-agent memory guide for details.

What happens when the graph gets very large?

For graphs under 1 million relationships, recursive CTEs perform efficiently enough to run synchronously in the request path. Above that, we apply automatic pruning based on confidence scores and temporal decay — low-confidence, stale relationships are archived. For Enterprise customers with massive graphs, we offer dedicated Postgres instances with optimized indexes.

Can I export the graph data?

Yes. The /graph/export endpoint returns your entire graph in standard formats (JSON, CSV, or GraphML) for visualization in tools like Gephi or for migration to a dedicated graph database if your needs outgrow the Postgres approach.