MySQL connector throws OperationalError about unavailable connection in Python Telegram bot after hours of running

I’m building a Telegram bot using Python with the pyrogram framework. The bot connects to a MySQL database during startup like this:

bot = Client("telegram_bot", api_id=settings.API_ID, api_hash=settings.API_HASH,
             bot_token=settings.BOT_TOKEN, parse_mode=enums.ParseMode.DEFAULT)
with bot:
    try:
        db_connection = mysql.connector.connect(host="localhost", user=settings.DB_USER,
                                           password=settings.DB_PASS, database=settings.DB_NAME)
    except Exception as error:
        print(f'Database Error: {error}')
        exit()

I have a message handler that looks like this:

@bot.on_message(filters.private & filters.text & filters.user(settings.ADMIN_LIST))
async def processAdminMessage(client: Client, msg: types.Message):
    content = msg.text.lower()
    sender_id = msg.from_user.id
    conversation_id = msg.chat.id
    message_id = msg.id
    if content == 'count':
        cursor = db_connection.cursor(buffered=True)
        cursor.execute('SELECT COUNT(*) FROM members')
        data = cursor.fetchone()
        if not data:
            data = [0]
        cursor.close()
        response = f'Total members: {data[0]}'
        await msg.reply(response, reply_to_message_id=message_id)
        return

The bot works fine when I run it normally. However, when I start it with nohup python bot.py & and let it run for several hours, I get this error:

File "/path/to/mysql/connector/connection_cext.py", line 772, in cursor
    raise OperationalError("MySQL Connection not available.")
mysql.connector.errors.OperationalError: MySQL Connection not available.

Why does this happen? Does MySQL automatically close connections after some time? How can I fix this issue?

MySQL’s wait_timeout parameter is typically set to 8 hours, which means idle connections are closed automatically. In your case, the connection remains open but can become stale if it’s not actively used during that time, leading to the OperationalError. A recommended solution is to implement connection pooling or to periodically verify if the connection is still active with db_connection.is_connected() before executing any queries. If it returns False, simply reconnect to the database. You might also consider setting autocommit=True and use_unicode=True in your connection options, and if you’re using SQLAlchemy, adding pool_recycle=3600 to refresh connections every hour can help prevent this issue.

Had the same issue when I deployed my bot. MySQL drops inactive connections after 8 hours by default. Your connection dies but Python doesn’t know until you try using it.

I fixed this by ditching the global connection. Instead, I made a simple get_db_connection() function that creates a fresh connection each time, then closes it after the query runs. Yeah, there’s a tiny performance hit, but it’s way more reliable for bots that run 24/7.

You could check db_connection.is_connected() before each query and reconnect if it’s dead, but the fresh connection approach works better. I’ve used it on several Telegram bots without issues.

same thing happened to me too. mysql drops idle connections when they timeout. quick fix: call db_connection.ping(reconnect=True) before using your cursor - it’ll reconnect automatically if the connection died. better solution is using a connection pooling library instead of keeping one persistent connection.