Optimizing Streamlit for Production ML/DL Gen AI Projects: Enhancing Performance with RQ

Kshitij Kutumbe
2 min readMay 12, 2024

--

Photo by Hitesh Choudhary on Unsplash

Streamlit has gained popularity for its ease of use in creating ML/DL Gen AI project interfaces. However, as projects scale, long-running tasks can impact performance. This blog explores how to combine Streamlit with RQ to offload tasks to a background queue, ensuring a smoother user experience.

Challenges with Streamlit:

  • Performance Bottlenecks: Long-running tasks can lead to unresponsive interfaces.
  • Scalability Issues: Handling large datasets or multiple users concurrently can strain Streamlit.
  • Resource Management: Streamlit’s synchronous nature can be resource-intensive for complex tasks.

Introducing RQ and Background Task Execution:

RQ (Redis Queue) is a Python library for task queueing with Redis. It enables background task execution, ensuring Streamlit remains responsive.

Key Concepts of RQ:

  • Queue: Holds tasks to be executed. RQ manages task execution order.
  • Worker: Processes that execute tasks. Each worker listens to specific queues.

Combining Streamlit with RQ

Folder Structure:

project/
├── streamlit_app.py
├── rq_worker.py
└── tasks.py

Setting Up Redis Server:

  • Install and run Redis server locally or use a cloud-based service.
  • Note the Redis server’s host and port for configuration.

Configuring RQ:

# rq_worker.py
import os
from rq import Worker, Queue, Connection

listen = ['high', 'default', 'low']
redis_url = os.getenv('REDIS_URL', 'redis://localhost:6379')

conn = Connection(redis_url)

if __name__ == '__main__':
with Connection(conn):
worker = Worker(map(Queue, listen))
worker.work()

Offloading Long-Running Tasks:

# streamlit_app.py
import streamlit as st
from rq import Queue
from redis import Redis
from tasks import long_running_task

# Connect to Redis server
redis_conn = Redis()
queue = Queue('default', connection=redis_conn)

def run_task():
job = queue.enqueue(long_running_task)
st.write('Task enqueued!')
st.write('Task ID:', job.id)

if st.button('Start Long Task'):
run_task()

Writing Task Function:

# tasks.py
def long_running_task():
# Your long-running task here
pass

Running the Application:

  • Run the RQ worker for the ‘default’ queue using rq worker command.
  • Run the Streamlit application using streamlit run streamlit_app.py command.

Conclusion

Combining Streamlit with RQ can significantly improve the performance and scalability of your ML/DL Gen AI projects. By offloading long-running tasks to a background queue, you can ensure a smoother user experience and efficient task processing. This integration allows Streamlit to focus on providing a responsive user interface while RQ handles the heavy lifting in the background.

Also , check out my other interesting blogs:

--

--

Kshitij Kutumbe

Data Scientist: Machine Learning | Deep Learning | NLP | Generative AI