Geode is an enterprise-ready graph database packed with production-grade features for reliability, performance, security, and scalability. This comprehensive guide covers all major database capabilities.

Core Transaction Features

ACID Compliance

Geode provides full ACID guarantees for data integrity:

// Atomic operations
BEGIN TRANSACTION;
  CREATE (:Account {id: 1, balance: 1000});
  CREATE (:Account {id: 2, balance: 500});
  MATCH (a:Account {id: 1}), (b:Account {id: 2})
  SET a.balance = a.balance - 100,
      b.balance = b.balance + 100;
COMMIT;

// Rollback on error
BEGIN TRANSACTION;
  MATCH (a:Account {id: 1})
  SET a.balance = a.balance - 10000;  // Would go negative
  // Automatically rolled back if constraint fails
COMMIT;

Isolation Levels

Geode implements Serializable Snapshot Isolation (SSI) by default, the strongest isolation level, preventing all anomalies including phantom reads, dirty reads, and write skew.

# Python client with explicit isolation
async with client.connection() as tx:
    # Isolation is configured server-side
    await tx.begin()
    result, _ = await tx.query("MATCH (u:User {id: $id}) RETURN u", {"id": 123})
    await tx.query("CREATE (:AuditLog {user_id: $id, action: 'login'})", {"id": 123})
    await tx.commit()

Savepoints

Nested transaction control with savepoints:

BEGIN TRANSACTION;
  CREATE (:User {id: 1, name: 'Alice'});

  SAVEPOINT sp1;
  CREATE (:User {id: 2, name: 'Bob'});

  ROLLBACK TO SAVEPOINT sp1;  // Removes Bob, keeps Alice

  CREATE (:User {id: 3, name: 'Charlie'});
COMMIT;  // Commits Alice and Charlie

Indexing and Performance

Index Types

Multiple index types for different access patterns:

// B-tree index (range queries, sorting)
CREATE INDEX FOR (p:Product) ON (p.price);

// Hash index (equality lookups)
CREATE HASH INDEX FOR (u:User) ON (u.id);

// Text index (full-text search)
CREATE TEXT INDEX FOR (p:Post) ON (p.content);

// Composite index (multi-column)
CREATE INDEX FOR (u:User) ON (u.last_name, u.first_name);

// HNSW vector index (similarity search)
CREATE VECTOR INDEX FOR (d:Document) ON (d.embedding)
OPTIONS {metric: 'cosine', dimensions: 768, m: 16, ef_construction: 200};

// BM25 index (ranking search)
CREATE BM25 INDEX FOR (a:Article) ON (a.title, a.body);

Query Optimization

Built-in query optimization and execution planning:

// Explain query plan
EXPLAIN MATCH (u:User)-[:PURCHASED]->(p:Product)
WHERE p.price > 100
RETURN u.name, COUNT(p);

// Profile execution with metrics
PROFILE MATCH (u:User)-[:PURCHASED]->(p:Product)
WHERE p.price > 100
RETURN u.name, COUNT(p);

Security Features

Row-Level Security (RLS)

Fine-grained access control at the data level:

// Create RLS policy
CREATE POLICY tenant_isolation ON User
USING (tenant_id = current_setting('app.tenant_id'));

// Apply policy
ALTER LABEL User ENABLE ROW LEVEL SECURITY;

// Set session context
SET app.tenant_id = 'acme';

// Query only sees tenant's data
MATCH (u:User) RETURN u;  // Automatically filtered

Encryption

Data protection at rest and in transit:

// Transparent Data Encryption (TDE)
-- Configured at server level, encrypts all data files

// Field-Level Encryption (FLE)
CREATE (:User {
  name: 'Alice',
  ssn: ENCRYPT('123-45-6789', 'user-key'),
  email: ENCRYPT('alice@example.com', 'user-key')
});

// Decrypt on retrieval
MATCH (u:User {name: 'Alice'})
RETURN u.name, DECRYPT(u.ssn, 'user-key') AS ssn;

Authentication and Authorization

# Client authentication
client = Client(
    'localhost:3141',
    username='admin',
    password='secure-password',
    tls_verify=True
)

# Role-based access control
await client.execute("""
    CREATE ROLE analyst;
    GRANT SELECT ON * TO analyst;
    GRANT analyst TO user_bob;
""")

Replication and High Availability

Streaming Replication

Real-time data replication to standby servers:

# Configure primary
geode serve --listen 0.0.0.0:3141 --replication-mode primary

# Configure replica
geode serve --listen 0.0.0.0:3142 --replication-mode replica --primary-host primary-host:3141

Change Data Capture (CDC)

Stream database changes to external systems:

# Poll application ChangeLog
last_seen = "1970-01-01T00:00:00Z"
async with client.connection() as conn:
    result, _ = await conn.query(
        """
        MATCH (e:ChangeLog)
        WHERE e.emitted_at > $since AND e.label IN $labels
        RETURN e.operation AS operation,
               e.label AS label,
               e.after AS after,
               e.emitted_at AS emitted_at
        ORDER BY emitted_at
        """,
        {"since": last_seen, "labels": ["User", "Product"]},
    )
    for row in result.rows:
        print(f"Operation: {row['operation'].raw_value}")  # INSERT, UPDATE, DELETE
        print(f"Label: {row['label'].raw_value}")
        print(f"Data: {row['after'].raw_value}")
        print(f"Timestamp: {row['emitted_at'].raw_value}")

Backup and Recovery

Point-in-Time Recovery

Restore to any point in transaction history:

# Create backup
geode backup create --destination /backups/geode-20240615

# Restore from backup
geode backup restore --source /backups/geode-20240615 --target /data/geode-restored

# Point-in-time restore
geode backup restore --source /backups/geode-20240615 --timestamp '2024-06-15T14:30:00Z'

Continuous Backup

Automated backup scheduling:

# Configure continuous backup
geode serve --backup-enabled --backup-interval 3600 --backup-destination /backups

Advanced Query Features

Prepared Statements

Compiled queries with parameter substitution:

# Prepare statement once
stmt = await client.prepare("""
    MATCH (u:User {id: $id})
    RETURN u.name, u.email
""")

# Execute multiple times with different parameters
result1, _ = await stmt.execute({"id": 1})
result2, _ = await stmt.execute({"id": 2})
result3, _ = await stmt.execute({"id": 3})

Stored Procedures

Reusable database logic:

// Create procedure
CREATE PROCEDURE transfer_funds(from_id INT, to_id INT, amount FLOAT)
LANGUAGE GQL
AS $$
BEGIN TRANSACTION;
  MATCH (from:Account {id: $from_id}), (to:Account {id: $to_id})
  WHERE from.balance >= $amount
  SET from.balance = from.balance - $amount,
      to.balance = to.balance + $amount;
  RETURN from, to;
COMMIT;
$$;

// Call procedure
CALL transfer_funds(1, 2, 100.0);

Query Caching

Automatic result caching for repeated queries:

# Enable query cache
client = Client('localhost:3141', enable_cache=True, cache_ttl=300)

# First execution hits database
result1 = await client.query("MATCH (u:User) WHERE u.active = true RETURN COUNT(u)")

# Second execution uses cache (if within TTL)
result2 = await client.query("MATCH (u:User) WHERE u.active = true RETURN COUNT(u)")

Monitoring and Observability

Performance Metrics

Built-in metrics collection:

// Query current metrics
SHOW METRICS;

// Results include:
// - queries_per_second
// - average_query_latency_ms
// - active_connections
// - cache_hit_rate
// - index_usage_stats
// - transaction_throughput

Query Logging

Detailed query execution logging:

# Enable slow query log
geode serve --slow-query-log --slow-query-threshold 1000  # Log queries > 1s

Health Checks

Built-in health monitoring:

# Health check endpoint
health = await client.health_check()
print(f"Status: {health['status']}")  # 'healthy', 'degraded', 'unhealthy'
print(f"Uptime: {health['uptime_seconds']}")
print(f"Version: {health['version']}")

Schema Management

Constraints

Data integrity enforcement:

// Unique constraints
CREATE CONSTRAINT ON (u:User) ASSERT u.email IS UNIQUE;

// Existence constraints
CREATE CONSTRAINT ON (u:User) ASSERT EXISTS(u.email);

// Property type constraints
CREATE CONSTRAINT ON (p:Product) ASSERT p.price IS :: FLOAT;

