TensorFlow
multiple sessions
graphs
machine learning
deep learning

Multiple sessions and graphs in Tensorflow in the same process

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Using multiple TensorFlow graphs and sessions in one process is mostly a TensorFlow 1.x concern, but it still matters when maintaining older training code, serving stacks, or research experiments. The key idea is simple: a Session executes operations from one Graph, and you have to be explicit about which graph owns which ops.

How Graphs and Sessions Fit Together

In TensorFlow 1.x, building a model and running a model are separate steps. You first add operations to a computation graph, then execute those operations inside a session.

That separation makes it possible to keep several graphs alive in the same Python process. Each graph can hold a different model, placeholder set, or variable namespace. Each session can then execute exactly one graph at a time.

A minimal example looks like this:

python
1import tensorflow as tf
2
3tf.compat.v1.disable_eager_execution()
4
5graph_a = tf.Graph()
6with graph_a.as_default():
7    x = tf.compat.v1.placeholder(tf.float32, name="x")
8    y = x * 2.0
9
10graph_b = tf.Graph()
11with graph_b.as_default():
12    a = tf.compat.v1.placeholder(tf.float32, name="a")
13    b = a + 10.0
14
15with tf.compat.v1.Session(graph=graph_a) as sess_a:
16    print(sess_a.run(y, feed_dict={x: 3.0}))
17
18with tf.compat.v1.Session(graph=graph_b) as sess_b:
19    print(sess_b.run(b, feed_dict={a: 5.0}))

The important detail is the graph= argument when creating the session. Without it, TensorFlow uses the current default graph, which is often the source of confusing bugs.

Running Multiple Models in the Same Process

A common use case is loading separate models for separate tasks, such as one graph for classification and another for preprocessing or scoring.

python
1import tensorflow as tf
2
3tf.compat.v1.disable_eager_execution()
4
5classifier_graph = tf.Graph()
6with classifier_graph.as_default():
7    features = tf.compat.v1.placeholder(tf.float32, shape=[None, 2])
8    logits = tf.keras.layers.Dense(1)(features)
9    init_classifier = tf.compat.v1.global_variables_initializer()
10
11scorer_graph = tf.Graph()
12with scorer_graph.as_default():
13    values = tf.compat.v1.placeholder(tf.float32, shape=[None])
14    score = tf.reduce_mean(values)
15    init_scorer = tf.compat.v1.global_variables_initializer()
16
17with tf.compat.v1.Session(graph=classifier_graph) as classifier_sess, \
18     tf.compat.v1.Session(graph=scorer_graph) as scorer_sess:
19    classifier_sess.run(init_classifier)
20    scorer_sess.run(init_scorer)
21
22    print(scorer_sess.run(score, feed_dict={values: [1.0, 2.0, 3.0]}))

This pattern keeps the variables, placeholders, and ops isolated. One graph does not accidentally reuse names or state from the other unless you intentionally share something outside TensorFlow.

What You Can and Cannot Share

Graphs and sessions in the same process can share Python memory, files, and NumPy arrays. They do not automatically share TensorFlow tensors or variables across graph boundaries.

If you need data from one session in another, extract it as a normal Python or NumPy value and feed it into the second graph.

python
1import numpy as np
2import tensorflow as tf
3
4tf.compat.v1.disable_eager_execution()
5
6source_graph = tf.Graph()
7with source_graph.as_default():
8    x = tf.compat.v1.placeholder(tf.float32)
9    doubled = x * 2.0
10
11target_graph = tf.Graph()
12with target_graph.as_default():
13    y = tf.compat.v1.placeholder(tf.float32)
14    shifted = y + 1.0
15
16with tf.compat.v1.Session(graph=source_graph) as source_sess, \
17     tf.compat.v1.Session(graph=target_graph) as target_sess:
18    value = source_sess.run(doubled, feed_dict={x: 4.0})
19    result = target_sess.run(shifted, feed_dict={y: np.float32(value)})
20    print(result)

That may feel clumsy, but it is the correct mental model. Session boundaries are execution boundaries.

Managing the Default Graph Safely

Many old TensorFlow bugs come from building ops into the wrong default graph. The safest habit is to always wrap model construction in with graph.as_default(): and always create sessions with Session(graph=that_graph).

Avoid relying on tf.compat.v1.get_default_graph() in larger applications unless you really control the entire process. Test code, imported modules, and notebook cells often mutate the default graph in ways that are hard to track.

If you truly need isolated experiments, tf.compat.v1.reset_default_graph() can help in short scripts, but it is not a replacement for explicit graph ownership in long-running services.

How This Changes in TensorFlow 2.x

TensorFlow 2 uses eager execution by default, so explicit Session objects are no longer part of normal model code. If you are writing new code, you usually do not want multiple sessions at all.

Instead, you would structure work around:

  • separate tf.keras.Model objects
  • separate tf.function traces when needed
  • explicit Python objects for state isolation

Still, understanding graphs and sessions is valuable because many migration guides, legacy repositories, and production inference wrappers still depend on tf.compat.v1.

Common Pitfalls

The most common mistake is creating operations in one graph and trying to run them in a session bound to another graph. TensorFlow will usually fail with a graph ownership error.

Another problem is forgetting to initialize variables inside each session. Initializing one graph does nothing for another graph.

Default-graph leakage is also common in notebooks and long scripts. If graph ownership is implicit, it becomes very hard to see where an op was created.

Finally, multiple sessions do not automatically improve performance. They add isolation, not magical parallel speedups. Use them when you need separate graph state, not as a default optimization.

Summary

  • In TensorFlow 1.x, a session executes exactly one graph.
  • Multiple graphs and sessions can coexist in the same process if you bind them explicitly.
  • Share data between sessions through Python or NumPy values, not by reusing tensors across graphs.
  • Use with graph.as_default(): and Session(graph=graph) to avoid default-graph bugs.
  • In TensorFlow 2.x, prefer eager execution and separate model objects unless you are maintaining legacy code.

Course illustration
Course illustration

All Rights Reserved.