Plugin System Timeouts#
Dify's plugin system has four distinct timeout layers that stack on top of each other. A slow LLM call will traverse all of them. Understanding each layer is necessary when tuning or debugging timeout errors.
Dify API worker
β
ββ[1] PLUGIN_DAEMON_TIMEOUT (API β Daemon HTTP)
β default 600 s
β
βββΊ Plugin Daemon (Go process)
β
ββ[2] PLUGIN_MAX_EXECUTION_TIMEOUT (Daemon execution limit)
β default 600 s
β
βββΊ Plugin Python process
β
ββ[3] OpenAI SDK / httpx Timeout (Daemon β LLM service)
β 315 s total, 300 s read, 10 s write, 5 s connect
β
ββ[4] requests.post timeout (text_embedding / rerank)
60 s
Layer 1 β API-to-Daemon HTTP Timeout (PLUGIN_DAEMON_TIMEOUT)#
All plugin invocations from the Dify API go through BasePluginClient in api/core/plugin/impl/base.py, which makes synchronous blocking httpx calls to the plugin daemon. Both _request() and _stream_request() obtain the timeout value by calling _get_plugin_daemon_request_timeout(), which returns either a request-scoped override (if set) or the global plugin_daemon_request_timeout.
The global timeout is resolved at module import time from PLUGIN_DAEMON_TIMEOUT:
| Env var | Default | Effect |
|---|---|---|
PLUGIN_DAEMON_TIMEOUT | 600.0 s | Maximum time any API worker will wait for a plugin daemon response (global fallback) |
Configured in PluginConfig (api/configs/feature/__init__.py). Set to None to disable the timeout entirely.
Request-scoped overrides: Use the use_plugin_daemon_request_timeout(timeout_seconds) context manager to temporarily apply a shorter timeout for specific code paths without changing the global default. For example, suggested question generation wraps its LLM call with use_plugin_daemon_request_timeout(30.0) to prevent reasoning models from causing excessive latency β the 30-second override applies only to that invocation, and the global 600-second default remains in effect for all other plugin requests.
Worker impact: Both
_request()and_stream_request()block the Gunicorn worker thread for the entire duration β including all upstream LLM inference time. Keep this value in mind when sizingSERVER_WORKER_AMOUNT.
Layer 2 β Daemon Execution Timeout (PLUGIN_MAX_EXECUTION_TIMEOUT)#
The plugin daemon (a separate Go binary) enforces its own per-invocation time cap via the environment variable PLUGIN_MAX_EXECUTION_TIMEOUT. This is a daemon-side setting, not present in the Dify API's Python config. In integration tests it is set to 600 seconds .
This timeout fires inside the daemon before the API-side PLUGIN_DAEMON_TIMEOUT would, when the plugin execution itself exceeds the limit. Both values default to 600 s, so they are effectively equivalent in the default configuration; lower PLUGIN_MAX_EXECUTION_TIMEOUT in the daemon if you want the daemon to abort plugin execution faster than the API-side HTTP timeout.
Layer 3 β OpenAI SDK HTTP Client Timeout (LLM Plugins)#
When a plugin calls an OpenAI-compatible LLM, the Python plugin process uses the openai SDK. The _CommonOpenAI._to_credential_kwargs() method in models/openai_api_compatible/models/common_openai.py hard-codes the following timeout for all requests made via the OpenAI Python client:
| Dimension | Value |
|---|---|
Total (Timeout outer) | 315 s |
| Read | 300 s |
| Write | 10 s |
| Connect | 5 s |
# common_openai.py line 26
"timeout": Timeout(315.0, read=300.0, write=10.0, connect=5.0)
These values are not configurable via environment variables β they are baked into the plugin source. The validation path in the OpenAILargeLanguageModel subclass uses a separate shorter timeout: _VALIDATE_TIMEOUT = (10, 300) β a (connect, read) tuple for requests.post .
Layer 4 β requests.post Timeout (Text Embedding & Rerank)#
The text embedding and rerank model implementations do not use the openai SDK for their main invocation paths; they call the upstream endpoint directly via requests.post. Both use a fixed timeout=60 (60 seconds):
- Text embedding (
text_embedding.py):requests.post(..., timeout=60) - Rerank (
rerank.py):requests.post(..., timeout=60)for both text and multimodal paths
Like Layer 3, these are hard-coded in plugin source and cannot be overridden via environment variables.
Configuration Reference#
| Variable | Where set | Default | Scope |
|---|---|---|---|
PLUGIN_DAEMON_TIMEOUT | Dify API .env | 600.0 s | API β Daemon HTTP |
PLUGIN_MAX_EXECUTION_TIMEOUT | Plugin daemon container env | 600 s | Daemon plugin execution |
OpenAI SDK Timeout(315.0, ...) | Hard-coded in common_openai.py | 315 s total / 300 s read | Daemon β LLM (LLM model type) |
requests.post(timeout=60) | Hard-coded in text_embedding.py, rerank.py | 60 s | Daemon β LLM (embedding/rerank) |
Key files:
api/configs/feature/__init__.pyβPluginConfigwithPLUGIN_DAEMON_TIMEOUTapi/core/plugin/impl/base.pyβ timeout resolution and sharedhttpx.Clientmodels/openai_api_compatible/models/common_openai.pyβ OpenAI SDK timeout kwargsmodels/openai_api_compatible/models/llm/llm.pyβ validation-path timeoutmodels/openai_api_compatible/models/text_embedding/text_embedding.pyβ embeddingrequests.posttimeoutmodels/openai_api_compatible/models/rerank/rerank.pyβ rerankrequests.posttimeout