---
title: "Neo4j Setup"
description: "Complete guide to installing and configuring Neo4j for TracerTM graph capabilities"
---

# Neo4j Setup

Neo4j is an optional graph database that powers TracerTM's advanced relationship visualization and traversal features. This guide covers everything from installation to production deployment.

## Overview

TracerTM uses Neo4j to:
- Visualize complex item relationships as interactive graphs
- Perform advanced graph traversals (shortest path, critical path analysis)
- Detect circular dependencies and orphaned items
- Enable impact analysis across traceability chains
- Support multi-hop relationship queries

Neo4j complements the primary PostgreSQL database by providing graph-optimized operations.

## Installation Methods

### macOS Installation

#### Option 1: Homebrew (Recommended)

```bash
# Install Neo4j Community Edition
brew install neo4j

# Start Neo4j service
brew services start neo4j

# Stop Neo4j service
brew services stop neo4j

# Restart Neo4j service
brew services restart neo4j
```

#### Option 2: Neo4j Desktop

1. Download [Neo4j Desktop](https://neo4j.com/download/)
2. Install the DMG package
3. Launch Neo4j Desktop
4. Create a new project named "TracerTM"
5. Add a local database with:
   - Name: `tracertm`
   - Password: (choose a secure password)
   - Version: 5.x (latest stable)

### Linux Installation

#### Ubuntu/Debian

```bash
# Add Neo4j repository
wget -O - https://debian.neo4j.com/neotechnology.gpg.key | sudo apt-key add -
echo 'deb https://debian.neo4j.com stable latest' | sudo tee /etc/apt/sources.list.d/neo4j.list

# Install Neo4j
sudo apt-get update
sudo apt-get install neo4j

# Enable and start service
sudo systemctl enable neo4j
sudo systemctl start neo4j

# Check status
sudo systemctl status neo4j
```

#### RHEL/Fedora/CentOS

```bash
# Add Neo4j repository
sudo rpm --import https://debian.neo4j.com/neotechnology.gpg.key
sudo cat <<EOF > /etc/yum.repos.d/neo4j.repo
[neo4j]
name=Neo4j RPM Repository
baseurl=https://yum.neo4j.com/stable
enabled=1
gpgcheck=1
EOF

# Install Neo4j
sudo yum install neo4j

# Enable and start service
sudo systemctl enable neo4j
sudo systemctl start neo4j
```

### Windows Installation

1. Download [Neo4j Community Edition](https://neo4j.com/download-center/#community)
2. Extract the ZIP file to `C:\neo4j`
3. Open PowerShell as Administrator:

```powershell
# Navigate to Neo4j directory
cd C:\neo4j\bin

# Install as Windows service
.\neo4j install-service

# Start Neo4j
.\neo4j start

# Check status
.\neo4j status
```

### Docker Installation (All Platforms)

```bash
# Pull Neo4j image
docker pull neo4j:5.15.0

# Run Neo4j container
docker run -d \
  --name neo4j-tracertm \
  -p 7474:7474 \
  -p 7687:7687 \
  -e NEO4J_AUTH=neo4j/tracertm_password \
  -e NEO4J_PLUGINS='["apoc", "graph-data-science"]' \
  -v $HOME/neo4j/data:/data \
  -v $HOME/neo4j/logs:/logs \
  neo4j:5.15.0

# View logs
docker logs -f neo4j-tracertm

# Stop container
docker stop neo4j-tracertm

# Start container
docker start neo4j-tracertm
```

## Neo4j Desktop vs Server

### Neo4j Desktop
**Use for:**
- Local development
- Learning and experimentation
- GUI-based database management
- Easy APOC plugin installation

**Pros:**
- User-friendly interface
- Built-in browser and query tools
- Easy database switching
- Automatic updates

**Cons:**
- Higher resource usage
- Desktop application required
- Not suitable for production

### Neo4j Server
**Use for:**
- Production deployments
- CI/CD environments
- Headless servers
- Docker/Kubernetes deployments

**Pros:**
- Lower resource footprint
- Scriptable and automatable
- Better for containerization
- Production-ready

**Cons:**
- Command-line configuration
- Manual plugin installation
- Requires external browser access

## Creating the TracerTM Database

### First-Time Setup

1. Access Neo4j Browser at `http://localhost:7474`

2. Login with default credentials:
   - Username: `neo4j`
   - Password: `neo4j`

3. Change the default password when prompted:
   ```cypher
   ALTER CURRENT USER SET PASSWORD FROM 'neo4j' TO 'your_secure_password';
   ```

4. Create a dedicated database (Neo4j Enterprise only, skip for Community):
   ```cypher
   CREATE DATABASE tracertm;
   :use tracertm;
   ```

   For Community Edition, use the default `neo4j` database.

## Authentication Setup

### Environment Variables

Create or update your `.env` file:

```bash
# Neo4j Configuration
NEO4J_URI=bolt://localhost:7687
NEO4J_USER=neo4j
NEO4J_PASSWORD=your_secure_password
NEO4J_DATABASE=neo4j  # or 'tracertm' for Enterprise

# Optional: Connection pool settings
NEO4J_MAX_CONNECTION_LIFETIME=3600
NEO4J_MAX_CONNECTION_POOL_SIZE=50
NEO4J_CONNECTION_ACQUISITION_TIMEOUT=60
```

### Configuration File

If using a `config.yaml`:

```yaml
neo4j:
  uri: bolt://localhost:7687
  user: neo4j
  password: ${NEO4J_PASSWORD}  # Read from environment
  database: neo4j
  encrypted: false  # Set true for production

  # Connection pool
  max_connection_lifetime: 3600
  max_connection_pool_size: 50
  connection_acquisition_timeout: 60

  # Trust settings (for SSL/TLS)
  trust: TRUST_SYSTEM_CA_SIGNED_CERTIFICATES
```

### Programmatic Connection

```python
from neo4j import GraphDatabase

class Neo4jConnection:
    def __init__(self, uri: str, user: str, password: str, database: str = "neo4j"):
        self.driver = GraphDatabase.driver(uri, auth=(user, password))
        self.database = database

    def close(self):
        if self.driver:
            self.driver.close()

    def verify_connectivity(self):
        with self.driver.session(database=self.database) as session:
            result = session.run("RETURN 1 AS test")
            return result.single()["test"] == 1

# Usage
conn = Neo4jConnection(
    uri="bolt://localhost:7687",
    user="neo4j",
    password="your_password"
)

if conn.verify_connectivity():
    print("Neo4j connection successful!")
```

## APOC Plugin Installation

APOC (Awesome Procedures On Cypher) provides essential utilities for TracerTM graph operations.

### Docker Installation

APOC is included automatically with the `-e NEO4J_PLUGINS='["apoc"]'` flag.

### Desktop Installation

1. Open Neo4j Desktop
2. Select your database
3. Click "Plugins" tab
4. Find "APOC" and click "Install"
5. Restart the database

### Server Installation (Manual)

```bash
# Download APOC jar
cd $NEO4J_HOME/plugins
wget https://github.com/neo4j/apoc/releases/download/5.15.0/apoc-5.15.0-core.jar

# Enable APOC in neo4j.conf
echo "dbms.security.procedures.unrestricted=apoc.*" >> $NEO4J_HOME/conf/neo4j.conf
echo "dbms.security.procedures.allowlist=apoc.*" >> $NEO4J_HOME/conf/neo4j.conf

# Restart Neo4j
neo4j restart
```

### Verify APOC Installation

```cypher
CALL apoc.help("apoc");
```

Expected output: List of APOC procedures and functions.

## Graph Data Science Library (Optional)

The Graph Data Science (GDS) library enables advanced analytics like community detection and centrality algorithms.

### Docker Installation

```bash
docker run -d \
  --name neo4j-tracertm \
  -p 7474:7474 \
  -p 7687:7687 \
  -e NEO4J_AUTH=neo4j/password \
  -e NEO4J_PLUGINS='["apoc", "graph-data-science"]' \
  neo4j:5.15.0
```

### Desktop Installation

1. Click "Plugins" in Neo4j Desktop
2. Install "Graph Data Science Library"
3. Restart database

### Server Installation

```bash
cd $NEO4J_HOME/plugins
wget https://github.com/neo4j/graph-data-science/releases/download/2.5.0/neo4j-graph-data-science-2.5.0.jar

# Update neo4j.conf
echo "dbms.security.procedures.unrestricted=gds.*" >> $NEO4J_HOME/conf/neo4j.conf
echo "dbms.security.procedures.allowlist=gds.*" >> $NEO4J_HOME/conf/neo4j.conf

neo4j restart
```

### Verify GDS Installation

```cypher
CALL gds.list();
```

## Schema Constraints and Indexes

Run these Cypher queries to establish TracerTM's graph schema:

### Node Constraints

```cypher
-- Project nodes
CREATE CONSTRAINT project_id IF NOT EXISTS
FOR (p:Project) REQUIRE p.id IS UNIQUE;

CREATE CONSTRAINT project_name IF NOT EXISTS
FOR (p:Project) REQUIRE p.name IS UNIQUE;

-- Item nodes
CREATE CONSTRAINT item_id IF NOT EXISTS
FOR (i:Item) REQUIRE i.id IS UNIQUE;

-- Agent nodes (for multi-agent operations)
CREATE CONSTRAINT agent_id IF NOT EXISTS
FOR (a:Agent) REQUIRE a.id IS UNIQUE;
```

### Indexes for Performance

```cypher
-- Item indexes
CREATE INDEX item_project_id IF NOT EXISTS
FOR (i:Item) ON (i.project_id);

CREATE INDEX item_view IF NOT EXISTS
FOR (i:Item) ON (i.view);

CREATE INDEX item_type IF NOT EXISTS
FOR (i:Item) ON (i.item_type);

CREATE INDEX item_status IF NOT EXISTS
FOR (i:Item) ON (i.status);

CREATE INDEX item_priority IF NOT EXISTS
FOR (i:Item) ON (i.priority);

-- Composite index for common queries
CREATE INDEX item_project_view_status IF NOT EXISTS
FOR (i:Item) ON (i.project_id, i.view, i.status);

-- Full-text search index
CREATE FULLTEXT INDEX item_search IF NOT EXISTS
FOR (i:Item) ON EACH [i.title, i.description];
```

### Verify Schema

```cypher
-- Show constraints
SHOW CONSTRAINTS;

-- Show indexes
SHOW INDEXES;
```

## Importing Initial Data

### Sync from PostgreSQL

TracerTM can synchronize data from PostgreSQL to Neo4j:

```python
# Example sync script
from tracertm.services.graph_sync import GraphSyncService

sync = GraphSyncService(
    postgres_uri="postgresql://localhost/tracertm",
    neo4j_uri="bolt://localhost:7687",
    neo4j_auth=("neo4j", "password")
)

# Full sync
sync.sync_all_projects()

# Incremental sync
sync.sync_changes_since(last_sync_timestamp)
```

### Manual Import from CSV

```cypher
-- Import projects
LOAD CSV WITH HEADERS FROM 'file:///projects.csv' AS row
CREATE (p:Project {
  id: row.id,
  name: row.name,
  description: row.description,
  created_at: datetime(row.created_at)
});

-- Import items
LOAD CSV WITH HEADERS FROM 'file:///items.csv' AS row
CREATE (i:Item {
  id: row.id,
  project_id: row.project_id,
  title: row.title,
  description: row.description,
  view: row.view,
  item_type: row.item_type,
  status: row.status,
  priority: row.priority
});

-- Create relationships
LOAD CSV WITH HEADERS FROM 'file:///links.csv' AS row
MATCH (source:Item {id: row.source_item_id})
MATCH (target:Item {id: row.target_item_id})
CREATE (source)-[r:LINKS_TO {
  type: row.link_type,
  created_at: datetime(row.created_at)
}]->(target);
```

### Batch Import with APOC

```cypher
CALL apoc.periodic.iterate(
  "LOAD CSV WITH HEADERS FROM 'file:///items.csv' AS row RETURN row",
  "CREATE (i:Item {
    id: row.id,
    project_id: row.project_id,
    title: row.title,
    view: row.view,
    item_type: row.item_type,
    status: row.status
  })",
  {batchSize: 1000, parallel: true}
);
```

## Neo4j Browser Usage

### Accessing the Browser

Navigate to `http://localhost:7474` in your web browser.

### Essential Queries for TracerTM

#### View All Projects

```cypher
MATCH (p:Project)
RETURN p.name, p.id, p.created_at
ORDER BY p.created_at DESC;
```

#### View Project Graph

```cypher
MATCH (p:Project {name: 'My Project'})<-[:BELONGS_TO]-(i:Item)
OPTIONAL MATCH (i)-[r:LINKS_TO]-(related:Item)
RETURN p, i, r, related
LIMIT 100;
```

#### Find Orphaned Items

```cypher
MATCH (i:Item)
WHERE NOT (i)-[:LINKS_TO]-()
  AND NOT ()-[:LINKS_TO]->(i)
RETURN i.id, i.title, i.view;
```

#### Detect Circular Dependencies

```cypher
MATCH path = (i:Item)-[:LINKS_TO*]->(i)
WHERE ALL(r IN relationships(path) WHERE r.type = 'depends_on')
RETURN [n IN nodes(path) | n.title] AS circular_dependency;
```

#### Impact Analysis

```cypher
MATCH path = (start:Item {id: 'item-123'})-[:LINKS_TO*1..5]->(affected:Item)
RETURN DISTINCT affected.title, affected.view, length(path) AS hops
ORDER BY hops;
```

### Visualization Tips

- Use different colors for node types: Settings → Visualization
- Set captions to show titles: Click node type → Caption → Select "title"
- Limit result sets to avoid browser overload: Always use `LIMIT`

## Common Neo4j Issues

### Issue: Connection Refused

**Symptoms:** Cannot connect to `bolt://localhost:7687`

**Solutions:**
```bash
# Check if Neo4j is running
neo4j status

# Check network listeners
lsof -i :7687  # macOS/Linux
netstat -ano | findstr :7687  # Windows

# Verify configuration
cat $NEO4J_HOME/conf/neo4j.conf | grep dbms.connector.bolt.listen_address

# Should be: dbms.connector.bolt.listen_address=0.0.0.0:7687
```

### Issue: Authentication Failed

**Solutions:**
```cypher
-- Reset password (requires server access)
# Stop Neo4j
neo4j stop

# Remove auth file
rm $NEO4J_HOME/data/dbms/auth

# Restart and use default credentials
neo4j start
```

### Issue: Out of Memory

**Symptoms:** Queries fail with heap space errors

**Solutions:**
```bash
# Edit neo4j.conf
server.memory.heap.initial_size=2g
server.memory.heap.max_size=4g
server.memory.pagecache.size=2g

# Restart Neo4j
neo4j restart
```

### Issue: Slow Queries

**Diagnosis:**
```cypher
-- Profile query
PROFILE MATCH (i:Item)-[:LINKS_TO]->(t:Item)
WHERE i.project_id = 'abc'
RETURN i, t;

-- Check for missing indexes
EXPLAIN MATCH (i:Item {project_id: 'abc'})
RETURN i;
```

**Solutions:**
- Add appropriate indexes (see Schema section)
- Use parameterized queries
- Limit relationship traversal depth
- Consider using `OPTIONAL MATCH` for better performance

### Issue: APOC Procedures Not Found

**Solutions:**
```bash
# Verify JAR is in plugins directory
ls $NEO4J_HOME/plugins/apoc*.jar

# Check neo4j.conf allows APOC
grep "apoc" $NEO4J_HOME/conf/neo4j.conf

# Should contain:
# dbms.security.procedures.unrestricted=apoc.*
# dbms.security.procedures.allowlist=apoc.*

# Check logs
tail -f $NEO4J_HOME/logs/neo4j.log
```

## Performance Considerations

### Memory Configuration

For production deployments with large graphs:

```bash
# neo4j.conf
server.memory.heap.initial_size=8g
server.memory.heap.max_size=16g
server.memory.pagecache.size=8g
```

### Query Optimization

```cypher
-- BAD: Scans all nodes
MATCH (i:Item)
WHERE i.project_id = 'abc'
RETURN i;

-- GOOD: Uses index
MATCH (i:Item {project_id: 'abc'})
RETURN i;

-- BETTER: With parameters
MATCH (i:Item {project_id: $projectId})
RETURN i;
```

### Batch Operations

```cypher
-- Use UNWIND for batch inserts
UNWIND $items AS item
CREATE (i:Item {
  id: item.id,
  title: item.title,
  project_id: item.project_id
});
```

### Monitoring

```cypher
-- Query statistics
CALL dbms.queryJmx('org.neo4j:*')
YIELD name, attributes;

-- Cache statistics
CALL dbms.listConfig()
YIELD name, value
WHERE name STARTS WITH 'metrics';
```

## Next Steps

- [Graph Service Documentation](/docs/development/services/graph-service)
- [Impact Analysis Guide](/docs/guides/impact-analysis)
- [Neo4j Best Practices](/docs/development/best-practices/neo4j)
- [Troubleshooting Guide](/docs/troubleshooting/neo4j)

## External Resources

- [Neo4j Documentation](https://neo4j.com/docs/)
- [Cypher Query Language Reference](https://neo4j.com/docs/cypher-manual/current/)
- [APOC Documentation](https://neo4j.com/labs/apoc/)
- [Graph Data Science Library](https://neo4j.com/docs/graph-data-science/current/)
