> ## Documentation Index
> Fetch the complete documentation index at: https://developer.upsun.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Web servers

> See how to start your apps as you wish with ASGI and WSGI servers.

export const DynamicCodeBlock = ({language = 'yaml', filename, icon, lines, wrap, expandable, highlight, focus, children}) => {
  const STORAGE_KEY = 'upsun_versions_cache';
  const COMPOSABLE_STORAGE_KEY = 'upsun_composable_cache';
  const CACHE_TTL = 5 * 60 * 1000;
  const API_URL = 'https://meta.upsun.com/images';
  const COMPOSABLE_API_URL = 'https://meta.upsun.com/composable';
  const DEBUG_PREFIX = '[DynamicCodeBlock cache]';
  const [versionData, setVersionData] = useState(null);
  const [versionError, setVersionError] = useState(false);
  const [composableData, setComposableData] = useState(null);
  const [composableError, setComposableError] = useState(false);
  useEffect(() => {
    const fetchData = async () => {
      let cachedData = null;
      let cachedEtag = null;
      if (typeof localStorage !== 'undefined') {
        try {
          const cached = localStorage.getItem(STORAGE_KEY);
          if (cached) {
            const parsed = JSON.parse(cached);
            cachedData = parsed?.data || null;
            cachedEtag = parsed?.etag || null;
            if (cachedData && Date.now() - parsed.timestamp < CACHE_TTL) {
              return cachedData;
            }
          }
        } catch (err) {
          console.error('Failed to load from cache:', err);
        }
      }
      const requestHeaders = cachedEtag ? {
        'If-None-Match': cachedEtag
      } : {};
      console.debug(`${DEBUG_PREFIX} revalidating`, {
        storageKey: STORAGE_KEY,
        hasCachedData: Boolean(cachedData),
        hasCachedEtag: Boolean(cachedEtag)
      });
      const response = await fetch(API_URL, {
        headers: requestHeaders
      });
      if (response.status === 304 && cachedData) {
        console.debug(`${DEBUG_PREFIX} revalidated (304)`, {
          storageKey: STORAGE_KEY
        });
        if (typeof localStorage !== 'undefined') {
          try {
            const etag = response.headers.get('etag') || cachedEtag;
            localStorage.setItem(STORAGE_KEY, JSON.stringify({
              data: cachedData,
              etag,
              timestamp: Date.now()
            }));
          } catch (err) {
            console.error('Failed to refresh cache metadata:', err);
          }
        }
        return cachedData;
      }
      if (!response.ok) throw new Error(`API request failed: ${response.statusText}`);
      const data = await response.json();
      const etag = response.headers.get('etag');
      console.debug(`${DEBUG_PREFIX} refreshed (200)`, {
        storageKey: STORAGE_KEY,
        etag
      });
      if (typeof localStorage !== 'undefined') {
        try {
          localStorage.setItem(STORAGE_KEY, JSON.stringify({
            data,
            etag,
            timestamp: Date.now()
          }));
        } catch (err) {
          console.error('Failed to cache data:', err);
        }
      }
      return data;
    };
    fetchData().then(data => setVersionData(data)).catch(err => console.error('Failed to fetch version data:', err));
  }, []);
  const findHighestVersion = versionsMap => {
    if (!versionsMap || Object.keys(versionsMap).length === 0) return null;
    const entries = Object.entries(versionsMap);
    const active = entries.filter(([, v]) => v.upsun && v.upsun.status === 'supported' || v.upsun && v.upsun.status === 'deprecated');
    const candidates = active.length > 0 ? active : entries;
    let [highestName] = candidates[0];
    for (let i = 1; i < candidates.length; i++) {
      const [currentName] = candidates[i];
      const cp = currentName.split('.').map(Number);
      const hp = highestName.split('.').map(Number);
      for (let j = 0; j < Math.max(cp.length, hp.length); j++) {
        if ((cp[j] || 0) > (hp[j] || 0)) {
          highestName = currentName;
          break;
        } else if ((cp[j] || 0) < (hp[j] || 0)) {
          break;
        }
      }
    }
    return highestName;
  };
  const getVersion = (lang, requestedVersion = 'latest') => {
    if (lang === 'composable') {
      if (!composableData || !composableData.versions || Object.keys(composableData.versions).length === 0) return null;
      if (requestedVersion && requestedVersion !== 'latest') {
        return (requestedVersion in composableData.versions) ? requestedVersion : null;
      }
      return findHighestVersion(composableData.versions);
    }
    if (!versionData) return null;
    const imageData = versionData[lang];
    if (!imageData || !imageData.versions || Object.keys(imageData.versions).length === 0) {
      return null;
    }
    if (requestedVersion && requestedVersion !== 'latest') {
      return (requestedVersion in imageData.versions) ? requestedVersion : null;
    }
    return findHighestVersion(imageData.versions);
  };
  let code = typeof children === 'string' ? children : String(children || '');
  const codeLines = code.split('\n');
  while (codeLines.length > 0 && codeLines[0].trim() === '') codeLines.shift();
  while (codeLines.length > 0 && codeLines[codeLines.length - 1].trim() === '') codeLines.pop();
  if (codeLines.length > 0) {
    const indents = codeLines.filter(line => line.trim().length > 0).map(line => line.match(/^[ \t]*/)[0].length);
    const minIndent = Math.min(...indents);
    code = codeLines.map(line => line.slice(minIndent)).join('\n');
  }
  code = code.replace(/\{\{version:(.*?)\}\}/g, (match, params) => {
    const parts = params.split(':');
    const lang = parts[0];
    const ver = parts[1] || 'latest';
    const isComposable = lang === 'composable';
    const hasError = isComposable ? composableError : versionError;
    const dataReady = isComposable ? composableData !== null : versionData !== null;
    if (hasError) return '(unavailable)';
    if (dataReady) {
      const resolvedVersion = getVersion(lang, ver);
      return resolvedVersion || match;
    }
    return '...';
  });
  const codeBlockProps = {
    language,
    ...filename && ({
      filename
    }),
    ...icon && ({
      icon
    }),
    ...lines !== undefined && ({
      lines
    }),
    ...wrap !== undefined && ({
      wrap
    }),
    ...expandable !== undefined && ({
      expandable
    }),
    ...highlight && ({
      highlight
    }),
    ...focus && ({
      focus
    })
  };
  return <CodeBlock {...codeBlockProps}>{code}</CodeBlock>;
};

