envoyproxy/envoy
Dynamic modules
Dynamic modules are Envoy's native (non-Wasm) extension mechanism for code that loads from a .so / .dylib at startup. They are designed for high-performance plugins written in Rust, Go, or C — same language flexibility as Wasm, but without the sandbox and at native speed. Implementation in source/extensions/dynamic_modules/.
Why dynamic modules?
- Native performance. No Wasm interpreter, no ABI marshalling. The module is just a
dlopen'd shared object that calls back into Envoy via a stable C ABI. - No bazel for plugin authors. Build the
.sowithcargo/go build/cmakeand ship it independently of Envoy. - Multi-language. Anything that produces a shared library and respects the C ABI can be a module — Rust and Go are the canonical choices.
- Newer than Wasm. Adopted in 2024–2025; the ABI is still stabilising.
Where dynamic modules plug in
| Concern | Path |
|---|---|
| HTTP filter | source/extensions/filters/http/dynamic_modules/ |
| Network filter | source/extensions/filters/network/dynamic_modules/ |
| Access logger | source/extensions/access_loggers/dynamic_modules/ |
| Tracer | source/extensions/tracers/dynamic_modules/ |
| Load balancer | source/extensions/load_balancing_policies/dynamic_modules/ |
ABI
The host ABI lives in source/extensions/dynamic_modules/abi/. It's a flat C header. The host exposes function pointers like:
envoy_dynamic_module_callback_http_get_request_headerenvoy_dynamic_module_callback_http_set_request_headerenvoy_dynamic_module_callback_http_send_responseenvoy_dynamic_module_callback_http_dispatchenvoy_dynamic_module_callback_logenvoy_dynamic_module_callback_define_counter/record_counter
The module exports symbols like:
envoy_dynamic_module_on_program_initenvoy_dynamic_module_on_http_filter_config_newenvoy_dynamic_module_on_http_filter_request_headersenvoy_dynamic_module_on_http_filter_response_headers
The host runtime bookkeeping is in dynamic_modules.cc; the implementation of host functions is in abi_impl.cc.
SDKs
Authoring a module from scratch against the C ABI is possible but verbose; the recommended path is via SDKs in source/extensions/dynamic_modules/sdk/:
- Rust SDK (
sdk/rust/) — the most polished SDK; idiomatic Rust traits for filter callbacks. - Go SDK (
sdk/go/) — uses cgo to bridge. - C SDK (
sdk/c/) — direct.
There is also a STYLE.md documenting Envoy-specific conventions for module authors.
Loading
http_filters:
- name: my_dyn_module
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.http.dynamic_modules.v3.DynamicModuleFilter
dynamic_module_config:
name: my_module
do_not_close: false
filter_name: my_filter
filter_config: '{"...":"..."}'The host:
- Locates the
.so(default search path is configurable). dlopenit (or returns a cached handle if already loaded).- Calls
envoy_dynamic_module_on_program_initonce. - Calls
envoy_dynamic_module_on_http_filter_config_newfor the typed config. - Per-stream callbacks fire from the filter manager.
Built-in modules
source/extensions/dynamic_modules/builtin_extensions/ holds modules that ship with Envoy itself — they exercise the ABI and serve as reference implementations.
Background fetch manager
background_fetch_manager.{h,cc} lets modules schedule periodic background tasks against the dispatcher. Used for things like long-lived JWKS / certificate refresh.
ABI stability
The ABI is versioned. Any breaking change requires bumping the version constant; the host refuses to load a module with an incompatible version. Additive changes are versioned via "feature flags" exposed through envoy_dynamic_module_supports.
When to use dynamic modules over Wasm
| Concern | Wasm | Dynamic modules |
|---|---|---|
| Sandbox | Yes | No (native code) |
| Cold latency | Higher | Native |
| ABI maturity | Mature (proxy-wasm) | Newer |
| Hot reload | Yes (ECDS) | Limited (process restart) |
| Multiplatform | Yes (cross-compiled .wasm) |
Per-arch .so |
| Memory access | Sandboxed; slow for big buffers | Direct |
For untrusted plugins or hot-reload: prefer Wasm. For trusted high-throughput in-house extensions: prefer dynamic modules.
See also
- Wasm — the sandboxed alternative.
- HTTP filters — the most common consumer.
- Filter manager — the host of per-stream module callbacks.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.