> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vortexiq.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Neo4j on Vortex IQ

> Monitor Neo4j health, cost and reliability signals, and catch incidents and runaway spend early.

export const CapabilityPage = ({data}) => {
  const d = data || ({});
  const [tab, setTab] = useState('overview');
  const [sel, setSel] = useState(null);
  const [q, setQ] = useState('');
  const [outcome, setOutcome] = useState('');
  const [status, setStatus] = useState('');
  const [limit, setLimit] = useState(8);
  const monitor = d.monitor || [];
  const audits = d.audits || [];
  const autos = d.autos || [];
  const outcomes = useMemo(() => {
    const s = new Set();
    monitor.forEach(m => s.add(m.o));
    audits.forEach(a => s.add(a.o));
    return [...s].sort();
  }, [monitor, audits]);
  const rows = useMemo(() => {
    const t = q.trim().toLowerCase();
    if (tab === 'monitor') {
      return monitor.filter(m => (!t || (m.n + ' ' + (m.d || '')).toLowerCase().includes(t)) && (!outcome || m.o === outcome));
    }
    if (tab === 'audit') {
      return audits.filter(a => (!t || (a.n + ' ' + (a.why || '')).toLowerCase().includes(t)) && (!outcome || a.o === outcome) && (!status || a.s === status));
    }
    if (tab === 'automate') {
      return autos.filter(w => !t || (w.n + ' ' + (w.d || '')).toLowerCase().includes(t));
    }
    return [];
  }, [tab, q, outcome, status, monitor, audits, autos]);
  const pill = (text, kind) => {
    const tone = kind === 'good' ? {
      color: '#1f9e54',
      borderColor: '#1f9e54',
      background: '#ecf8f110'
    } : kind === 'warn' ? {
      color: '#c07a17',
      borderColor: '#c07a17',
      background: '#fdf6e910'
    } : kind === 'bad' ? {
      color: '#c53527',
      borderColor: '#c53527',
      background: '#fdf0ee10'
    } : kind === 'brand' ? {
      color: '#5529d6',
      borderColor: '#5529d6'
    } : {
      color: 'inherit',
      borderColor: 'currentColor',
      opacity: 0.65
    };
    return <span key={text} style={{
      fontSize: '10.5px',
      fontFamily: 'ui-monospace, monospace',
      border: '1px solid',
      borderRadius: '999px',
      padding: '2px 8px',
      whiteSpace: 'nowrap',
      ...tone
    }}>
        {text}
      </span>;
  };
  const sevKind = s => s === 'critical' ? 'bad' : s === 'high' ? 'warn' : 'muted';
  const fixKind = s => s === 'Prepared fix' ? 'good' : s === 'Candidate remediation' ? 'warn' : 'muted';
  const card = (item, kind) => {
    const title = item.n;
    const badges = kind === 'monitor' ? [pill(item.o, 'brand'), pill(item.a === 'Watch only' || item.a === 'Merchant rule' ? item.a : `Alert ${item.a}`, 'muted')] : kind === 'audit' ? [pill(item.sev, sevKind(item.sev)), pill(item.s, fixKind(item.s))] : [pill(item.role, 'brand'), pill(item.ready, 'good')];
    const body = kind === 'monitor' ? item.nc ? 'Description pending editorial review; the signal is live.' : item.d : kind === 'audit' ? item.why : item.d;
    return <button key={title} onClick={() => setSel({
      kind,
      item
    })} style={{
      display: 'block',
      width: '100%',
      textAlign: 'left',
      border: '1px solid rgba(128,128,128,.28)',
      borderRadius: '10px',
      padding: '12px 14px',
      marginBottom: '8px',
      background: 'transparent',
      cursor: 'pointer',
      font: 'inherit',
      color: 'inherit'
    }}>
        <div style={{
      display: 'flex',
      gap: '10px',
      justifyContent: 'space-between',
      alignItems: 'flex-start',
      flexWrap: 'wrap'
    }}>
          <strong style={{
      fontSize: '14px'
    }}>{title}</strong>
          <span style={{
      display: 'flex',
      gap: '5px',
      flexWrap: 'wrap'
    }}>{badges}</span>
        </div>
        {body ? <div style={{
      fontSize: '12.5px',
      opacity: 0.72,
      marginTop: '4px'
    }}>{body}</div> : null}
      </button>;
  };
  const tabBtn = (id, label) => <button key={id} onClick={() => {
    setTab(id);
    setLimit(8);
    setQ('');
  }} style={{
    border: 0,
    background: 'none',
    font: 'inherit',
    fontWeight: 600,
    fontSize: '14px',
    padding: '9px 14px',
    cursor: 'pointer',
    color: tab === id ? '#5529d6' : 'inherit',
    opacity: tab === id ? 1 : 0.65,
    borderBottom: tab === id ? '2px solid #5529d6' : '2px solid transparent'
  }}>
      {label}
    </button>;
  const inputStyle = {
    border: '1px solid rgba(128,128,128,.3)',
    borderRadius: '999px',
    padding: '7px 13px',
    font: 'inherit',
    fontSize: '13px',
    background: 'transparent',
    color: 'inherit'
  };
  return <div style={{
    position: 'relative'
  }}>
      {}
      <div style={{
    display: 'grid',
    gridTemplateColumns: 'repeat(auto-fit,minmax(120px,1fr))',
    gap: '10px',
    margin: '18px 0'
  }}>
        {(d.stats || []).map(([v, l]) => <div key={l} style={{
    border: '1px solid rgba(128,128,128,.28)',
    borderRadius: '10px',
    padding: '11px 13px'
  }}>
            <div style={{
    fontSize: v.length > 6 ? '15px' : '21px',
    fontWeight: 700,
    letterSpacing: '-.02em',
    color: v.length > 6 ? '#5529d6' : 'inherit'
  }}>{v}</div>
            <div style={{
    fontSize: '11px',
    opacity: 0.66
  }}>{l}</div>
          </div>)}
      </div>

      <div style={{
    display: 'flex',
    gap: '4px',
    borderBottom: '1px solid rgba(128,128,128,.25)',
    marginBottom: '16px',
    flexWrap: 'wrap'
  }}>
        {tabBtn('overview', 'Overview')}
        {tabBtn('monitor', `Monitor (${monitor.length})`)}
        {tabBtn('audit', `Audit (${audits.length})`)}
        {tabBtn('automate', 'Automate')}
      </div>

      {tab === 'overview' && <div>
          <div style={{
    display: 'grid',
    gridTemplateColumns: 'repeat(auto-fit,minmax(240px,1fr))',
    gap: '10px'
  }}>
            {outcomes.map(o => <div key={o} style={{
    border: '1px solid rgba(128,128,128,.28)',
    borderLeft: '3px solid #5529d6',
    borderRadius: '10px',
    padding: '11px 14px'
  }}>
                <strong style={{
    fontSize: '13.5px'
  }}>{o}</strong>
              </div>)}
          </div>
          <p style={{
    fontSize: '13px',
    opacity: 0.75,
    marginTop: '16px'
  }}>
            Every capability follows the same controlled sequence: connect, monitor, detect, recommend,
            approve, execute, verify. Nothing changes a connected system without the approval step.
          </p>
        </div>}

      {tab !== 'overview' && <div>
          <div style={{
    display: 'flex',
    gap: '8px',
    marginBottom: '12px',
    flexWrap: 'wrap'
  }}>
            <input style={{
    ...inputStyle,
    flex: 1,
    minWidth: '170px'
  }} placeholder={`Search ${tab === 'monitor' ? 'signals' : tab === 'audit' ? 'checks' : 'workflows'}...`} value={q} onChange={e => {
    setQ(e.target.value);
    setLimit(8);
  }} />
            {tab !== 'automate' && <select style={inputStyle} value={outcome} onChange={e => {
    setOutcome(e.target.value);
    setLimit(8);
  }}>
                <option value="">All outcomes</option>
                {outcomes.map(o => <option key={o} value={o}>{o}</option>)}
              </select>}
            {tab === 'audit' && <select style={inputStyle} value={status} onChange={e => {
    setStatus(e.target.value);
    setLimit(8);
  }}>
                <option value="">All fix statuses</option>
                <option>Prepared fix</option>
                <option>Candidate remediation</option>
                <option>Report only</option>
              </select>}
          </div>

          {rows.length === 0 && tab === 'automate' && <div style={{
    border: '1px dashed #5529d6',
    borderRadius: '10px',
    padding: '15px'
  }}>
              <strong style={{
    fontSize: '14px'
  }}>Ready to build your first {d.name} workflow</strong>
              <p style={{
    fontSize: '12.5px',
    opacity: 0.75,
    margin: '6px 0 0'
  }}>
                Vortex IQ is integrated with {d.reads} read and {d.writes} write operations on {d.name}.
                Pick a trigger, add them as steps, and every step that changes data pauses for approval.
              </p>
            </div>}
          {rows.length === 0 && tab !== 'automate' && <div style={{
    opacity: 0.6,
    fontSize: '13px'
  }}>Nothing matches this search or filter.</div>}

          {rows.slice(0, limit).map(r => card(r, tab))}

          {rows.length > limit && <button onClick={() => setLimit(rows.length)} style={{
    ...inputStyle,
    display: 'block',
    margin: '10px auto 0',
    cursor: 'pointer'
  }}>
              View all {rows.length}
            </button>}
        </div>}

      {}
      {sel && <>
          <div onClick={() => setSel(null)} style={{
    position: 'fixed',
    inset: 0,
    background: 'rgba(10,6,26,.45)',
    zIndex: 40
  }} />
          <aside style={{
    position: 'fixed',
    top: 0,
    right: 0,
    width: 'min(430px, 94vw)',
    height: '100vh',
    overflowY: 'auto',
    background: 'var(--background, #fff)',
    backgroundColor: 'light-dark(#fff, #0c061f)',
    borderLeft: '1px solid rgba(128,128,128,.3)',
    padding: '20px 22px',
    zIndex: 50
  }}>
            <button onClick={() => setSel(null)} style={{
    float: 'right',
    border: '1px solid rgba(128,128,128,.3)',
    background: 'transparent',
    color: 'inherit',
    borderRadius: '999px',
    width: '30px',
    height: '30px',
    cursor: 'pointer'
  }}>
              ×
            </button>
            <DetailBody sel={sel} d={d} pill={pill} sevKind={sevKind} fixKind={fixKind} />
          </aside>
        </>}
    </div>;
};

Monitor Neo4j health, cost and reliability signals, and catch incidents and runaway spend early.

No changes are made without the configured approval policy. Read-only operations do not modify the connected system; schedules, access scopes, API usage and data handling remain governed by Vortex IQ controls.

[Connect or manage this source](https://app.vortexiq.ai/workbench/settings/sources) · [How connecting works](/integrations/connector-catalogue) · [Create a workflow](https://app.vortexiq.ai/workbench/flows/create?connector=neo4j)

<CapabilityPage data={{"name": "Neo4j", "reads": 8, "writes": 1, "stats": [["21", "performance signals"], ["7", "automated checks"], ["0", "prepared fixes"], ["0", "proven workflows"], ["9", "API operations"]], "resRows": [{"n": "dbquerys", "r": 0, "w": 1}, {"n": "dbstats", "r": 1, "w": 0}, {"n": "dbmclusteroverview()s", "r": 1, "w": 0}, {"n": "dbmlistconnections()s", "r": 1, "w": 0}, {"n": "dbmqueryjmxs", "r": 1, "w": 0}, {"n": "instances", "r": 1, "w": 0}, {"n": "show databases", "r": 1, "w": 0}, {"n": "show transactions", "r": 1, "w": 0}], "opsPhrase": "over 13,000", "connPhrase": "more than 200", "monitor": [{"n": "Cluster Member Not FOLLOWER/LEADER or Lag \u003e10s", "o": "Run operations", "a": "0 / 1", "d": "Alerts for Cluster Member Not FOLLOWER/LEADER or Lag \u003e10s.", "nc": false}, {"n": "Cluster Replication Lag (seconds)", "o": "Run operations", "a": "1 / 10", "d": "Max last-applied-tx lag of any FOLLOWER vs LEADER (dbms.cluster.overview()). Enterprise cluster only.", "nc": false}, {"n": "Connection Pool Saturation %", "o": "Control risk and change", "a": "70 / 90", "d": "Active bolt connections / configured bolt thread-pool max. Saturation = new sessions queue or time out.", "nc": false}, {"n": "Last Successful Snapshot (hours ago)", "o": "Control risk and change", "a": "24 / 72", "d": "Aura-managed only - newest snapshot from the Aura management API. Self-managed merchants run neo4j-admin backup out of band (gated).", "nc": false}, {"n": "Leader Elections (24h)", "o": "Grow revenue", "a": "Merchant rule", "d": "Neo4j-distinctive - repeated leader elections = primary flapping (network / GC pause / hardware). Requires storing the leader identity over time.", "nc": false}, {"n": "Long-Running Transaction Holding Locks (\u003e60s)", "o": "Run operations", "a": "Merchant rule", "d": "Alerts for Long-Running Transaction Holding Locks (\u003e60s).", "nc": false}, {"n": "Long-Running Transactions (\u003e30s)", "o": "Customer experience", "a": "Merchant rule", "d": "Neo4j-distinctive - open transactions from SHOW TRANSACTIONS with elapsedTime \u003e30s hold locks + heap. Runaway Cypher / un-terminated session.", "nc": false}, {"n": "Neo4j Health Score", "o": "Control risk and change", "a": "Merchant rule", "d": "Composite: p95 latency healthy x error-free x cluster-healthy x page-cache-warm x pool-headroom.", "nc": false}, {"n": "Neo4j Query Spike vs Ecom Order Rate", "o": "Protect revenue", "a": "Merchant rule", "d": "Recommendation graphs get hammered by scrapers - QPS up while orders flat = bot traffic on the recommendation endpoint.", "nc": false}, {"n": "Page Cache Hit Ratio %", "o": "Run operations", "a": "95 / 80", "d": "Neo4j-distinctive - page-cache hits / (hits + faults) from db.stats / metrics. \u003c95% = store no longer fits in page cache, IO climbing.", "nc": false}, {"n": "Page Cache Hit Ratio Below 95%", "o": "Run operations", "a": "0 / 1", "d": "Alerts for Page Cache Hit Ratio Below 95%.", "nc": false}, {"n": "Queries per Second (live)", "o": "Run operations", "a": "Watch only", "d": "Transaction-committed rate delta from db.stats / metrics - graph query throughput.", "nc": false}, {"n": "Query Latency p95 (ms)", "o": "Customer experience", "a": "50 / 200", "d": "p95 elapsedTime across transactions sampled from SHOW TRANSACTIONS over the window.", "nc": false}, {"n": "Slow Graph Ops During Checkout Window (5m)", "o": "Protect revenue", "a": "Merchant rule", "d": "Graph powering on-site recommendations stalls → checkout pages slow → conversion drops. Surfaces graph latency as revenue at risk.", "nc": false}, {"n": "Transaction Rollback Rate %", "o": "Customer experience", "a": "0.1 / 1", "d": "Rolled-back / committed transactions from db.stats counters. Spike = deadlocks, constraint violations, or app retry storms.", "nc": false}, {"n": "Bolt Connections In Use", "o": "Run operations", "a": "Watch only", "d": "Active connections from dbms.listConnections().", "nc": false}, {"n": "Cluster Members (role + state)", "o": "Run operations", "a": "Watch only", "d": "From dbms.cluster.overview() - address, role (LEADER / FOLLOWER / READ_REPLICA), databases hosted.", "nc": false}, {"n": "Database Status (ONLINE / OFFLINE)", "o": "Run operations", "a": "Merchant rule", "d": "currentStatus from SHOW DATABASES - surfaces STORE_COPYING / OFFLINE / STARTING states.", "nc": false}, {"n": "JVM Heap Usage %", "o": "Protect revenue", "a": "Merchant rule", "d": "JVM heap used / committed from dbms.queryJmx('java.lang:type=Memory'). Sustained \u003e85% = GC pressure, OOM risk.", "nc": false}, {"n": "Store Size", "o": "Grow revenue", "a": "Watch only", "d": "Total store size in bytes. Trend matters more than absolute - sudden growth = bulk import or runaway write.", "nc": false}, {"n": "Top 10 Slow Transactions", "o": "Customer experience", "a": "Watch only", "d": "From SHOW TRANSACTIONS ordered by elapsedTime - currentQuery, database, owner (hashed), elapsed.", "nc": false}], "audits": [{"n": "Connection pool saturation above 90%", "o": "Customer experience", "sev": "critical", "s": "Report only", "why": "At 90% of the connection pool in use, the database is close to refusing new connections outright. Once it does, every part of the application that needs a fresh database connection, including new customer sessions and checkout, starts failing, not just slowing down.", "codes": ["DB-CAP-001"]}, {"n": "Disk usage above 90%", "o": "Run operations", "sev": "critical", "s": "Report only", "why": "A database that runs out of disk stops accepting writes entirely, which for most stores means orders, inventory updates and customer records stop being saved, not just that the database gets slower. There is very little runway left at 90%.", "codes": ["DB-CAP-002"]}, {"n": "Query error rate above 1% in last 5 minutes", "o": "Run operations", "sev": "critical", "s": "Report only", "why": "More than 1 in 100 queries is failing right now. Depending on what those queries do, this can mean orders not saving, pages failing to load product or customer data, or background jobs silently dropping work, and a rate this high in a 5-minute window is an active incident, not background noise.", "codes": ["DB-ERR-001"]}, {"n": "Last successful backup older than 72 hours", "o": "Run operations", "sev": "high", "s": "Report only", "why": "If something goes wrong with this database right now, the most recent point it can be restored to is over 3 days old. Every order, customer record and inventory change since that backup would be unrecoverable in a real incident, not just delayed.", "codes": ["DB-BAK-001"]}, {"n": "Replication lag above 10 seconds", "o": "Run operations", "sev": "high", "s": "Report only", "why": "Anything reading from the replica, reports, dashboards, or read traffic split off the primary for capacity, is now up to 10+ seconds stale. If the primary fails while lag is this high, the replica is also that far behind on failover, which is a bigger problem than the staleness alone.", "codes": ["DB-REP-001"]}, {"n": "p95 query latency above 200ms sustained 15m", "o": "Customer experience", "sev": "high", "s": "Report only", "why": "One in twenty queries against this database is taking over 200ms, sustained for at least 15 minutes, not a brief spike. Any storefront page, checkout step or order sync that depends on this database inherits that slowness directly, and a sustained p95 this high is usually already visible to customer", "codes": ["DB-PERF-001"]}, {"n": "Buffer / cache hit rate below 80%", "o": "Run operations", "sev": "medium", "s": "Report only", "why": "More than 1 in 5 reads is missing the cache and going to disk instead, which is markedly slower. This shows up as everything the database does feeling incrementally heavier, rather than as one obvious failure.", "codes": ["DB-CACHE-001"]}], "autos": [], "inValidation": 0}} />
