Advanced

Best Practices

Production patterns for deploying Chainlit chatbots: Docker containerization, error handling, performance optimization, and scaling for multiple users.

Docker Deployment

Dockerfile
FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY app.py .
COPY .chainlit/ .chainlit/
COPY public/ public/

EXPOSE 8000

CMD ["chainlit", "run", "app.py", "--host", "0.0.0.0", "--port", "8000"]
Terminal
docker build -t my-chatbot .
docker run -p 8000:8000 --env-file .env my-chatbot

Error Handling

Python
@cl.on_message
async def main(message: cl.Message):
    try:
        response = await generate_response(message.content)
        await cl.Message(content=response).send()
    except RateLimitError:
        await cl.Message(
            content="I'm receiving too many requests. Please wait a moment and try again."
        ).send()
    except Exception as e:
        logging.error(f"Error: {e}")
        await cl.Message(
            content="Sorry, something went wrong. Please try again."
        ).send()

Conversation Memory

Python
@cl.on_chat_start
async def start():
    cl.user_session.set("history", [
        {"role": "system", "content": "You are a helpful assistant."}
    ])

@cl.on_message
async def main(message: cl.Message):
    history = cl.user_session.get("history")
    history.append({"role": "user", "content": message.content})

    # Trim history to prevent token overflow
    if len(history) > 20:
        history = [history[0]] + history[-18:]

    response = await llm.achat(history)
    history.append({"role": "assistant", "content": response})
    cl.user_session.set("history", history)

    await cl.Message(content=response).send()

Production Checklist

🔒

Authentication

Enable auth for production. Use OAuth for enterprise, password auth for internal tools. Never expose unauthenticated chatbots with API access.

📊

Logging

Log all conversations for debugging and compliance. Use Literal AI or custom logging to track usage and errors.

💰

Cost Control

Set token limits per message and per session. Track API costs per user. Implement rate limiting.

🚀

Scaling

Chainlit uses WebSocket connections. Use sticky sessions with load balancers. Consider Redis for shared state.

Common Mistakes

  • No error handling: Unhandled exceptions crash the chat. Always wrap LLM calls in try/except.
  • Unbounded history: Conversation history grows indefinitely. Trim or summarize to prevent token overflow.
  • Global state: Do not use global variables for user data. Use cl.user_session instead.
  • Sync blocking: Chainlit is async. Use await and cl.make_async() for sync functions.
  • No auth in production: Open chatbots with API access are a security and cost risk.

Course Complete!

Congratulations! You can now build, customize, and deploy production-ready chatbots with Chainlit, including LangChain integration, custom branding, and authentication.

Ready to Go Deeper?

Live instructor-led courses from our partners. Affiliate disclosure.