Skip to content

Instantly share code, notes, and snippets.

@Bnowako
Last active December 17, 2025 08:21
Show Gist options
  • Select an option

  • Save Bnowako/135b13312fda6b96da8f6b522344f954 to your computer and use it in GitHub Desktop.

Select an option

Save Bnowako/135b13312fda6b96da8f6b522344f954 to your computer and use it in GitHub Desktop.
import logging
import multiprocessing
from http.server import BaseHTTPRequestHandler, HTTPServer
from time import sleep

from modal import App, Image

logger = logging.getLogger(__name__)


image = Image.debian_slim()


app = App("mre-fork", image=image)


class SimpleHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-type", "text/plain")
        self.end_headers()
        my_pid = multiprocessing.current_process().pid
        self.wfile.write(f"Hello from forkserver process {my_pid}".encode())


def run_server():
    server = HTTPServer(("0.0.0.0", 8081), SimpleHandler)
    print("Server running on port 8081")
    server.serve_forever()


@app.function(
    min_containers=1,
)
async def mre():
    multiprocessing.set_start_method("forkserver", force=True)
    process = multiprocessing.Process(target=run_server)
    process.start()
    return process.pid


@app.local_entrypoint()
def main():
    pid = mre.remote()
    print(f"HTTP server spawned with forkserver method, PID: {pid}")

    pid = mre.remote()
    print(f"HTTP server spawned with forkserver method, PID: {pid}")

    sleep(600)

If you spawn processes across function calls, the processes seem to persist in the live container.

How to reproduce

  1. modal run mre_fork.py
  2. ssh to the container
  3. ps aux or curl localhost:8081 you will see the process from first function call to respond
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment