Skip to content

Issue: Sticky Session / Session Affinity Not Working with Azure Web App + FastAPI +FastMCP + Gunicorn #1350

@swapnlv

Description

@swapnlv

Question

Context

I’m running a FastAPI application on Azure Web App (Linux, containerized) using Gunicorn + Uvicorn workers.

The app is an MCP (Model Context Protocol) server that connects to Rally via pyral.
Because Rally connections are cached per worker, all requests from the same client need to be routed to the same worker.

If a request lands on a different worker, the Rally API responds with a BAD session ID error because the cached connection is no longer valid.

What I Tried

1. Gunicorn Startup Command

gunicorn -k uvicorn.workers.UvicornWorker \
  -w 2 \
  -b 0.0.0.0:8000 \
  main:app \
  --keep-alive 120 \
  --timeout 240 \
  --worker-connections 1000 \
  --max-requests 1000 \
  --max-requests-jitter 50 \
  --preload \
  --log-level info

2. Custom Session Middleware (FastAPI)

Validates that a request always maps back to the same worker.

3. Debugging

Logged worker PID + session ID on each request.

Observed the same client’s requests hitting different workers intermittently.

Example log:

Worker 1234 → Session=sess_abc_1234
Worker 5678 → Session=sess_def_5678 # Same client, different worker

Problem

Client requests are not consistently routed to the same Gunicorn worker.

Cached Rally sessions exist only in the worker process that created them.

When a client hits another worker, Rally rejects the request with BAD session ID.

Expected Behavior

All requests from a given client should always land on the same worker.

Session affinity should be preserved consistently until session expiry.

### Questions for the Community

  1. Is it possible to achieve worker-level sticky sessions with FastAPI + Gunicorn on Azure Web App?

  2. Should I run a single worker per instance (e.g., --workers 1) to avoid this problem (I Actually tried and found out the Server crashes a lot )?

  3. Should I share Rally session state across workers (e.g., Redis or DB-backed session store) instead of relying on per-worker caching(Tried it but due to mounting with FASTAPI, the session management didn't got intercepted for the main MCP server URL)?

Note:

Have to use statefull http as using sampling/elicitation in my server

mcp = FastMCP("Rally MCP Server",stateless_http=True)

Additional Context

Environment

Azure Web App (Linux, Code Deploy)

FastAPI + Gunicorn + Uvicorn workers

Python 3.13

pyral (Rally API client)

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1Significant bug affecting many users, highly requested featuredocumentationImprovements or additions to documentationready for workEnough information for someone to start working on

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions