# Many contexts, one engine

> Run independent tasks in parallel, call across languages on one thread, and reuse compiled code through a shared engine.

<!-- Generated by `bun run sync:architecture` from architecture/threading/public.md; never edit it by hand. -->

[![Interactive tour: Many contexts, one engine](https://elide.help/assets/architecture/threading-light.jpg)![Interactive tour: Many contexts, one engine](https://elide.help/assets/architecture/threading-dark.jpg)](https://deepdive.elide.dev/threading?source=docs&from=/docs/architecture/threading)

[Learn more](https://deepdive.elide.dev/threading?source=docs&from=/docs/architecture/threading)

Run independent tasks in parallel, call across languages on one thread, and reuse compiled code through a shared engine.

Each execution context owns its guest language state. Multiple contexts run on a shared Truffle engine.[1][2]

## Contexts support multiple languages

JavaScript and Python can exchange values within one context. Host access and guest thread permissions are configured at the context level.[1][2]

A context running JavaScript admits one executing thread at a time. Python-only contexts support multiple threads, with a per-context GIL serializing Python execution and normally releasing around foreign calls.[2][3]

## A bounded pool of reusable contexts

Elide schedules one active task per pooled context, with a configurable bound that defaults to processor count. Reused contexts retain application state. Tasks that require a particular context return to it.[2][4]

## Callbacks return to their context

I/O and worker completions post work to the context's event loop. Callbacks run on the thread holding that context and can call another language without a thread handoff.[2][5]

For example, a server can distribute requests across pooled contexts. Within a request, a Python handler can call a JavaScript renderer and use its result directly.[1][2][4]

## Dedicated workers for CPU-bound tasks

Each worker owns a dedicated host thread and a fresh context on the shared engine. Workers exchange messages through structured clone.[6]

## Shared engine with JIT caching

The shared engine reuses eligible parsed and compiled code across contexts. GraalVM's Auxiliary Engine Cache can persist this code across program starts.[2][7]

## Sources

1. [Elide runtime](https://github.com/elide-dev/elide/blob/d8ac9d068726e614e0360c2c23a1ae1dd83f431e/packages/base/main/dev/elide/runtime/ElideRuntime.kt) — shared engines, context configuration and guest capabilities.
2. [Polyglot Context](https://www.graalvm.org/truffle/javadoc/org/graalvm/polyglot/Context.html) and [Engine](https://www.graalvm.org/truffle/javadoc/org/graalvm/polyglot/Engine.html) — context access, language interoperation and code reuse.
3. [GraalJS multithreading](https://www.graalvm.org/javascript/docs/#multithreading) and [GraalPy multithreading](https://github.com/oracle/graalpython/blob/master/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java) — language-specific threading behavior.
4. [Elide context-aware executor](https://github.com/elide-dev/elide/blob/d8ac9d068726e614e0360c2c23a1ae1dd83f431e/packages/base/main/dev/elide/runtime/execution/ContextAwareExecutorBase.kt) — pooling, task scheduling and context ownership.
5. [Elide event loop](https://github.com/elide-dev/elide/blob/d8ac9d068726e614e0360c2c23a1ae1dd83f431e/packages/base/main/dev/elide/runtime/truffle/EventLoop.kt) — callback execution and external completions.
6. [Elide workers](https://github.com/elide-dev/elide/blob/d8ac9d068726e614e0360c2c23a1ae1dd83f431e/packages/base/main/dev/elide/lang/javascript/node/worker_threads/NodeWorkers.kt) — worker contexts, host threads and parent notifications.
7. [Auxiliary Engine Caching](https://www.graalvm.org/latest/graalvm-as-a-platform/language-implementation-framework/AuxiliaryEngineCachingEnterprise/) — persisting code for reuse across runs of the same native executable.
