В своём боте по учёту долгов
https://t.me/DebtsTrackerRuBot я реализовал это следующим образом.
Создал табличку TgChat в БД с ключём по chat_id и в ней есть поле lang:string. По умолчании там русский, но пользователь может в настройках поменять на английский или другой.
При каждом запросе проверяется это поле и выставляется переменная в контекст который передаётся в каждый метод насквозь. Везде где надо отвечать текстом по ключу сообщения берётся перевод.
В этой же табличке хранится текущее состояние чата так что грузить эту запись надо всё равно, соответсвенно накладных расходов ноль.