Gremlin
Updated: May 22, 2026Categories: Query
Printed from:
Gremlin Cheatsheet: Master Graph Traversals with Apache TinkerPop
1. Connection and Basic Setup
Gremlin Console
groovy
1234567// Launch Gremlin Console (Apache TinkerPop 3.7.x) bin/gremlin.sh // Create an in-memory graph instance graph = TinkerGraph.open() g = traversal().withEmbedded(graph) // preferred over graph.traversal()
Driver Connections
Python
12345678# Python (gremlinpython 3.7.x)
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
from gremlin_python.process.anonymous_traversal import traversal
g = traversal().withRemote(
DriverRemoteConnection('ws://localhost:8182/gremlin', 'g')
)
Java
1234567// Java (tinkerpop 3.7.x)
import static org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource.traversal;
import org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteConnection;
GraphTraversalSource g = traversal()
.withRemote(DriverRemoteConnection.using("localhost", 8182, "g"));
JavaScript
123456789// JavaScript (gremlin 3.7.x, Node.js)
const gremlin = require('gremlin');
const { DriverRemoteConnection } = gremlin.driver;
const { traversal } = gremlin.process.AnonymousTraversalSource;
const g = traversal().withRemote(
new DriverRemoteConnection('ws://localhost:8182/gremlin')
);
2. Graph Structure Basics
Vertices and Edges
groovy
1234567891011121314// Create vertices (iterate() ensures execution in remote sessions) alice = g.addV('Person').property('name', 'Alice').next() corp = g.addV('Company').property('name', 'TinkerCorp').next() // Create edges using anonymous traversals with V() inside the step g.V().has('Person', 'name', 'Alice') .addE('works_at') .to(__.V().has('Company', 'name', 'TinkerCorp')) .iterate() // mergeV / mergeE (3.6+) for idempotent upserts g.mergeV([(T.label): 'Person', name: 'Alice']) g.mergeE([(T.label): 'knows', (Direction.OUT): aliceId, (Direction.IN): bobId])
Properties
groovy
12345678910// Add/Modify properties g.V().has('Person', 'name', 'Alice') .property('age', 30) .property('city', 'San Francisco') .iterate() // Retrieve properties g.V().has('name', 'Alice').valueMap(true) // include id/label g.V().has('name', 'Alice').elementMap() // 3.4+ flat map incl. id/label
3. Gremlin Traversal Language Fundamentals
Basic Traversal Pattern
groovy
1234567// Pipeline-based traversals are lazy; terminal steps trigger execution g.V() // Start with all vertices .hasLabel('User') // Filter by label (preferred over has('type', ...)) .out('friends') // Traverse outgoing edges labeled 'friends' .values('name') // Extract name property .toList() // Terminal step
Terminal steps: next(), toList(), toSet(), toBulkSet(), iterate(), hasNext().
4. Basic Traversal Steps
Vertex and Edge Traversals
groovy
1234567g.V() // All vertices g.E() // All edges g.V().out('knows') // Outgoing neighbors via 'knows' edges g.V().in('knows') // Incoming neighbors g.V().both('knows') // Both directions g.V().outE('knows').inV() // Edge-then-vertex variant
5. Filtering and Predicates
Filtering
groovy
1234567891011import static org.apache.tinkerpop.gremlin.process.traversal.P.* import static org.apache.tinkerpop.gremlin.process.traversal.TextP.* g.V().has('age', gt(25)) g.V().has('name', containing('John')) // TextP, 3.4+ g.V().has('name', startingWith('Al')) g.V().has('name', regex('^A.*')) // TextP, 3.6+ // where() with anonymous traversal g.V().where(__.out('knows').count().is(gt(2)))
Predicate Reference
groovy
1234567// Comparison (P) eq, neq, gt, gte, lt, lte, inside, outside, between, within, without // Text (TextP, 3.4+; regex/notRegex added in 3.6) startingWith, notStartingWith, endingWith, notEndingWith, containing, notContaining, regex, notRegex
6. Transformation Steps
Mapping and Selection
groovy
123456789101112// Map transformation (anonymous traversal) g.V().map(__.values('name')) // Select previously labeled steps g.V().as('v').out('knows').as('friend').select('v', 'friend') // Project multiple values (use anonymous traversal in by()) g.V().hasLabel('Person') .project('name', 'friends') .by('name') .by(__.out('knows').count())
7. Aggregation and Grouping
Counting and Grouping
groovy
12345678910g.V().count() g.V().group().by(label).by(count()) // Fold/unfold g.V().fold() g.V().group().by(label).by(fold()) // mean / sum / min / max g.V().hasLabel('Person').values('age').mean()
8. Path Operations
Tracking Traversal Paths
groovy
12345678910g.V().out().path() g.V().out().path().by('name') // Bounded repeat with path output g.V().repeat(out()).times(2).path() // shortestPath() step (3.5+, via withComputer()) g.withComputer().V().has('name', 'Alice') .shortestPath().with(ShortestPath.target, __.has('name', 'Bob'))
9. Mutations
Graph Modifications
groovy
1234567891011121314g.addV('Person').property('name', 'Bob').iterate() g.V().has('Person', 'name', 'Alice') .addE('knows') .to(__.V().has('Person', 'name', 'Bob')) .iterate() // Drop elements (properties, vertices, or edges) g.V().has('Person', 'name', 'Bob').drop().iterate() // Idempotent upserts (3.6+) g.mergeV([(T.label): 'Person', name: 'Carol']) .option(Merge.onCreate, [createdAt: System.currentTimeMillis()])
10. Subgraph and Branching
Conditional Traversals
groovy
1234567891011121314// choose() for if/then, branch() for fan-out g.V().choose(__.hasLabel('User'), __.out('friends'), __.in('works_at')) // branch() with options g.V().branch(__.label()) .option('User', __.out('friends')) .option('Company', __.in('works_at')) // Subgraph extraction (collects matching edges into a side-effect graph) g.V().has('age', gt(25)).outE().subgraph('adultNetwork') .cap('adultNetwork')
11. Performance Optimization
Efficient Traversals
groovy
1234567891011121314151617// Direct id-based lookups beat full scans g.V(userId) // Use indexed has() with label + property when possible g.V().has('Person', 'email', 'alice@example.com') // Limit results early g.V().hasLabel('Person').limit(100).values('name') // local() restricts a sub-traversal to each incoming element g.V().local(__.values('name').limit(5)) // Use barrier() to batch network/IO heavy steps g.V().hasLabel('Person').barrier(1000).out('knows') // Prefer elementMap()/valueMap() over multiple property() calls
12. Graph Database Integration
TinkerPop-Enabled Databases
- Apache TinkerGraph (reference impl, in-memory)
- JanusGraph
- Amazon Neptune
- Azure Cosmos DB (Gremlin API)
- ArangoDB
- OrientDB
- Hugegraph
- DataStax (HGE / DSE Graph — DSE Graph is end-of-life in DSE 6.9; new projects should consider alternatives)
Neo4j's native Cypher is the recommended language for Neo4j; the historical
neo4j-gremlinplugin is no longer maintained alongside current TinkerPop releases.
13. Common Graph Algorithms
Path and Connectivity
groovy
123456789101112// Shortest path via repeat/until (works on any TinkerPop provider) g.V().has('name', 'Alice') .repeat(both().simplePath()) .until(has('name', 'Bob').or().loops().is(6)) .has('name', 'Bob') .path().limit(1) // PageRank / Peer Pressure / Connected Components (OLAP, via withComputer()) g.withComputer().V().pageRank().by('pageRank').values('pageRank') g.withComputer().V().peerPressure().by('cluster').values('cluster') g.withComputer().V().connectedComponent().values('gremlin.connectedComponentVertexProgram.component')
14. Best Practices
- Use vertex/edge IDs (
g.V(id)) for direct lookups. - Always pair
has(label, key, value)so providers can hit composite indexes. - Terminate mutating traversals with
iterate()to ensure execution. - Prefer
elementMap()over chained property reads. - Use
mergeV/mergeE(3.6+) for upserts instead of hand-rolledcoalescepatterns. - Wrap long-running OLTP traversals with
limit()andbarrier(); reservewithComputer()for OLAP analytics. - Use
__(anonymous traversal spawn) consistently inside steps likewhere,by,choose,repeat. - Keep traversals bytecode-friendly — avoid mixing lambdas/closures so they can run on any GLV.
Anti-Patterns
- Full graph scans (
g.V().has('type', ...)) instead ofhasLabel(...). - Forgetting
iterate()on mutations in remote sessions (changes silently skipped). - Lambda steps (
map{ it -> ... }) — break cross-language and remote execution. - Building deep paths without
simplePath()or atimes()/until()bound. - Using removed
tree()-style orOrder.incr/decrconstants (replaced byOrder.asc/Order.descsince 3.4).
Additional Resources
- Apache TinkerPop 3.7 Reference Documentation
- TinkerPop Recipes (common traversal patterns)
- Practical Gremlin by Kelvin R. Lawrence (free online book)
- Gremlin Language Variants (GLV) docs for Python, JavaScript, Java, .NET, Go
Continue Learning
Discover more cheatsheets to boost your productivity