---
title: "Keep no state inside the app process · Agent Wranglers"
url: https://agentwranglers.se/playbook/engineering/running-in-production/stateless-processes
updated: 2026-10-21
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Keep no state inside the app process

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Running in production](https://agentwranglers.se/playbook/engineering/running-in-production.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers). Updated 2026-10-21.

- Level: Recommended
- Chapter: [Running in production](https://agentwranglers.se/playbook/engineering/running-in-production)
- Rule: Keep sessions, uploads and pending jobs outside the app process and its local disk. Any copy of the app can then stop or start without losing them.
- How: Store sessions in the database or a shared store such as Redis or Valkey. Store uploads in object storage, as [Upload straight to storage with a signed address](https://agentwranglers.se/playbook/api-design/files-and-uploads/presigned-uploads) shows. Put background work in a queue that survives a restart. Treat local disk as scratch space that the next deploy may wipe. Then a [one-step deploy](https://agentwranglers.se/playbook/engineering/build-test-and-deploy/atomic-deploys-with-rollback) or a second server loses nothing. Each copy also [shuts down cleanly](https://agentwranglers.se/playbook/operations/running-the-service/graceful-shutdown), so no request in flight is lost.
- Check: Sign in, upload a file and start a background job on a test server. Deploy a fresh copy of the app on a new machine and stop the old one. The session, the file and the job are all still there.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### JavaScript example

```js
// Express: sessions live in Redis, so any copy of the app can serve any request
import session from 'express-session';
import { RedisStore } from 'connect-redis';

app.use(session({
  store: new RedisStore({ client: redisClient }),
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: false,
}));
```

### Python example

```python
# Django settings: sessions in the database and uploads in object storage, never on the app's disk
SESSION_ENGINE = "django.contrib.sessions.backends.db"
STORAGES = {
    "default": {"BACKEND": "storages.backends.s3.S3Storage"},
    "staticfiles": {"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage"},
}
```

## Sources

- [The Twelve-Factor App, VI Processes](https://12factor.net/processes)

## Related rules

- [Upload straight to storage with a signed address](https://agentwranglers.se/playbook/api-design/files-and-uploads/presigned-uploads) in API design
- [Deploy in one step and roll back by itself](https://agentwranglers.se/playbook/engineering/build-test-and-deploy/atomic-deploys-with-rollback) in Engineering
- [Shut down cleanly](https://agentwranglers.se/playbook/operations/running-the-service/graceful-shutdown) in Operations

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/engineering/running-in-production/stateless-processes">Agent Wranglers engineering playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Keep secrets in a secrets store](https://agentwranglers.se/playbook/engineering/running-in-production/secrets-store)
- [Running in production](https://agentwranglers.se/playbook/engineering/running-in-production)
