Building a Platform Stateless Runner with LangGraph, Redis, and FastAPI

This guide covers the implementation of a stateless runner platform using LangGraph for workflow management, Redis for state persistence, and FastAPI for API exposure.

Blog cover image
2101050's avatar
2101050
12 views

Building a Platform Stateless Runner with LangGraph, Redis, and FastAPI


1. Introduction: Why Stateless Runners?

Overview

In today’s distributed computing ecosystem, the adoption of stateless application patterns has become crucial for scalability, reliability, and platform flexibility. Stateless runners—compute components that do not depend on local or in-memory state—enable all critical state to persist externally, typically in a dedicated database, cache, or queue system. This allows you to scale horizontally, recover seamlessly from failures, and support cloud-native, microservice-oriented workflows.

When do you need this?

  • Batch and pipeline orchestration: Workloads are split across short-lived tasks.
  • Asynchronous API tasks: Users submit requests and poll for results.
  • Large-scale LLM or data processing: Jobs can be split, resumed, and recovered without loss.

Stack Overview:

  • LangGraph manages the workflow logic as a directed acyclic graph, chaining together multiple steps including validations, LLM calls, and summaries.
  • Redis serves as the high-performance, in-memory key/value store, ensuring that all progress, errors, and final results are persisted externally.
  • FastAPI exposes APIs for users to submit jobs and query results, acting as a stateless gateway.

Architectural Diagram (Mermaid)

Mermaid
1flowchart LR 2 subgraph Client 3 C1(User) 4 end 5 6 subgraph FastAPI_Service 7 FAPI(FastAPI REST API) 8 end 9 10 subgraph Core_Workflow 11 LG(LangGraph Workflow Engine) 12 end 13 14 subgraph State 15 REDIS[(Redis <br>State Store)] 16 end 17 18 C1 -->|POST/GET job| FAPI 19 FAPI -->|Trigger| LG 20 LG <-->|Read/Write State| REDIS 21 FAPI <-->|Query State| REDIS 22 FAPI -->|Responds| C1 23

Sample Request Flow Example

  1. User sends a POST to /jobs with input.
  2. FastAPI assigns a job_id and stores an initial job state in Redis.
  3. FastAPI kicks off the LangGraph workflow with this state.
  4. Each LangGraph step updates the job state in Redis.
  5. The user polls GET /jobs/{job_id}, and FastAPI fetches the latest state from Redis.

References


2. Environment Setup and Prerequisites

2.1. Project Structure

Text
1stateless-runner-platform/
2│
3├── app/
4│   ├── __init__.py
5│   ├── main.py              # FastAPI entrypoint
6│   ├── workflow.py          # LangGraph workflow logic
7│   ├── redis_client.py      # Redis connection logic
8│   └── models.py            # State models
9│
10├── tests/
11│   └── test_end_to_end.py   # Integration tests
12│
13├── docker-compose.yml
14├── requirements.txt
15└── README.md
16

2.2. Python Virtual Environment & Package Setup

Sh
1python3 -m venv .venv 2source .venv/bin/activate # (.venv) prefix now shown 3python -m pip install --upgrade pip setuptools 4

In requirements.txt:

Text
1fastapi
2uvicorn[standard]
3redis
4langgraph
5pydantic
6
Sh
1pip install -r requirements.txt 2

2.3. Redis (Docker-based Setup)

Sh
1docker run -d --name stateless-redis -p 6379:6379 redis:7 2

Confirm it works:

Sh
1docker exec -it stateless-redis redis-cli ping 2# Output: PONG 3

2.4. Minimal FastAPI + Redis Test

app/main.py:

Python
1from fastapi import FastAPI, HTTPException 2import redis 3import os 4 5app = FastAPI() 6REDIS_HOST = os.getenv("REDIS_HOST", "localhost") 7REDIS_PORT = int(os.getenv("REDIS_PORT", 6379)) 8redis_client = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, db=0) 9 10@app.post("/set/") 11def set_value(key: str, value: str): 12 redis_client.set(key, value) 13 return {"status": "ok"} 14 15@app.get("/get/") 16def get_value(key: str): 17 value = redis_client.get(key) 18 if value is None: 19 raise HTTPException(status_code=404, detail="Key not found") 20 return {"value": value.decode()} 21

Run:

Sh
1uvicorn app.main:app --reload 2

3. Deep Dive: Stateless Runner Implementation

3.1. Workflow State and LangGraph Setup

app/models.py

Python
1from typing import TypedDict, Optional 2 3class JobState(TypedDict): 4 job_id: str 5 input_text: str 6 validation_status: str 7 analysis_result: Optional[str] 8 status: str 9 error: Optional[str] 10

app/workflow.py

Python
1from langgraph.graph import StateGraph, START, END 2from app.models import JobState 3from app.redis_client import save_state 4 5def validate_text(state: JobState) -> JobState: 6 ... 7def analyze_text(state: JobState) -> JobState: 8 ... 9def finish_job(state: JobState) -> JobState: 10 ... 11 12def build_job_workflow(): 13 workflow = StateGraph(JobState) 14 ... 15 return workflow.compile() 16

3.2. Redis Integration

app/redis_client.py:

Python
1import redis, json, os 2 3redis_client = redis.Redis(host=os.getenv("REDIS_HOST", "localhost"), 4 port=int(os.getenv("REDIS_PORT", 6379)), db=0) 5 6def save_state(job_id: str, state: dict): 7 redis_client.set(job_id, json.dumps(state)) 8def retrieve_state(job_id: str): 9 val = redis_client.get(job_id) 10 if not val: return None 11 return json.loads(val) 12

3.3. FastAPI API Layer

app/main.py:

Python
1from fastapi import FastAPI, HTTPException, BackgroundTasks 2... 3 4@app.post("/jobs/") 5def submit_job(input_text: str, background_tasks: BackgroundTasks): 6 ... 7@app.get("/jobs/{job_id}") 8def get_result(job_id: str): 9 ... 10

Run & test as above.


4. End-to-End Practical Example & Case Study

4.1. Workflow & API Integration

More advanced workflow (with retries, error handling) as in Section 4 above—see detailed code samples in the previous message.

4.2. Testing

Bash
1curl -X POST "http://127.0.0.1:8000/jobs/" -H "Content-Type: application/json" -d "{\"input_text\":\"I feel really good about this product!\"}" 2curl "http://127.0.0.1:8000/jobs/job:your_id_here" 3

4.3. Troubleshooting Table

SymptomCauseFix
Always "pending"Logic errorAdd debug logs
"Job not found"Wrong key/expValidate and check TTL
Data lost on failRedis not persistEnable disk volume

See Section 4 above for full example code and diagrams.


5. Further Considerations, Troubleshooting & Extensibility

5.1. Troubleshooting Checklist

  • Jobs persist after crash? If not, check Redis persistence.
  • API unreachable? Docker/Compose service config, logs.
  • Unexpected errors? Add deeper logging in workflow and Redis client wrappers.

5.2. Security: API & Redis

API Key Security:

Python
1from fastapi import Depends 2from fastapi.security.api_key import APIKeyHeader 3API_KEY = "your-secret" 4api_key_header = APIKeyHeader(name="X-API-Key") 5 6def verify_api_key(key: str = Depends(api_key_header)): 7 if key != API_KEY: 8 raise HTTPException(status_code=403, detail="Forbidden") 9@app.post("/jobs/", dependencies=[Depends(verify_api_key)]) 10

Redis password:

  • Add requirepass in configuration.
  • Use in the Python Redis client.

5.3. Production Deployment

docker-compose.yml:

Yaml
1version: '3' 2services: 3 redis: 4 image: redis:7 5 volumes: 6 - redis_data:/data 7 ports: 8 - "6379:6379" 9 api: 10 build: . 11 command: uvicorn app.main:app --host 0.0.0.0 --port 8000 12 ports: 13 - "8000:8000" 14 environment: 15 - REDIS_HOST=redis 16 depends_on: 17 - redis 18volumes: 19 redis_data: 20

Kubernetes (section above for manifests and patterns).

5.4. Observability & Monitoring

5.5. Extensibility

  • Introduce Celery/advanced queues for heavier workloads.
  • Swap Redis for DB/other key-value stores.
  • Register multiple workflow types with LangGraph.

References

Recommended Articles

Discover more articles you might find interesting

Installing and Authenticating Gemini CLI
Application Case Studies

Installing and Authenticating Gemini CLI

A comprehensive guide to installing and authenticating Gemini CLI for developers.

2101050
Jun 26
30
Read More
React Native WebRTC in 2025: A Practical Guide to Real-Time Communication on Mobile
Application Case Studies

React Native WebRTC in 2025: A Practical Guide to Real-Time Communication on Mobile

Learn how to build real-time communication features in mobile apps using React Native WebRTC, including installation, configuration, and example code.

2101050
Jul 07
18
Read More
Discovering Second Me: Redefining Personal Identity in the AI Era
Application Case Studies

Discovering Second Me: Redefining Personal Identity in the AI Era

An exploration of Second Me, an open-source AI identity system that protects individual identity and enhances personalized AI experiences.

2101050
Mar 25
12
Read More
Crafting Effective Privacy Policies and Terms of Service for Subscription Websites
Application Case Studies

Crafting Effective Privacy Policies and Terms of Service for Subscription Websites

A comprehensive guide on creating privacy policies and terms of service for subscription-based websites.

2101050
Feb 27
10
Read More
Implementing a Voice Conversation Demo with OpenAI Swarm and React
Application Case Studies

Implementing a Voice Conversation Demo with OpenAI Swarm and React

This blog post guides you through creating a voice conversation demo using OpenAI Swarm and React, covering technical details, system architecture, and implementation steps.

2101050
May 28
7
Read More
Building Full Stack Applications with Expo Starter: A Practical Guide
Application Case Studies

Building Full Stack Applications with Expo Starter: A Practical Guide

Learn to build robust mobile and web apps with Expo Starter, integrating popular backends like Firebase and Supabase.

2101050
Jul 01
6
Read More