Workflow:Langfuse Langfuse Prompt management lifecycle
| Knowledge Sources | |
|---|---|
| Domains | LLM_Ops, Prompt_Engineering, Version_Control |
| Last Updated | 2026-02-14 05:00 GMT |
Overview
End-to-end process for creating, versioning, composing, caching, and serving LLM prompts through Langfuse's prompt management system, from authoring through SDK retrieval with dependency resolution.
Description
This workflow describes how Langfuse manages the full lifecycle of LLM prompts. Users create prompts (text or chat format) with auto-incrementing versions, labels (production, latest, custom), and tags. Prompts can reference other prompts through dependency tags, enabling composition. When SDKs fetch prompts via the public API, the system resolves all dependencies recursively, caches results in Redis, and returns the fully composed prompt. Variable substitution using mustache syntax and placeholder expansion for chat messages allow prompts to be compiled with runtime data before being sent to LLMs.
Usage
Execute this workflow when managing LLM prompts across development, staging, and production environments. This covers prompt authoring in the Langfuse UI, fetching prompts from application code via SDKs, composing complex prompts from reusable components, and compiling prompts with runtime variables before LLM calls.
Execution Steps
Step 1: Prompt Authoring and Versioning
A new prompt version is created through the tRPC API or public REST API. The system validates prompt type consistency (text or chat) with previous versions of the same name, extracts variables (mustache syntax) and placeholders, and checks for naming conflicts between variables and placeholders. The version number is auto-incremented from the latest version with the same name, and the "latest" label is automatically assigned.
Key considerations:
- Text prompts contain a single string; chat prompts contain an array of message objects
- Variable names must match the pattern [a-zA-Z][a-zA-Z_]* (letters and underscores)
- Labels follow the pattern [a-z0-9_\-.] (lowercase alphanumeric with underscore, hyphen, period)
- The "latest" label is automatically moved to the newest version
Step 2: Dependency Declaration and Graph Validation
Prompt dependency tags embedded in the prompt content are parsed using a regex pattern. Each tag specifies a child prompt by name and either version number or label. The system builds a dependency graph and validates it for circular references and excessive nesting depth (maximum 5 levels). Child prompts must be of type "text" to be embeddable.
Pseudocode:
Parse all dependency tags from prompt content For each dependency, fetch child prompt from database Validate child exists and is text type Recursively resolve child dependencies Check for circular references via seen set Enforce maximum nesting depth of 5
Key considerations:
- Dependency tag format: @@@langfusePrompt:name=<name>|version=<N>@@@ or @@@langfusePrompt:name=<name>|label=<label>@@@
- Only text-type prompts can be embedded as dependencies
- Circular dependency detection uses a visited set during graph traversal
- PromptDependency records are stored in PostgreSQL for graph tracking
Step 3: Cache Invalidation
When a prompt is created or updated, the Redis cache is locked for 30 seconds to prevent serving stale data during the transition. After the database transaction commits, all cached versions and labels for that prompt name are invalidated by deleting their Redis keys. The lock is then released, allowing fresh cache entries to be populated on the next read.
Key considerations:
- Cache lock prevents stale reads during the brief window between write and invalidation
- A key index (Redis Set) tracks all cached versions/labels per prompt name for efficient invalidation
- Legacy key formats are handled for backward compatibility
- Cache is only used when LANGFUSE_CACHE_PROMPT_ENABLED is true and Redis is available
Step 4: Prompt Retrieval and Resolution
When an SDK requests a prompt via the public API, the system first checks the Redis cache. On cache miss, the prompt is fetched from PostgreSQL by name and either version or label (defaulting to "production" label). All dependency tags are resolved by recursively fetching and inlining child prompt content. The resolved prompt and its dependency graph are cached in Redis with a configurable TTL.
Key considerations:
- Cache hits record prompt_cache_hit metric; misses record prompt_cache_miss
- The resolve flag can be set to false to skip dependency resolution
- Redis getex command atomically gets and extends TTL on cache access
- The resolution graph (adjacency list of dependencies) is returned alongside the prompt
Step 5: Prompt Compilation with Variables
At runtime in the application code, the retrieved prompt is compiled by substituting mustache-style variables and expanding placeholder messages. Text variables are replaced using regex pattern matching that allows optional whitespace around variable names. Placeholder messages (type "placeholder") are expanded into arrays of actual chat messages provided at runtime.
Key considerations:
- Mustache variable syntax: Template:VariableName with optional whitespace
- Placeholder expansion replaces a single placeholder message with an array of messages
- Variable substitution is applied after placeholder expansion
- Missing placeholder values throw descriptive errors