Nginx Configuration Required for Sub2API Sticky Sessions

Sub2API requires Nginx to configure sticky sessions using the sticky directive in the upstream block, which routes clients to the same backend instance via a sub2api_session cookie that preserves the session_hash across requests.

The Wei-Shaw/sub2API repository implements stateful session handling that relies on consistent client-to-server routing to maintain continuity. To ensure the session_hash (also referenced as previous_response_id) remains bound to a specific backend worker, the reverse proxy must issue a persistent cookie and honor it for subsequent requests. According to the deployment documentation in deploy/README.md, this requires enabling the sticky session module in Nginx and configuring specific upstream and proxy settings.

How Sub2API Sticky Sessions Work

Sub2API tracks user sessions by emitting a session_hash cookie that identifies the specific backend instance handling the request. When the API runs behind a load balancer, subsequent requests must reach the same worker to access cached session data and consistent rate-limiting states. The frontend type definitions in frontend/src/types/index.ts reference this as sticky_score and related session fields, while the backend logic in backend/internal/web/static_cache.go and backend/internal/repository/usage_log_repo.go depends on this hash remaining stable for accurate usage logging and cache retrieval.

Without sticky session configuration, Nginx distributes requests round-robin across workers, causing session state fragmentation and potential rate-limiting errors.

Required Nginx Configuration

The recommended setup uses the sticky directive available in the open-source nginx-upstream-sticky-module or the commercial NGINX Plus distribution. This creates an upstream block that assigns each client a cookie-based routing identifier.


# -------------------------------------------------

# Upstream definition – enables sticky routing

# -------------------------------------------------

upstream sub2api {
    # List each Sub2API instance (replace with your host/port)

    server 127.0.0.1:8000;
    server 127.0.0.1:8001;

    # Create a sticky cookie that lasts 1 hour

    sticky cookie sub2api_session expires=1h path=/;
}

# -------------------------------------------------

# Server block – public entry point

# -------------------------------------------------

server {
    listen 80;
    server_name api.example.com;   # <-- set your domain

    # -------------------------------------------------

    # Proxy all API paths to the upstream

    # -------------------------------------------------

    location / {
        proxy_pass http://sub2api;
        proxy_http_version 1.1;

        # Preserve original request headers

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Forward the sticky cookie (handled automatically)

        proxy_set_header Cookie $http_cookie;

        # Optional security tweaks

        proxy_cookie_path / "/; HttpOnly; Secure";
        client_max_body_size 10m;   # adjust if needed

    }

    # -------------------------------------------------

    # Health-check endpoint (optional)

    # -------------------------------------------------

    location /healthz {
        proxy_pass http://sub2api/healthz;
        proxy_set_header Host $host;
    }
}

Key Configuration Components

Understanding each directive ensures reliable session persistence in production environments.

Upstream Block with Sticky Directive

The upstream sub2api block declares the pool of backend processes. The sticky cookie sub2api_session directive tells Nginx to generate a routing cookie named sub2api_session with a one-hour expiration. As implemented in Wei-Shaw/sub2api, this cookie guarantees that requests bearing this identifier route to the same worker where the session_hash originated.

Proxy Header Preservation

The proxy_set_header directives ensure Sub2API receives accurate client metadata for rate-limiting and auditing. Specifically, proxy_set_header Cookie $http_cookie forwards the sub2api_session cookie so the backend can validate the session continuity. The backend/internal/repository/usage_log_repo.go file relies on these headers to attribute requests correctly to individual sessions.

Payload Size Configuration

The client_max_body_size 10m directive adjusts maximum request payload limits. This is critical if Sub2API handles image uploads or large JSON payloads that exceed Nginx default limits.

Source Code Integration

Several files in the Wei-Shaw/sub2api repository interact with the sticky session mechanism:

  • backend/internal/web/static_cache.go – Handles HTTP caching headers and works in conjunction with sticky-session routing to ensure cached responses align with the correct session hash.

  • backend/internal/repository/usage_log_repo.go – Persists per-session usage logs that depend on stable session_hash values provided by the sticky session configuration.

  • frontend/src/types/index.ts – Defines TypeScript interfaces for sticky_score and session-related fields that the frontend expects to remain consistent throughout the cookie lifetime.

  • deploy/EDGE_SECURITY.md – Documents edge-level security considerations, including recommendations for securing the sticky session cookie with HttpOnly and Secure flags.

Security Considerations

When terminating TLS at Nginx, apply strict cookie security parameters to prevent session hijacking. The proxy_cookie_path / "/; HttpOnly; Secure" directive marks the sub2api_session cookie inaccessible to JavaScript and restricts transmission to HTTPS connections only. As noted in deploy/EDGE_SECURITY.md, these measures protect the session identifier from XSS attacks and man-in-the-middle interception.

Summary

  • Sticky sessions are mandatory for Sub2API to maintain consistent session_hash routing across multiple backend workers.

  • Configure the sticky cookie directive in the Nginx upstream block to generate the sub2api_session routing identifier.

  • Preserve client metadata using proxy_set_header directives so backend/internal/repository/usage_log_repo.go can accurately track per-session metrics.

  • Secure the configuration using proxy_cookie_path with HttpOnly and Secure flags to protect session integrity at the edge.

  • Reference the official deployment guide in deploy/README.md for complete implementation details specific to the Wei-Shaw/sub2api architecture.

Frequently Asked Questions

Does Sub2API require the commercial NGINX Plus version for sticky sessions?

No, Sub2API works with the open-source nginx-upstream-sticky-module or NGINX Plus. The configuration syntax remains identical using the sticky cookie directive. Ensure your Nginx build includes the sticky module before deploying the configuration from deploy/README.md.

When the sub2api_session cookie expires, Nginx routes the next request to any available backend worker using standard load-balancing algorithms. Sub2API will generate a new session_hash for that worker, potentially resetting rate limits and cache states for that client session.

While ip_hash provides an alternative load-balancing method, Sub2API specifically recommends cookie-based sticky sessions because they survive network address translation (NAT) and mobile network IP changes. The session_hash mechanism in backend/internal/web/static_cache.go expects the cookie-based routing defined in the upstream configuration.

How do I verify that sticky sessions are working correctly?

Monitor the sub2api_session cookie in browser developer tools or curl responses. Each request should present the same cookie value, and backend/internal/repository/usage_log_repo.go should show consistent session attribution in logs. Additionally, check that sequential requests hit the same backend instance by examining your application logs for matching worker process IDs.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →