Overview

Geode provides comprehensive session management features for maintaining stateful connections to the database. Sessions enable parameter storage, transaction management, connection pooling, and timeout configuration.

What You’ll Learn

  • How to use session parameters (GRAPH, VALUE, BINDING TABLE)
  • Connection pooling configuration and best practices
  • Session lifecycle and timeout management
  • Session state persistence and restoration
  • Advanced session patterns for multi-tenant applications

Prerequisites

  • Geode installed (see Installation Guide )
  • Basic understanding of database sessions
  • Familiarity with GQL query syntax

Session Parameters

Session parameters allow you to store named values that persist across queries within a session. Geode supports three types of session parameters according to ISO/IEC 39075:2024.

1. Graph Parameters

Graph parameters store references to graphs for use in graph pattern queries.

Syntax:

SESSION SET GRAPH [$param_name] = <graph_expression> [IF NOT EXISTS]

Examples:

-- Set current graph as parameter
SESSION SET GRAPH $my_graph = CURRENT_GRAPH

-- Set specific graph
SESSION SET GRAPH $social = social_network

-- Conditional set (only if doesn't exist)
SESSION SET GRAPH IF NOT EXISTS $default_graph = main_graph

-- Reference graph parameter in queries (planned feature)
USE GRAPH $my_graph
MATCH (n:Person) RETURN n

Use Cases:

  • Multi-graph applications
  • Dynamic graph selection
  • Graph isolation for testing
  • Multi-tenant graph separation

2. Value Parameters

Value parameters store scalar values (integers, strings, booleans, etc.) for use in queries.

Syntax:

SESSION SET VALUE [$param_name] = <expression> [IF NOT EXISTS]

Examples:

-- Set integer value
SESSION SET VALUE $counter = 42

-- Set string value
SESSION SET VALUE $username = 'alice'

-- Set boolean value
SESSION SET VALUE $enabled = true

-- Set computed value
SESSION SET VALUE $max_age = 18 * 5  -- 90

-- Conditional set
SESSION SET VALUE IF NOT EXISTS $default_limit = 100

Using in Queries:

-- Set parameter
SESSION SET VALUE $min_age = 25

-- Use in query
MATCH (p:Person)
WHERE p.age >= $min_age
RETURN p.name, p.age
ORDER BY p.age DESC

Use Cases:

  • Query parameterization
  • Default value configuration
  • User preferences
  • Application state

3. Binding Table Parameters

Binding table parameters store references to binding tables (result sets) for use in queries.

Syntax:

SESSION SET [BINDING] TABLE [$param_name] = <binding_table_ref> [IF NOT EXISTS]

Examples:

-- Set binding table
SESSION SET BINDING TABLE $my_table = user_bindings

-- Shorthand syntax (BINDING is optional)
SESSION SET TABLE $results = query_results

-- Store query results
SESSION SET TABLE $active_users = (
  MATCH (u:User)
  WHERE u.active = true
  RETURN u.id, u.name
)

-- Reference in subsequent queries
MATCH (u:User)
WHERE u.id IN $active_users.id
RETURN u

Use Cases:

  • Temporary result storage
  • Query composition
  • Performance optimization (avoiding repeated queries)
  • Complex multi-step analytics

Session Reset

The SESSION RESET command clears session state, including parameters.

Syntax:

SESSION RESET [ALL] PARAMETERS      -- Reset all parameters
SESSION RESET PARAMETERS             -- Same as ALL PARAMETERS
SESSION RESET PARAMETER $name        -- Reset specific parameter
SESSION RESET GRAPH                  -- Reset current graph
SESSION RESET TIME ZONE              -- Reset time zone
SESSION RESET                        -- Reset all session state

Examples:

-- Reset all parameters
SESSION RESET ALL PARAMETERS

-- Reset specific parameter
SESSION SET VALUE $temp = 123
SESSION RESET PARAMETER $temp

-- Reset graph setting
SESSION SET GRAPH $g = my_graph
SESSION RESET GRAPH

-- Reset time zone
SESSION SET TIME ZONE 'America/New_York'
SESSION RESET TIME ZONE

-- Reset everything
SESSION RESET

What Gets Reset:

  • All session parameters (GRAPH, VALUE, TABLE)
  • Current graph selection
  • Time zone setting
  • Transaction state (if applicable)
  • Custom session variables

Connection Pooling

Client-Side Pooling

All Geode clients support connection pooling for optimal resource utilization and performance.

Go Client Pooling
import "geodedb.com/geode"

// Create connection pool
pool, err := geode.NewConnectionPool(&geode.PoolConfig{
    Address:         "localhost:3141",
    MinConnections:  5,
    MaxConnections:  50,
    IdleTimeout:     time.Minute * 10,
    ConnectTimeout:  time.Second * 30,
    MaxLifetime:     time.Hour,
})
if err != nil {
    log.Fatal(err)
}
defer pool.Close()

// Execute queries (automatically uses pooled connections)
result, err := pool.Query(ctx, "MATCH (n:Person) RETURN n LIMIT 10")

Configuration:

  • MinConnections: Minimum pool size (default: 5)
  • MaxConnections: Maximum pool size (default: 100)
  • IdleTimeout: Close idle connections after this duration
  • ConnectTimeout: Connection establishment timeout
  • MaxLifetime: Maximum connection lifetime
Python Client Pooling
from geode_client import ConnectionPool

# Create connection pool (async)
pool = await ConnectionPool.create(
    host='localhost',
    port=3141,
    min_connections=5,
    max_connections=50,
    idle_timeout=600,  # 10 minutes
    max_lifetime=3600,  # 1 hour
)

# Execute queries (async)
async with pool.acquire() as conn:
    result, _ = await conn.query("MATCH (n:Person) RETURN n LIMIT 10")

# Cleanup
await pool.close()

Performance: Throughput depends on workload, network, and server limits; pooling reduces connection overhead

Rust Client Pooling
use geode_client::ConnectionPool;

let pool = ConnectionPool::new("localhost", 3141, 10).skip_verify(true);
let mut conn = pool.acquire().await?;
let (page, _) = conn.query("MATCH (n:Person) RETURN n LIMIT 10").await?;

Performance: Throughput depends on workload, network, and server limits; pooling reduces connection overhead

Zig Client Pooling

The Zig client exposes low-level protocol primitives. Build pooling at the application layer or wrap GeodeClient with your own pool implementation.

Server-Side Configuration

Configure server-side connection limits:

# geode.yaml
network:
  max_connections: 5000
  connection_timeout: 60s
  idle_timeout: 300s

performance:
  worker_threads: 16
  max_concurrent_queries: 1000

Command-Line:

geode serve \
  --max-connections 5000 \
  --connection-timeout 60s \
  --idle-timeout 300s \
  --worker-threads 16

Environment Variables:

export GEODE_MAX_CONNECTIONS=5000
export GEODE_CONNECTION_TIMEOUT=60s
export GEODE_IDLE_TIMEOUT=300s

Timeout Configuration

Connection Timeout

Time limit for establishing a connection:

# Server configuration
network:
  connection_timeout: 30s

Client Configuration:

// Go
config := &geode.Config{
    ConnectTimeout: 30 * time.Second,
}
# Python
config = ConnectionConfig(
    connect_timeout=30.0,
)

Query Timeout

Time limit for query execution:

# Server configuration
performance:
  query_timeout: 300s  # 5 minutes
  default_timeout: 60s # Default for queries without explicit timeout

Client-Side Timeout:

// Go: Context-based timeout
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()

result, err := conn.Query(ctx, "MATCH (n) RETURN count(n)")
# Python: asyncio timeout
result = await asyncio.wait_for(
    conn.query("MATCH (n) RETURN count(n)"),
    timeout=60.0
)

Idle Timeout

Close connections idle for this duration:

# Server configuration
network:
  idle_timeout: 600s  # 10 minutes

Behavior:

  • Server monitors idle connections
  • Connections inactive for idle_timeout are closed
  • Client pools automatically reconnect as needed
  • Prevents resource exhaustion from abandoned connections

Transaction Timeout

Time limit for transaction duration:

# Server configuration
transactions:
  timeout: 3600s  # 1 hour
  idle_timeout: 300s  # 5 minutes

Example:

-- Begin transaction
BEGIN TRANSACTION

-- Long-running operations
MATCH (n:Person) SET n.processed = true

-- Must complete within transaction_timeout
COMMIT

Session Lifecycle

Session Creation

Sessions are created automatically on first connection:

// Go: database/sql creates sessions on first use
db, err := sql.Open("geode", "localhost:3141")
_ = db.Ping()
// Session ID assigned automatically

Session ID Format: UUID v4 (e.g., 550e8400-e29b-41d4-a716-446655440000)

Session State

Each session maintains:

  1. Parameters: User-defined variables ($param_name)
  2. Transaction State: Active transaction (if any)
  3. Current Graph: Selected graph context
  4. Time Zone: Session time zone setting
  5. Connection Metadata: Client info, connection time

Session Persistence

Session state persists until:

  • Explicit SESSION RESET command
  • Connection closed
  • Session timeout (server-side)
  • Server restart (sessions not persisted across restarts)

Session Cleanup

Graceful Cleanup:

// Go: Explicit cleanup
defer db.Close()
# Python: Context manager
async with pool.acquire() as conn:
    # Session automatically cleaned up on exit
    pass

Server-Side Cleanup:

  • Idle sessions cleaned up after idle_timeout
  • Abandoned transactions rolled back after transaction_timeout
  • Resources released (memory, file handles)

Advanced Session Patterns

Multi-Tenant Sessions

Isolate tenants using session parameters:

-- Set tenant context
SESSION SET VALUE $tenant_id = 'acme-corp'

-- Automatically filter by tenant
MATCH (n:Customer)
WHERE n.tenant_id = $tenant_id
RETURN n

Enforcement with Row-Level Security:

-- Policy automatically applied
CREATE POLICY tenant_isolation FOR Customer
USING (tenant_id = session_parameter('tenant_id'))

Session-Based Caching

Cache query results in session:

-- First query: expensive computation
SESSION SET TABLE $recent_orders = (
  MATCH (o:Order)
  WHERE o.timestamp > datetime() - duration('P7D')
  RETURN o.id, o.customer_id, o.total
)

-- Subsequent queries: use cached results
MATCH (c:Customer)
WHERE c.id IN $recent_orders.customer_id
RETURN c.name, sum($recent_orders.total) AS total_spent

Session State Snapshots

Save and restore session state:

-- Save current state
SESSION SET VALUE $saved_graph = CURRENT_GRAPH
SESSION SET VALUE $saved_tz = CURRENT_TIMEZONE

-- Make temporary changes
USE GRAPH temp_graph
SET TIME ZONE 'UTC'

-- Restore state
USE GRAPH $saved_graph
SET TIME ZONE $saved_tz

Stateful Workflows

Implement multi-step workflows:

-- Step 1: Initialize workflow
SESSION SET VALUE $workflow_id = uuid()
SESSION SET VALUE $step = 1

-- Step 2: Process data
MATCH (n:RawData)
WHERE n.workflow_id = $workflow_id
CREATE (p:ProcessedData {
  id: uuid(),
  workflow_id: $workflow_id,
  step: $step,
  data: n.data
})
SESSION SET VALUE $step = $step + 1

-- Step 3: Validate
MATCH (p:ProcessedData)
WHERE p.workflow_id = $workflow_id AND p.step = $step - 1
-- Validation logic...

-- Step 4: Finalize
SESSION RESET PARAMETERS

Session Security

Parameter Validation

Always validate session parameters:

--  Unsafe: No validation
SESSION SET VALUE $user_input = $raw_input

--  Safe: Validate before setting
SESSION SET VALUE $validated_age =
  CASE
    WHEN $user_input >= 0 AND $user_input <= 150
    THEN $user_input
    ELSE NULL
  END

Session Hijacking Prevention

Server-Side Protection:

  • TLS 1.3 required (encrypted transport)
  • Session IDs cryptographically random
  • Session binding to client IP (optional)
  • Session timeout enforcement

Client-Side Best Practices:

// Go: Secure configuration
config := &geode.Config{
    TLS: true,
    VerifyCertificate: true,
    SessionTimeout: 3600, // 1 hour
}

Sensitive Data Handling

Avoid storing sensitive data in session parameters:

--  Unsafe: Password in session
SESSION SET VALUE $password = 'secret123'

--  Safe: Use secure parameter passing
MATCH (u:User)
WHERE u.username = $username
  AND verify_password(u.password_hash, $password)
RETURN u
-- $password passed via prepared statement, not stored

Monitoring and Debugging

Session Inspection

Query current session state:

-- Show current session parameters
SHOW SESSION PARAMETERS

-- Show current graph
SHOW CURRENT_GRAPH

-- Show time zone
SHOW TIME ZONE

-- Show session info
SHOW SESSION INFO

Session Metrics

Monitor session activity (server-side):

# Prometheus metrics endpoint
curl http://localhost:9090/metrics | grep session

# Example metrics:
# geode_active_sessions{} 42
# geode_session_create_total{} 1234
# geode_session_timeout_total{} 5
# geode_avg_session_duration_seconds{} 180.5

Session Logging

Enable session debugging:

# geode.yaml
logging:
  level: debug
  modules:
    session: trace

Log Output:

[SESSION] Created session: 550e8400-e29b-41d4-a716-446655440000
[SESSION] Set parameter: $username = 'alice'
[SESSION] Transaction started
[SESSION] Transaction committed
[SESSION] Idle timeout: closing session

Troubleshooting

Connection Pool Exhaustion

Symptom: “Connection pool exhausted” error

Solutions:

  1. Increase max_connections:

    config.MaxConnections = 200
    
  2. Decrease idle_timeout to reclaim connections faster:

    config.IdleTimeout = 5 * time.Minute
    
  3. Check for connection leaks:

    // Always close connections
    defer conn.Close()
    

Session Timeout

Symptom: “Session expired” or “Session not found” error

Solutions:

  1. Increase session timeout:

    network:
      idle_timeout: 1800s  # 30 minutes
    
  2. Use keep-alive queries:

    ticker := time.NewTicker(5 * time.Minute)
    go func() {
        for range ticker.C {
            _, _ = db.QueryContext(ctx, "RETURN 1")  // Keep-alive
        }
    }()
    
  3. Re-establish connection on timeout:

    if errors.Is(err, geode.ErrBadConn) {
        db, err = sql.Open("geode", address)
        _ = db.Ping()
    }
    

Parameter Not Found

Symptom: “Parameter $name not found” error

Solutions:

  1. Set parameter before use:

    SESSION SET VALUE $name = 'Alice'
    MATCH (n:Person) WHERE n.name = $name RETURN n
    
  2. Use IF NOT EXISTS for default values:

    SESSION SET VALUE IF NOT EXISTS $limit = 100
    
  3. Check parameter scope (session-local):

    -- Different sessions have different parameters
    SESSION RESET PARAMETERS  -- Clears all
    

Best Practices

Connection Lifecycle

  1. Use connection pooling for multi-user applications
  2. Always close connections explicitly (defer in Go, context managers in Python)
  3. Set appropriate timeouts based on workload
  4. Monitor pool metrics (active connections, wait time, etc.)

Parameter Management

  1. Name parameters clearly: $user_id not $x
  2. Validate inputs before setting parameters
  3. Use IF NOT EXISTS for default values
  4. Reset parameters after workflows complete
  5. Document parameter contracts for team consistency

Performance Optimization

  1. Reuse connections via pooling (significantly faster than creating new connections)
  2. Batch queries when possible to reduce round-trips
  3. Use prepared statements for repeated queries
  4. Set realistic timeouts (too short = failures, too long = resource waste)
  5. Monitor session duration and optimize long-running sessions

Security Hardening

  1. Always use TLS for production
  2. Validate all session parameters from user input
  3. Implement session timeout to limit exposure
  4. Audit session creation/destruction for compliance
  5. Use row-level security with session parameters for multi-tenancy

Next Steps

Explore More:

Related Topics:

Client Libraries:


ISO Standard: ISO/IEC 39075:2024 §15.3-15.4 Session Types: GRAPH, VALUE, BINDING TABLE parameters Pooling: All 5 client libraries (Go, Python, Rust, Node.js, Zig) Status: Production-ready