@@ -61,7 +61,7 @@ Gremlin Javascript now supports Node 22 and 24 alongside Node 20.
6161
6262Gremlin Go has been upgraded to Go version 1.25.
6363
64- ==== Python Set Deserialization with Non-Hashable Elements
64+ ==== Python Set-to-List Fallback
6565
6666Traversals that return a `Set` containing non-hashable items (such as `Dictionary`, `Set`, or `List`) previously caused
6767a `TypeError` during deserialization in Gremlin-Python. These results are now coerced to a `List` to avoid errors. This
@@ -70,10 +70,135 @@ Python hashable types manually (e.g. `dict` to `HashableDict`, `list` to `tuple`
7070
7171See: link:https://issues.apache.org/jira/browse/TINKERPOP-3232[TINKERPOP-3232]
7272
73+ ==== Remote Transaction Improvements
74+
75+ The Java driver now supports reusing existing pooled WebSocket connections for session-based requests rather than
76+ establishing a dedicated connection per session. This behavior is controlled by the `Cluster.Builder` option
77+ `reuseConnectionsForSessions`, which defaults to `false`.
78+
79+ When enabled, a `Client.SessionedChildClient` will attempt to borrow a connection from the connection pool of a standard
80+ `Client` rather than opening its own WebSocket connection. This avoids the overhead of the TCP handshake and WebSocket
81+ upgrade for each session, which can be significant when issuing many short-lived transactions.
82+
83+ [source,java]
84+ ----
85+ // Enable connection reuse for sessions
86+ Cluster cluster = Cluster.build(host)
87+ .reuseConnectionsForSessions(true)
88+ .create();
89+ ----
90+
91+ This feature was designed specifically for use with remote transactions, where sessions are short-lived and terminate
92+ after a `commit()` or `rollback()`. It should not be used for classic long-running session use cases where a session
93+ is used for purposes other than transactions such as remote console.
94+
95+ ===== Server Configuration
96+
97+ When using `reuseConnectionsForSessions`, the server should be configured to close sessions immediately after a graph
98+ operation such as commit() or rollback() completes. Without this behavior, sessions may remain open until the session
99+ timeout expires, potentially leading to a buildup of idle sessions on the server side.
100+
101+ Some remote graph providers handle this automatically and require no additional configuration. For the reference Gremlin
102+ Server, this is controlled by the `closeSessionPostGraphOp` setting, which should be set to true. Users of other graph
103+ providers should consult their provider's documentation to determine whether this behavior is enabled by default,
104+ requires explicit configuration or is unsupported.
105+
106+ [source,yaml]
107+ ----
108+ # gremlin-server.yaml
109+ closeSessionPostGraphOp: true
110+ ----
111+
112+ IMPORTANT: Failing to enable `closeSessionPostGraphOp` on the server when using `reuseConnectionsForSessions` on the
113+ client will result in sessions that are not properly cleaned up. These leaked sessions will accumulate until the
114+ configured `sessionLifetimeTimeout` is reached, consuming server resources unnecessarily.
115+
116+ ===== Performance
117+
118+ Performance was measured with an ad-hoc benchmark application. The application executes a configurable number of
119+ complete transaction lifecycles (begin, mutate, commit) and reports throughput and latency percentiles. Each transaction
120+ opens a session, submits one or more `addV()` operations, commits, and closes the session.
121+
122+ The benchmark varies the following parameters:
123+
124+ * *Concurrent clients* (`threads`): The number of threads issuing transactions simultaneously. A value of 1 means
125+ transactions are executed sequentially by a single client. Higher values simulate multiple application threads or
126+ service instances issuing transactions concurrently against the same server.
127+ * *Connection pool size* (`pool`): The number of WebSocket connections maintained in the pool when
128+ `reuseConnectionsForSessions` is enabled. When reuse is disabled, each session creates its own dedicated connection
129+ and this parameter does not apply (shown as `n/a`).
130+ * *Transaction weight* (`weight`): "light" transactions perform a single `addV()` plus commit. "heavy" transactions
131+ perform ten `addV()` operations plus commit, simulating a more substantial unit of work per transaction.
132+
133+ Tests were conducted both locally (client and server on the same machine) and remotely (client on the US west coast,
134+ server on the US east coast) to isolate the effect of network latency on connection setup overhead. Each scenario
135+ executed 1000 transactions after a warmup phase of 50 transactions.
136+
137+ *Local Results (same machine)*
138+
139+ [cols="3,1,1,1", options="header"]
140+ |=========================================================
141+ |Configuration |No-Reuse (tx/s) |Best-Reuse (tx/s) |Speedup
142+ |1 client, light |23.1 |26.7 |1.16x
143+ |8 clients, light |25.2 |28.5 |1.13x
144+ |16 clients, light |25.4 |27.9 |1.10x
145+ |1 client, heavy |26.0 |26.9 |1.03x
146+ |8 clients, heavy |26.4 |27.9 |1.06x
147+ |16 clients, heavy |25.8 |26.5 |1.03x
148+ |=========================================================
149+
150+ *Remote Results (west coast to east coast)*
151+
152+ [cols="3,1,1,1", options="header"]
153+ |=========================================================
154+ |Configuration |No-Reuse (tx/s) |Best-Reuse (tx/s) |Speedup
155+ |1 client, light |3.6 |7.6 |2.10x
156+ |8 clients, light |15.6 |23.0 |1.48x
157+ |16 clients, light |15.4 |25.3 |1.64x
158+ |1 client, heavy |1.4 |1.8 |1.26x
159+ |8 clients, heavy |9.2 |10.8 |1.17x
160+ |16 clients, heavy |14.5 |15.9 |1.10x
161+ |=========================================================
162+
163+ The "Best-Reuse" column reflects the highest throughput observed across all tested pool sizes (2, 4, and 8 connections)
164+ for each scenario.
165+
166+ The benefit of connection reuse is most pronounced in remote scenarios with light transactions. When the network
167+ round-trip cost is high and the transaction payload is small, the WebSocket connection setup overhead represents a
168+ larger proportion of the total transaction time. In the single-client remote light workload, connection reuse yielded a
169+ 2.10x throughput improvement, as the connection handshake cost dominated the per-transaction time. With 16 concurrent
170+ clients in the same remote light scenario, throughput improved from 15.4 tx/s to 25.3 tx/s (1.64x), as the connection
171+ pool amortized the setup cost across many parallel sessions.
172+
173+ As transaction weight increases, the relative benefit diminishes because the graph operations themselves become the
174+ bottleneck rather than connection setup. In the local heavy workload scenarios, the improvement was only 3-6%, as the
175+ connection overhead was already negligible relative to the cost of the graph mutations. Even in the remote heavy
176+ scenarios, the improvement ranged from 10-26%, as the ten `addV()` operations per transaction shifted the time
177+ distribution toward server-side processing.
178+
179+ In summary, `reuseConnectionsForSessions` provides the greatest benefit when:
180+
181+ * Network latency between client and server is significant (remote deployments)
182+ * Transactions are lightweight (few operations per transaction)
183+ * Many short-lived transactions are issued in sequence or concurrently
184+
185+ See: link:https://issues.apache.org/jira/browse/TINKERPOP-3213[TINKERPOP-3213]
186+
73187=== Upgrading for Providers
74188
75189==== Graph System Providers
76190
191+ ===== Session Changes
192+
193+ An option has been added to the Java GLV (`reuseConnectionsForSessions`) that allows for borrowing open WebSocket
194+ connections for sessions. This is primarily to reduce the overhead of new connection setup per session. This can lead
195+ to large performance gains in remote transaction scenarios where there are many small mutation traversals.
196+
197+ This option is disabled by default on the driver but providers may want to add an option that will allow sessions to end
198+ on the successful completion of a graph operation (commit/rollback). This will prevent a buildup of sessions if a user
199+ has enabled this option as the driver will *not* close the underlying WebSocket connection as a signal to end the
200+ session. Gremlin Server has added an option like this called `closeSessionPostGraphOp`. Remote graph providers are
201+ encouraged to add the same functionality.
77202
78203==== Graph Driver Providers
79204
0 commit comments