How to initialize and manage DB connections in a Livekit agent?

I basically want to initialize some async DB connections in my Livekit agent. I use Beanie to manage my MongoDB database. Beanie initialization looks something like this (as per the docs):

from beanie import init_beanie, Document
from pymongo import AsyncMongoClient

class Sample(Document):
    name: str

async def init():
    # Create Async PyMongo client
    client = AsyncMongoClient(
        "mongodb://user:pass@host:27017"
    )

    # Initialize beanie with the Sample document class and a database
    await init_beanie(database=client.db_name, document_models=[Sample])

The issue I face is that I can’t find how to initialize my DB connections when setting up a Livekit agent. For example with a fastapi app, I could tie the DB initialization and shutdown to the FastAPI Lifespan like so:

@asynccontextmanager
async def lifespan(app: FastAPI):
    # Initialize mongodb connection and collections
    app.state.mongodb_manager = await init_mongodb("database_name")
    # Initialize all the other dbs
    app.state.redis_manager = RedisManager()
    app.state.weaviate_manager = WeaviateManager()
    app.state.elasticsearch_manager = ElasticSearchManager()

    yield

    # Close all the connections at shutdown
    await app.state.mongodb_manager.close_connection()
    await app.state.redis_manager.close_connection()
    app.state.weaviate_manager.close_connection()
    app.state.elasticsearch_manager.close_connection()


iris_app = FastAPI(lifespan=lifespan)

The tricky thing with livekit is that since the agent service runs in its own async event loop, I would have to ensure that beanie is initialized within the same event loop as well. Also, I don’t want to do the intialization within the entrypoint funnction as that would try to initialize the DB connections every time a new instance of the agent is created for a room.

I remember this came up on StackOverflow, https://stackoverflow.com/questions/79855363/how-to-initialize-and-manage-db-connections-in-a-livekit-agent a couple of months back, did you see my answer there?

LiveKit agents should not be run in a FastAPI server. It is a stateful systems and generally web containers are stateless.

Hi, thanks for the reply. I did see your answer, yes. But I think prewarm cannot be used asynchronously, so that approach wouldn’t work for me. Also I think, especially when you start the agent with the “start“ command rather than dev, prewarm is taken out of the context of the events loops created for the different instances of the agent. So the async connections created there are no longer usable within the agents as they would be running in different event loops.
I couldn’t really find anything in the docs suggesting a recommended method for initializing and cleanly closing db connections (specifically async connections). prewarm was the closest thing but I think it was meant mostly for a one-time loading up of heavy models into the memory.

Yes, I understand that. I just took Fastapi lifecycles as a reference to better indicate what I was suggesting.
I basically wanted to know if there was some way in livekit to initialize db connections such that they exist and can be reused across all the different agent instances. lifecycle is fastapi’s solution to that. It also provides a clean way to close the db connections when the server shuts down.
I wanted to know if there was a similar way to do that in livekit.
Right now, I’ve resorted to initializing the connections within the entrypoint function. So the connections are being created per agent instance. And I have no way of cleanly ensuring that the connections are closed.

The key detail is in the Server lifecycle and Job lifecycle: each job runs in its own process. The entrypoint is executed as the main function of that new process. So there isn’t a single shared async event loop across all agent instances—each room/job is process‑isolated.

That means:

  • You cannot safely share async DB connections across jobs, because they live in different processes (not just different loops).

  • The correct place to initialize async resources like Beanie is inside the entrypoint, since that runs inside the job’s event loop.

  • To clean up, use ctx.add_shutdown_callback() as described in the Post-processing and cleanup section of the Job lifecycle page to close your Mongo client when the session ends.

So the recommended pattern is: initialize Beanie once per job (in entrypoint), reuse it for that job only, and close it in a shutdown callback. There is no FastAPI-style global lifespan because isolation is a core design feature of agent servers.

Okay thanks for clearing that up. I think it would be a good idea to add handling db connections to the docs or as an example. That would really help out junior devs and people who are new to the framework.

Just a suggestion :slight_smile: .. anyway thanks for helping me out

1 Like