Use this file to discover all available pages before exploring further.
Data workflows involve multiple steps — fetching, transforming, validating, enriching, and loading data. Tensorlake lets you define these pipelines as composed functions that automatically run in parallel where possible, with built-in durability and resource optimization.Your workflows are exposed as HTTP endpoints, that can be called on-demand. They scale up when they are called, and scale down when they are idle.
Workflows in Tensorlake use futures to define function calls without executing them immediately. This allows Tensorlake to optimize execution by running independent steps in parallel. When you return a future from a function (called a tail call), the function completes immediately without blocking, and Tensorlake orchestrates the remaining work.Here’s a simple workflow that processes and formats data from multiple sources:
from tensorlake.applications import application, function@application()@function()def enrich_record(record_id: str) -> dict: # Create futures - these don't run yet, just define the function calls profile = fetch_profile.future(record_id) history = fetch_history.future(record_id) # Return a tail call - enrich_record() completes immediately without blocking # Tensorlake then automatically: # 1. Runs fetch_profile() and fetch_history() in parallel (no dependencies between them) # 2. Once both complete, runs merge_data() with their results # 3. Uses merge_data()'s return value as enrich_record()'s final result return merge_data.future(profile, history)@function()def fetch_profile(record_id: str) -> dict: # Fetch from profile service return {"id": record_id, "name": "Example Corp", "tier": "enterprise"}@function()def fetch_history(record_id: str) -> list: # Fetch transaction history return [{"date": "2024-01-15", "amount": 5000}]@function()def merge_data(profile: dict, history: list) -> dict: return {"profile": profile, "transactions": history}
enrich_record starts and immediately returns (doesn’t block)
fetch_profile("rec_123") and fetch_history("rec_123") run in parallel
When both complete, merge_data runs with both results
Final response contains the merged data
Key benefits:
Parallel execution where possible (lower latency)
No blocking — the orchestrator container is freed immediately
Automatic dependency tracking — no manual coordination needed
Built-in durability — failures resume from checkpoints
For a deep dive on futures and tail calls, see Futures.
See async functions on how to build non-blocking workflows using Python async/await.
Each function in your workflow can be configured with retry policies. If a step fails, Tensorlake automatically retries it based on your retry configuration.
Return futures instead of blocking. When you return a future as a tail call, the current function’s container is freed immediately — you’re not paying for idle containers waiting for downstream results.