Skip to main contentSkip to user menuSkip to navigation

Neo4j

Master Neo4j: graph database modeling, Cypher queries, and building knowledge graph applications.

40 min readIntermediate
Not Started
Loading...

What is Neo4j?

Neo4j is a transactional graph database that stores business entities as nodes and their connections as typed relationships. Cypher queries describe the pattern to find, such as an account that transferred money to another account owned by the same device.

Neo4j matters when the useful answer depends on following connections, such as an account that sent money to another account controlled by the same device. A relational database can represent the same facts, but repeated joins become awkward when a path has variable depth, several relationship types, or many possible branches.

The core invariant is a relationship connects two existing nodes, and every committed transaction satisfies the graph's declared constraints. Graph storage makes navigation direct; it does not make an unbounded search cheap.

New to databases? Start with Database Fundamentals for records, indexes, transactions, and replication.

Read the property graph as connected facts

A property graph is a data model made from nodes, relationships, labels, and properties. Each element has one specific job.

Things with identity

Nodes

An Account, Person, or Device node represents an entity that can participate in many facts. A stable domain identifier lets the application find the same entity again.

Typed connections

Relationships

(:Account)-[:SENT_TO]->(:Account) stores a named, directed fact. A relationship can carry properties such as at, amount, or role when they describe that connection.

Roles and entry points

Labels

Labels such as Account and Merchant classify nodes for constraints, indexes, and query planning. A node may have more than one label.

Values on facts

Properties

Properties hold scalar, temporal, spatial, or list values. Keep large blobs in object storage and place only the graph-relevant metadata in Neo4j.

Index-free adjacency needs a precise interpretation

After Neo4j locates a starting node, it can follow that node's stored relationships without performing a foreign-key join for every hop. The work still grows with the number of relationships inspected, the number of paths produced, and whether the needed pages are cached. A node with millions of relationships can remain a hotspot.

Choose Neo4j for a path-shaped workload

A path-shaped workload asks how entities are connected, not only which records match a filter. The query shape, consistency boundary, and operational constraints should drive the database choice.

Connections are the answer

Strong fit

Fraud rings, identity resolution, recommendations, network dependencies, authorization paths, and knowledge graphs repeatedly traverse several relationship types.

Mixed access patterns

Possible fit

Catalogs and customer views may benefit from graph traversal while orders, ledgers, or large aggregates remain in systems optimized for those access paths.

Connections add little

Weak fit

Append-only events, wide scans, simple key lookups, blob storage, and high-volume time-series aggregation usually have clearer primary stores.

Validate the decision with representative questions

  • Name the starting identity, relationship types, maximum useful depth, and result size for each important query.
  • Measure degree distribution, not only average degree. A few supernodes can dominate latency and memory even when the average looks safe.
  • Decide which facts Neo4j owns. If another database remains authoritative, define an idempotent change-data path and an acceptable synchronization delay.
  • Benchmark production-like graph shape and skew. A graph with the right node count but uniform relationships hides the hardest traversal behavior.

Model the graph from questions and invariants

Graph modeling is the process of turning domain questions into stable node identities, relationship semantics, and integrity rules. Start from the path the application must read or change, not from a mechanical copy of relational tables.

  1. 1

    Query first

    Write the question

    State the starting entity, the connection to follow, the terminal entity, and the maximum path depth. Include the latency and freshness requirement.

  2. 2

    Node boundary

    Assign identity

    Promote a value to a node when it needs independent identity, many relationships, or a lifecycle. Keep descriptive values as properties.

  3. 3

    Relationship

    Name the fact

    Use a specific relationship type and meaningful direction. Put properties on the relationship only when they describe that fact rather than either endpoint.

  4. 4

    Invariant

    Enforce and test

    Create identity constraints, load skewed sample data, run the real pattern, and inspect its plan before freezing the model into application APIs.

Use constraints as concurrency controls

A uniqueness constraint on Account.id prevents two concurrent writers from creating different nodes for the same account. MERGE describes the pattern to match or create, but a constraint is what makes domain identity unambiguous under concurrency. Prefer merging one constrained node at a time before creating relationships between bound nodes.

Model identity and a bounded recommendation pattern

Run the standalone example with node content/entries/technology/neo4j/code/model-and-query.mjs. It checks a small in-memory graph without a database, then prints the parameterized Cypher that a Neo4j driver should execute.

Start selective and bound every traversal

Traversal budgeting is a rough estimate of how many relationships a pattern may inspect before filters and deduplication finish. It exposes the most important query controls: anchor cardinality, degree, path depth, and predicates applied while expanding.

Start as close to 1 as possible

Anchor rows

Use a label plus indexed or constrained identity

degree x pass rate

Branching

Measure percentiles and supernodes, not only the mean

Always set a useful maximum

Depth

One extra hop can multiply the search frontier

EXPLAIN, then PROFILE

Evidence

Compare estimated rows, actual rows, DB hits, and memory

Loading the traversal model...

The lab is a planning envelope, not a Neo4j benchmark. Cycles, repeated paths, planner operators, cache state, runtime choice, and data skew change real work. Use it to detect a dangerous query shape, then prove the plan against representative data.

Estimate a traversal envelope from the command line

Run node content/entries/technology/neo4j/code/estimate-traversal.mjs 1 20 3 100. The four arguments are anchor rows, average degree, maximum hops, and the percentage of relationships that pass an expansion-time predicate.

