Skip to content
Consultation

One Qwen chat for two articles: followups via chat URL

Adityo Guni Waluyo

A --chat-url option lets EN translation reuse the existing Qwen chat, one chat for two articles, plus how force-cache works in Next.js 15.

TL;DR

The author's translation pipeline burned through free Qwen quota because every generate run opened a new chat, so they added a --chat-url option to reuse existing sessions, halving quota use. Next.js 15 stopped caching fetch by default, requiring explicit force-cache settings. A tldr-tolerant push now ignores server metadata, preventing CI failures.

I was busy building an automated pipeline for the adityo.web.id blog. The intention was simple: translate Indonesian articles to English using Qwen. But the reality? My free chat.qwen.ai account was depleted in a short time. Every time the generate process ran, the system opened a new chat instead. This is clearly a waste of quota and inefficient for production scale, especially when there are many articles to process every week. Imagine having 10 articles, meaning 10 new chats that immediately eat up the daily limit allowance.

Initially, I thought the problem was an inefficient prompt or exceeding the token limit. I tried shortening the instructions, tidying up the context, and even breaking the prompt into smaller parts. Still, every generate process triggered a new session. Logically, the conversation context should still be connected and reusable for articles within the same topic or processing batch.

Quota Issues and the Chat URL Solution

The solution turned out to be more technical than just fixing the prompt sentences. I decided to modify the generate tool by adding the --chat-url option. This way, follow-up instructions (default translate to EN) are sent directly to the EXISTING chat, rather than creating a new session from scratch that consumes additional quota.

The result showed up immediately in daily use. One chat = 2 articles (Indonesian and English versions). The generate output now automatically includes the chat_url field in its metadata. This field serves as a marker so that the old session can be called again anytime without needing to start the conversation from scratch. Imagine it like continuing a chat with a friend who already understands the context, not a new acquaintance who has to be explained everything from zero. The system becomes leaner because it doesn't need to reload the same context repeatedly, which also means the generate process latency becomes faster.

Next.js 15 Caching Lessons Often Misunderstood

While pushing this update to the repository, I actually encountered a valuable lesson about caching in Next.js that I had previously taken for granted. Since Next.js 15, fetch in Server Components is not cached by default [1]. This is a major change from previous versions. We now must explicitly state cache: 'force-cache' per request, or set export const fetchCache = 'default-cache' at the layout or page level [2]. For GET Route Handlers, we are required to use the dynamic = 'force-static' configuration so that data can be properly cached at the edge or server.

I used to be confused about distinguishing memoization from persistent cache. Memoization (GET with the same URL and options within a single render pass) is totally different from persistent cache across requests, which I used to mix up [3]. The force-cache mechanism performs matching based on URL, method, headers, and body, and only stores HTTP 200 responses. If there is a conflicting configuration like { revalidate: 3600, cache: 'no-store' }, Next.js will ignore both and provide a warning in the development environment. Understanding this makes tuning cache lifespan with next: { revalidate: N } much more predictable, and I no longer have to guess why old data still appears or why requests are always fresh.

This commit also brings an equally important additional feature, namely tldr-tolerant push. Server fields like id, published_at, and tldr are now silently discarded during the work file re-push process. The goal is simple: local archives will no longer cause validation to fail just because of server metadata differences that are actually irrelevant to the regenerate process. The system becomes more forgiving of state differences between local and server, so developers don't need to manually edit JSON files just to pass CI/CD validation.

The experience of tinkering with this pipeline reminded me of the importance of designing a system with a solid fallback. Similar to the strategy for keeping answers alive when the LLM is down, or the router9 fallback lane in the cron pipeline I wrote about before. When we already have full control over chat sessions and data caching, configuring the LLM router via environment variables also feels more logical.

With this approach, the article pipeline is not only more quota-efficient, but also more stable, easier to maintain, and ready to face future framework version changes without panicking. This is not just about saving a few megabytes, but about building an automation foundation that doesn't easily break when there are minor changes in data structure.

Sources

  1. Next.js — Upgrading: Version 15, accessed September 3, 2026.
  2. Next.js — fetch function (options.cache, next.revalidate, memoization), accessed September 3, 2026.
  3. Next.js — Caching (Previous Model), accessed September 3, 2026.

Related articles