export const DisclaimerNix = () => <Tip>
    You can now use composable image to install runtimes and tools in your application container. To find out more, see the <a href="/docs/configure-apps/app-reference/composable-image">Composable image</a> topic.
  </Tip>;

<DisclaimerNix />

The Python ecosystem offers a number of web servers that can be used to deploy to Upsun.
The following examples deploy a Django project named `myapp`.
They assume a `myapp/wsgi.py` or `myapp/asgi.py` file  with a callable `application`.
Adjust the examples to fit your framework and app.

## Gunicorn

[Gunicorn](https://docs.gunicorn.org/) is a Python WSGI HTTP Server for Unix
that operates on a pre-fork worker model.
The Gunicorn server is broadly compatible with various web frameworks, light on server resource usage, and fast.

To deploy with Gunicorn on Upsun,
use one of the following examples to update your [app configuration](/docs/configure-apps).

The examples vary based on both your package manager (Pip, Pipenv, or Poetry)
and whether your app listens on a TCP (default) or Unix (for running behind a proxy server) socket.
For more information on upstream sockets and protocols, see the [application reference](/docs/configure-apps/image-properties/web#upstream).

The snippets below assume that Gunicorn has been added as a dependency to your `requirements.txt`, `Pipfile.lock`, or `poetry.lock`.

<Tabs>
  <Tab title="Pip (TCP)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    commands:
                      start: "gunicorn -w 4 -b localhost:$PORT app.wsgi:application"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Pip (Unix)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    upstream:
                      socket_family: unix
                    commands:
                      start: "gunicorn -w 4 -b unix:$SOCKET app.wsgi:application"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Pipenv (TCP)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    commands:
                      start: "pipenv run gunicorn -w 4 -b localhost:$PORT app.wsgi:application"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Pipenv (Unix)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    upstream:
                      socket_family: unix
                    commands:
                      start: "pipenv run gunicorn -w 4 -b unix:$SOCKET app.wsgi:application"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Poetry (TCP)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    commands:
                      start: "poetry run gunicorn -w 4 -b localhost:$PORT app.wsgi:application"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Poetry (Unix)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    upstream:
                      socket_family: unix
                    commands:
                      start: "poetry run gunicorn -w 4 -b unix:$SOCKET app.wsgi:application"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>
</Tabs>

### Gunicorn workers

These examples define four worker processes with `-w 4`.
For more details on what you can configure, see the [Gunicorn documentation](https://docs.gunicorn.org/en/stable/faq.html#worker-processes).

Workers can also be defined with a custom [worker class](https://docs.gunicorn.org/en/latest/settings.html#worker-class),
such as [Uvicorn](https://www.uvicorn.org/#running-with-gunicorn), [gevent](https://www.gevent.org/),
or [Tornado](https://www.tornadoweb.org/).

For example, to add a Uvicorn worker class to the pip example for Unix,
adjust the start command to the following:

<DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
  {`
      applications:
        # The app's name, which must be unique within the project.
        myapp:
          type: 'python:{{version:python:latest}}'
          web:
            upstream:
              socket_family: unix
            commands:
              start: "gunicorn -w 4 -k uvicorn.workers.UvicornWorker -b unix:$SOCKET app.wsgi:application"`
  }
</DynamicCodeBlock>

## Daphne

[Daphne](https://github.com/django/daphne) is a HTTP, HTTP2 ,and WebSocket protocol server for ASGI and ASGI-HTTP,
developed to power Django Channels.

To deploy with Daphne on Upsun,
use one of the following examples to update your [app configuration](/docs/configure-apps).

The examples vary based on both your package manager (Pip, Pipenv, or Poetry)
and whether your app listens on a TCP (default) or Unix (for running behind a proxy server) socket.
For more information on upstream sockets and protocols, see the [application reference](/docs/configure-apps/image-properties/web#upstream).

The snippets below assume that Daphne has been added as a dependency to your `requirements.txt`, `Pipfile.lock`, or `poetry.lock`.

<Tabs>
  <Tab title="Pip (TCP)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    commands:
                      start: "daphne -p $PORT app.asgi:application"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Pip (Unix)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    upstream:
                      socket_family: unix
                    commands:
                      start: "daphne -u $SOCKET app.asgi:application"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Pipenv (TCP)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    commands:
                      start: "pipenv run daphne -p $PORT app.asgi:application"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Pipenv (Unix)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    upstream:
                      socket_family: unix
                    commands:
                      start: "pipenv run daphne -u $SOCKET app.asgi:application"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Poetry (TCP)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    commands:
                      start: "poetry run daphne -p $PORT app.asgi:application"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Poetry (Unix)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    upstream:
                      socket_family: unix
                    commands:
                      start: "poetry run -u $SOCKET app.asgi:application"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>
</Tabs>

## Uvicorn

[Uvicorn](https://www.uvicorn.org/) is an ASGI web server implementation for Python.

To deploy with Uvicorn on Upsun,
use one of the following examples to update your [app configuration](/docs/configure-apps).

The examples vary based on both your package manager (Pip, Pipenv, or Poetry)
and whether your app listens on a TCP (default) or Unix (for running behind a proxy server) socket.
For more information on upstream sockets and protocols, see the [application reference](/docs/configure-apps/image-properties/web#upstream).

The snippets below assume that Uvicorn has been added as a dependency to your `requirements.txt`, `Pipfile.lock`, or `poetry.lock`.

<Tabs>
  <Tab title="Pip (TCP)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    commands:
                      start: "uvicorn app.asgi:application --port $PORT --workers 4"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Pip (Unix)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    upstream:
                      socket_family: unix
                    commands:
                      start: "uvicorn app.asgi:application --uds $SOCKET --workers 4"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Pipenv (TCP)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    commands:
                      start: "pipenv run uvicorn app.asgi:application --port $PORT --workers 4"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Pipenv (Unix)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    upstream:
                      socket_family: unix
                    commands:
                      start: "pipenv run uvicorn app.asgi:application --uds $SOCKET --workers 4"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Poetry (TCP)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    commands:
                      start: "poetry run uvicorn app.asgi:application --port $PORT --workers 4"
                    locations:
                        "/":
                          passthru: true
                        "/static":
                          root: "static"
                          expires: 1h
                          allow: true`
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Poetry (Unix)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    upstream:
                      socket_family: unix
                    commands:
                      start: "poetry run uvicorn app.asgi:application --uds $SOCKET --workers 4"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>
</Tabs>

### Uvicorn workers

These examples define four worker processes with `-w 4`.
For more recommendations on this and other settings, see the [Uvicorn documentation](https://www.uvicorn.org/settings/#timeouts).

Instead of the `-w` flag, you can also use the `WEB_CONCURRENCY` variable.
See how to [set variables](/docs/development/variables/set-variables).

## Hypercorn

[Hypercorn](https://hypercorn.readthedocs.io/) is an ASGI and WSGI web server inspired by Gunicorn.

To deploy with Hypercorn on Upsun,
use one of the following examples to update your [app configuration](/docs/configure-apps).

The examples vary based on both your package manager (Pip, Pipenv, or Poetry)
and whether your app listens on a TCP (default) or Unix (for running behind a proxy server) socket.
For more information on upstream sockets and protocols, see the [application reference](/docs/configure-apps/image-properties/web#upstream).

The snippets below assume that Hypercorn has been added as a dependency to your `requirements.txt`, `Pipfile.lock`, or `poetry.lock`.

<Tabs>
  <Tab title="Pip (TCP)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    commands:
                      start: "hypercorn app.asgi:application -b localhost:$PORT -w 4"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Pip (Unix)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    upstream:
                      socket_family: unix
                    commands:
                      start: "hypercorn app.asgi:application -b unix:$SOCKET -w 4"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Pipenv (TCP)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    commands:
                      start: "pipenv run hypercorn app.asgi:application -b localhost:$PORT -w 4"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Pipenv (Unix)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    upstream:
                      socket_family: unix
                    commands:
                      start: "pipenv run hypercorn app.asgi:application -b unix:$SOCKET -w 4"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Poetry (TCP)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    commands:
                      start: "poetry run hypercorn app.asgi:application -b localhost:$PORT -w 4"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Poetry (Unix)">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  type: 'python:{{version:python:latest}}'
                  web:
                    upstream:
                      socket_family: unix
                    commands:
                      start: "poetry run hypercorn app.asgi:application -b unix:$SOCKET -w 4"
                    locations:
                      "/":
                        passthru: true
                      "/static":
                        root: "static"
                        expires: 1h
                        allow: true`
          }
    </DynamicCodeBlock>
  </Tab>
</Tabs>

### Hypercorn workers

These examples define four worker processes with `-w 4`.
For more details on what you can configure, see the [Hypercorn documentation](https://hypercorn.readthedocs.io/en/latest/how_to_guides/configuring.html).

Workers can also be defined with a custom [worker class](https://hypercorn.readthedocs.io/en/latest/how_to_guides/configuring.html#configuration-options),
such as Asyncio, Uvloop, or Trio.

For example, to add a Asyncio worker class to the pip example for Unix,
adjust the start command to the following:

<DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
  {`
      applications:
        # The app's name, which must be unique within the project.
        myapp:
          type: 'python:{{version:python:latest}}'
          web:
            upstream:
              socket_family: unix
            commands:
              start: "hypercorn app.asgi:application -b unix:$SOCKET -w 4 -k asyncio"`
  }
</DynamicCodeBlock>