// Check constraints
CREATE CONSTRAINT ON (u:User) ASSERT u.age >= 0 AND u.age <= 150;

Schema Versioning

Track schema changes over time:

// Create versioned schema change
BEGIN SCHEMA MIGRATION 'v2.0.0';
  CREATE INDEX FOR (p:Product) ON (p.category);
  ALTER LABEL User ADD PROPERTY created_at DATETIME DEFAULT NOW();
COMMIT SCHEMA MIGRATION;

// View migration history
SHOW SCHEMA MIGRATIONS;

Import and Export

Bulk Data Loading

Efficient bulk import:

# Import from CSV
geode import --format csv --file users.csv --label User --mapping id:id,name:name,email:email

# Import from JSON
geode import --format json --file data.json

# Import from Cypher/GQL dump
geode import --format gql --file database.gql

Data Export

Export data in various formats:

# Export to CSV
geode export --format csv --query "MATCH (u:User) RETURN u.id, u.name, u.email" --output users.csv

# Export entire database
geode export --format gql --output database-backup.gql

# Export to JSON
geode export --format json --query "MATCH (u:User) RETURN u" --output users.json

Multi-Tenancy

Logical Isolation

Isolate tenant data within single database:

// Schema-based multi-tenancy
CREATE GRAPH tenant_acme;
CREATE GRAPH tenant_globex;

// Switch context
USE GRAPH tenant_acme;
MATCH (u:User) RETURN u;  // Only sees Acme data

// RLS-based multi-tenancy
CREATE POLICY tenant_filter ON *
USING (tenant_id = current_setting('app.tenant_id'));

Client Libraries

Polyglot client support for multiple languages:

# Python (async)
from geode_client import Client
client = Client(host="localhost", port=3141)
async with client.connection() as conn:
    result, _ = await conn.query("MATCH (u:User) RETURN u")
// Go (database/sql)
import "database/sql"
import _ "geodedb.com/geode"

db, _ := sql.Open("geode", "quic://localhost:3141")
rows, _ := db.Query("MATCH (u:User) RETURN u.name")
// Rust (async)
use geode_client::Client;

let client = Client::from_dsn("localhost:3141")?;
let mut conn = client.connect().await?;
let (page, _) = conn.query("MATCH (u:User) RETURN u").await?;

Standards Compliance

ISO/IEC 39075:2024 GQL

Aligned with the ISO 100% GQL compliance:

  • MATCH and OPTIONAL MATCH with bounded expansions
  • Deterministic ORDER BY and pagination policies
  • Set operations (UNION, INTERSECT, EXCEPT)
  • Diagnostics aligned to the conformance profile

Interoperability

Standard protocol support:

  • QUIC transport (RFC 9000)
  • TLS 1.3 encryption (RFC 8446)
  • Protobuf wire protocol
  • OpenCypher compatibility layer
  • Transactions: Deep dive into transaction management
  • Security: Comprehensive security configuration
  • Replication: High availability setup
  • Performance: Query optimization and tuning
  • Monitoring: Observability and metrics

Further Reading

Geode’s comprehensive feature set provides everything needed for production-grade graph database deployments, from single-node development to distributed enterprise systems.

Advanced Enterprise Features

Multi-Tenancy Implementation

Isolate tenant data with Row-Level Security:

class MultiTenantClient:
    def __init__(self, base_client):
        self.client = base_client
    
    async def setup_tenant_isolation(self):
        """Configure RLS policies for multi-tenancy"""
        await self.client.execute("""
            -- Create RLS policy for users
            CREATE POLICY tenant_users ON User
            USING (tenant_id = current_setting('app.tenant_id'));
            
            -- Create RLS policy for orders
            CREATE POLICY tenant_orders ON Order
            USING (tenant_id = current_setting('app.tenant_id'));
            
            -- Enable RLS
            ALTER LABEL User ENABLE ROW LEVEL SECURITY;
            ALTER LABEL Order ENABLE ROW LEVEL SECURITY;
        """)
    
    async def execute_for_tenant(self, tenant_id, query, params=None):
        """Execute query in tenant context"""
        async with self.client.connection() as conn:
            await conn.begin()
            try:
                # Set tenant context
                await conn.execute("""
                    SET app.tenant_id = $tenant_id
                """, {"tenant_id": tenant_id})

                # Execute query (RLS auto-applied)
                result, _ = await conn.query(query, params)
                await conn.commit()
                return result
            except Exception:
                await conn.rollback()
                raise

# Usage
client = MultiTenantClient(base_client)
await client.setup_tenant_isolation()

# Queries automatically filtered by tenant
result = await client.execute_for_tenant("tenant_123", """
    MATCH (u:User) RETURN u.name
""")  # Only sees tenant_123 users

Time-Travel Queries

Query historical state with temporal data:

-- Point-in-time query
MATCH (u:User)
WHERE u.valid_from <= datetime('2024-01-15')
  AND (u.valid_to IS NULL OR u.valid_to > datetime('2024-01-15'))
RETURN u.name, u.email

-- Temporal join
MATCH (e:Employee)-[r:WORKS_FOR]->(c:Company)
WHERE r.start_date <= datetime('2023-06-01')
  AND (r.end_date IS NULL OR r.end_date >= datetime('2023-06-01'))
RETURN e.name, c.name

-- Audit trail
MATCH (a:Account {id: $account_id})-[:HAS_HISTORY]->(h:AccountHistory)
WHERE h.timestamp BETWEEN datetime('2024-01-01') AND datetime('2024-12-31')
RETURN h.balance, h.timestamp
ORDER BY h.timestamp

Full-Text Search Integration

Advanced text search capabilities:

-- Create full-text index
CREATE TEXT INDEX FOR (p:Post) ON (p.title, p.content);
CREATE TEXT INDEX FOR (a:Article) ON (a.body)
OPTIONS {language: 'english', stemming: true};

-- Basic text search
MATCH (p:Post)
WHERE p.content CONTAINS 'graph database'
RETURN p.title, p.content

-- Ranked search with BM25
CREATE BM25 INDEX FOR (d:Document) ON (d.title, d.body);

MATCH (d:Document)
WHERE d MATCH 'graph AND (database OR query)'
RETURN d.title, score(d) as relevance
ORDER BY relevance DESC
LIMIT 10

-- Phrase search
MATCH (a:Article)
WHERE a.body CONTAINS PHRASE 'machine learning'
RETURN a.title

-- Fuzzy search
MATCH (u:User)
WHERE u.name =~ fuzzy('Alise', max_edit_distance: 2)
RETURN u.name

Semantic search with embeddings:

async def semantic_search(client, query_text, limit=10):
    """Perform semantic search using vector embeddings"""
    # Generate query embedding
    query_embedding = await generate_embedding(query_text)
    
    # Vector similarity search
    results, _ = await client.query("""
        MATCH (d:Document)
        WITH d, vector_similarity(d.embedding, $query_embedding, 'cosine') as similarity
        WHERE similarity > 0.7
        RETURN d.id, d.title, d.content, similarity
        ORDER BY similarity DESC
        LIMIT $limit
    """, {
        "query_embedding": query_embedding,
        "limit": limit
    })
    
    return results

# HNSW index for fast approximate search
await client.execute("""
    CREATE VECTOR INDEX document_embeddings
    FOR (d:Document) ON (d.embedding)
    OPTIONS {
        metric: 'cosine',
        dimensions: 768,
        m: 16,
        ef_construction: 200,
        ef_search: 100
    }
""")

Graph Algorithms Library

Built-in algorithm implementations:

-- PageRank
CALL algo.pageRank('User', 'FOLLOWS', {
    iterations: 20,
    dampingFactor: 0.85
}) YIELD node, score
RETURN node.name, score
ORDER BY score DESC
LIMIT 10

-- Community Detection (Louvain)
CALL algo.louvain('User', 'FRIENDS_WITH', {
    resolution: 1.0
}) YIELD node, community
RETURN community, COUNT(node) as size
ORDER BY size DESC

-- Shortest Path
MATCH path = shortestPath((start:User {id: $id1})-[:KNOWS*]-(end:User {id: $id2}))
RETURN [node IN nodes(path) | node.name] as path, length(path) as distance

-- Betweenness Centrality
CALL algo.betweenness('User', 'KNOWS') YIELD node, score
RETURN node.name, score
ORDER BY score DESC
LIMIT 20

Data Validation and Constraints

Comprehensive data integrity:

-- Uniqueness constraints
CREATE CONSTRAINT ON (u:User) ASSERT u.email IS UNIQUE;
CREATE CONSTRAINT ON (p:Product) ASSERT (p.sku, p.variant) IS UNIQUE;

-- Existence constraints
CREATE CONSTRAINT ON (u:User) ASSERT EXISTS(u.email);
CREATE CONSTRAINT ON (o:Order) ASSERT EXISTS(o.customer_id);

-- Type constraints
CREATE CONSTRAINT ON (p:Product) ASSERT p.price IS :: FLOAT;
CREATE CONSTRAINT ON (u:User) ASSERT p.created_at IS :: DATETIME;

-- Check constraints
CREATE CONSTRAINT ON (u:User) ASSERT u.age BETWEEN 0 AND 150;
CREATE CONSTRAINT ON (p:Product) ASSERT p.price > 0;
CREATE CONSTRAINT ON (r:Rating) ASSERT r.score IN [1,2,3,4,5];

-- Pattern constraints
CREATE CONSTRAINT ON (u:User) 
ASSERT u.email =~ '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$';

-- Custom validation functions
CREATE FUNCTION validate_credit_card(card_number STRING) RETURNS BOOLEAN
AS $$
    -- Luhn algorithm implementation
    RETURN luhn_check(card_number);
$$;

CREATE CONSTRAINT ON (p:Payment)
ASSERT validate_credit_card(p.card_number);

Geospatial Features

Location-based queries:

-- Create spatial index
CREATE SPATIAL INDEX FOR (l:Location) ON (l.coordinates);

-- Point creation
CREATE (store:Store {
    name: 'Main Street Store',
    coordinates: point({latitude: 37.7749, longitude: -122.4194})
});

-- Distance queries
MATCH (u:User {id: $user_id}), (store:Store)
WITH u, store, distance(u.location, store.location) as dist_meters
WHERE dist_meters < 5000  // Within 5km
RETURN store.name, dist_meters
ORDER BY dist_meters

-- Polygon containment
MATCH (p:Place)
WHERE contains(
    polygon([
        point({latitude: 37.8, longitude: -122.5}),
        point({latitude: 37.8, longitude: -122.3}),
        point({latitude: 37.7, longitude: -122.3}),
        point({latitude: 37.7, longitude: -122.5})
    ]),
    p.location
)
RETURN p.name

Query Result Caching

Intelligent result caching:

from functools import lru_cache
import hashlib

class CachedClient:
    def __init__(self, client, cache_backend):
        self.client = client
        self.cache = cache_backend
    
    def cache_key(self, query, params):
        """Generate cache key from query and params"""
        content = f"{query}:{json.dumps(params, sort_keys=True)}"
        return hashlib.sha256(content.encode()).hexdigest()
    
    async def execute_cached(self, query, params=None, ttl=300):
        """Execute query with result caching"""
        key = self.cache_key(query, params)
        
        # Check cache
        cached = await self.cache.get(key)
        if cached:
            return json.loads(cached)
        
        # Execute query
        result, _ = await self.client.query(query, params)
        
        # Store in cache
        await self.cache.set(key, json.dumps(result), ex=ttl)
        
        return result
    
    async def invalidate_pattern(self, pattern):
        """Invalidate cached queries matching pattern"""
        keys = await self.cache.keys(f"{pattern}*")
        if keys:
            await self.cache.delete(*keys)

Batch Operations

Efficient bulk data processing:

async def batch_insert_users(client, users, batch_size=1000):
    """Insert users in batches"""
    for i in range(0, len(users), batch_size):
        batch = users[i:i + batch_size]
        
        await client.execute("""
            UNWIND $users AS user_data
            CREATE (u:User {
                id: user_data.id,
                name: user_data.name,
                email: user_data.email,
                created_at: datetime()
            })
        """, {"users": batch})

async def batch_update_prices(client, price_updates):
    """Update prices in batch"""
    await client.execute("""
        UNWIND $updates AS update
        MATCH (p:Product {id: update.product_id})
        SET p.price = update.new_price,
            p.updated_at = datetime()
    """, {"updates": price_updates})

Browse the tagged content below to discover comprehensive feature documentation and implementation guides for Geode’s enterprise capabilities.


Related Articles