Read a Cypher plan in order

  1. Prefix a query with EXPLAIN to inspect estimated operators without executing it.
  2. Confirm the plan begins with a node index seek or another intentionally small anchor, rather than a broad label scan.
  3. Trace estimated row growth through each expand, join, aggregation, sort, or shortest path operator.
  4. Use PROFILE only on safe, bounded queries because it executes the query and adds measurement overhead. Compare estimated rows with actual rows and inspect DB hits.
  5. Change one model, predicate, or index decision at a time and retain before-and-after plans with the representative parameters.

Keep transaction retries safe

A Neo4j transaction is an atomic unit of reads and writes. The official drivers can route read and write transaction functions and retry transient failures, so the callback may run more than once even though one successful database transaction commits.

Build the write boundary deliberately

  • Pass values as query parameters; do not build Cypher by concatenating user input.
  • Put all graph changes that protect one business invariant in the same transaction.
  • Make retried callbacks idempotent. Do not send email, charge a card, or mutate shared process state inside a callback that the driver may execute again.
  • Read or consume results inside the transaction function instead of returning a live result object after the transaction closes.
  • Use stable domain keys and constraints before MERGE; a broad MERGE pattern can create more of the graph than intended.
  • Bound transaction time, result size, and memory. Large batch imports should use measured chunks and restartable checkpoints.

executeRead and executeWrite are routing declarations, not authorization controls. Database roles and privileges must still prevent an application identity from changing data it should only read.

Size heap, page cache, and native memory separately

Neo4j memory is an operating envelope, not one cache setting. The page cache holds graph store and native index pages; JVM heap holds query, transaction, and object state; the operating system and native allocations also need explicit headroom.

Store and native indexes

Page cache

Cache the repeatedly traversed working set where practical. Watch page faults and hit behavior after restart, topology movement, and workload shifts.

Transactions and queries

JVM heap

Heap must absorb concurrent query state and transaction changes without disruptive garbage collection. One unbounded query can still consume a dangerous share.

Runtime headroom

Native and OS

Network buffers, JVM overhead, plugins, vector indexes, and the operating system need memory outside the configured heap and page cache.

Latency and recovery

Storage

Fast durable storage affects page faults, checkpoints, transaction logs, backup, and recovery. Memory cannot compensate for an untested storage boundary.

Start with neo4j-admin server memory-recommendation, explicitly configure heap and page cache for self-managed deployments, then tune from measurements. Track query latency and timeouts, transaction memory, heap and GC pauses, page cache faults, checkpoint duration, disk latency, and free space together.

Route around failures without weakening consistency

A Neo4j cluster separates consensus-bearing primaries from asynchronously replicated secondaries. One primary is elected writer for each database; secondaries add read capacity but do not join the commit quorum.

Use the scenarios below to trace normal writes, scaled reads, read-after-write, leader failure, and majority loss. Select a component to inspect its responsibility.

Know what each copy can promise

  • Three primaries can keep writes available after one primary fails because the two remaining copies still form a majority. A second failure removes write quorum.
  • Secondaries pull transaction logs asynchronously and scale read-only work. They can lag and do not increase write fault tolerance.
  • Routing drivers discover readers and the current writer when the application uses a routing URI. Directly pinning all work to one server defeats that behavior.
  • Bookmarks carry causal position between dependent transactions. Use them when a read must observe a prior write; unnecessary cross-session bookmark dependencies add waiting and coordination.
  • Replicas are not backups. They can copy an accidental delete or corrupt logical change. Keep independent backups and prove restore time and recovered state.

Operate the graph from user-visible objectives

Production operations connect graph-specific signals to latency, correctness, availability, and recoverability. A healthy process is not enough if a traversal is silently expanding millions of paths or a cluster has lost write quorum.

Observe one query from admission to durable state

Each stage needs a limit, a signal, and an owner.

Admission

Driver pool

Bound sessions and concurrent transactions, set acquisition and transaction timeouts, and distinguish pool wait from server execution time.

Query work

Planner and runtime

Capture query fingerprints, latency percentiles, rows, DB hits, memory, timeouts, and plan changes for important patterns.

Data path

Store and cache

Watch page cache faults, disk latency, checkpoint pressure, transaction logs, store growth, and hotspots in node degree.

Authority

Cluster

Monitor writer identity, primary health, replication progress, elections, routing errors, and whether a majority remains available.

Proof

Recovery

Run scheduled backups, validate artifacts, restore into an isolated environment, and measure actual RPO, RTO, permissions, constraints, and application-level integrity.

Review before production

  • Constraints enforce every domain identity relied on by MERGE and ingestion.
  • Critical queries have representative EXPLAIN and PROFILE evidence, bounded path depth, realistic result limits, and tests against high-degree nodes.
  • Driver pools, transaction retries, timeouts, and backpressure are measured under peak concurrency and during leader changes.
  • Least-privilege roles, encrypted client and cluster traffic, credential rotation, and audit requirements match the threat model.
  • Memory leaves room for page cache, heap, native allocations, the operating system, maintenance, and failover load.
  • Backup restore and cluster failover exercises prove the recovery objectives; they are not inferred from replication status.

Keep the final decision explicit

Neo4j earns its place when bounded traversal is a primary access path and the team can operate a graph-specific consistency and memory model. Keep another store authoritative when the graph is only a derived projection, and define synchronization behavior as part of the product contract.

Correct abstraction

Model for paths

Name identities and relationships from real questions. Protect identity with constraints and treat high-degree nodes as a deliberate modeling decision.

Predictable work

Budget expansion

Seek a selective anchor, specify relationship types, prune during traversal, cap depth, limit results, and verify the physical plan.

Production ownership

Prove recovery

Use routing and bookmarks for the required consistency, monitor quorum and lag, and restore independent backups on a schedule.

No quiz questions available
Could not load questions file
Spotted an issue or have a better explanation? This page is open source.Edit on GitHub·Suggest an improvement