When I added more languages to dizi.jpg, my TV show and movie tracker, the obvious plan was to call a commercial translation API whenever a description was missing in the user's language. I did the math and dropped the idea almost immediately. The catalogue has a very large number of show, movie, season and episode descriptions, and multiplying that by dozens of languages turns into a bill that a one-person project cannot carry.
This post is about the alternative I went with: translating offline, in batches, with open-source models, and storing the results.
The setup
- Argos Translate provides open-source translation models for many language pairs.
- CTranslate2 runs those models efficiently on a normal machine.
- A batch job picks descriptions that are missing in a given language, translates them on my own computer and writes the results into PostgreSQL.
- The app and the server-rendered pages simply read the stored translation. Nothing is translated at request time.
Why batch instead of on demand
Cost is fixed. The only cost is my own machine's time. Adding a language does not add a monthly invoice.
Latency is zero at request time. Users never wait for a translation; it is already in the database.
Search engines see real content. Because every language has its own stored text, each language version of a page can be served with its own title and description and indexed separately.
The trade-offs
It is not free in every sense:
- Quality is lower than the best commercial systems. The output is readable and useful for a plot summary, but it is not polished prose. For short descriptions that is an acceptable trade.
- Some language pairs go through English. When there is no direct model between two languages, pivoting through English adds a second chance for errors.
- Batches need babysitting. Long jobs can stop halfway. The job has to be restartable and must know which rows are already done.
- New content lags behind. A new episode description appears in the source language first and in other languages after the next batch run.
Where I still use human judgement
The interface itself (buttons, menus, settings) is not machine translated on the fly. Interface strings are few, visible everywhere and easy to get embarrassingly wrong, so they deserve more care than bulk content.
Would I recommend it?
If you run a content-heavy side project and want many languages, offline translation with open models is worth trying before you sign up for a per-character API. You trade some polish for a predictable cost and full control over the data.
You can see the result by switching languages on any title page of dizi.jpg, for example Breaking Bad in Spanish. The app is also on Google Play and the App Store.
Top comments (0)