148 trials, 1 paid: an honest conversion post-mortem
10 November 2026 · ThaiPo
148 people started a free trial of ThaiPo's best translation tier. One of them paid.
That is roughly 0.7 percent, and there is no way to phrase it that makes it sound better. So we treated it like a production incident: instrument, find the root causes, fix, read the data again. This is that write-up, including the parts where we were wrong first.

First, check the number is a number
The panic started a week early, when the admin page showed 113 people on trial and almost nobody paying. The trial had launched with a backfill that started everyone's clock at once. Every trial was one or two days old. None had reached the end.
So the conversion rate was not low. It did not exist yet. We left pricing alone and used the week to make sure we could see the real result when it landed.
Instrument before you theorise
Our policy is that Google Analytics is the only event store. No events table in Postgres, no homemade tracking system to regret later. That only works if the events arrive, and three of ours did not.
- The trial itself. Analytics showed 2 trial starts against 113 real ones. The backfill created rows and fired nothing.
- Where signups came from. Our first-touch attribution table had zero rows for more than fifty signups. The signup link did an internal redirect that dropped the query string, so the campaign tags never reached the page that records them. We forwarded the tags through the redirect and stamped a first-party cookie on the way. Attribution is one fact, written once at signup.
- The money. A completed subscription never sent a server-side purchase event; only the browser did. Our buyers arrive through LINE, and its in-app browser drops the client-side tag. Every real sale we had made was invisible to analytics.
The habit this left: for anything a browser might not see, send the event from the server. In one sample, client-side analytics credited 2 of 41 signups to the channel our own database showed was producing most of them.
The traffic was fine. The door was shut.
The first real finding: daily signups had fallen about tenfold in under a week (38, 30, 16, 3, 1, 1) while sessions held flat at 380 to 500 a day. That is a regression, and it lined up with a landing page redesign.
The redesign had pointed the sticky mobile button at LINE's add-friend link. Following the bot creates no website account, so mobile signups went from 84 to 7. We pointed it back at the login page and felt clever for about a day.
Then we split the funnel by source. Over seven days: 3,747 sessions, 1,157 taps on the signup button, 254 people starting a login, 99 signups. Visitors arriving from LINE turned 94 login starts into 56 signups, about 60 percent. Visitors arriving from Facebook and Instagram made roughly 1,150 of those 1,157 taps and produced about 4 signups. A third of a percent.
Facebook and Instagram open links in their own in-app browser. Google refuses OAuth inside embedded webviews, and the OAuth cookie round trip loses its state on the way back. Our signup button was a dead end for nearly all of that traffic, and traffic was at an all-time high.
The fix is small. A token match on the user agent (FBAN, FBAV, Instagram, Line/ and friends) decides whether the visitor is in an in-app browser. If so, every signup button on the landing page becomes a LINE add-friend deep link, which hands off to the LINE app and escapes the webview entirely. Everyone else still gets the login page. Reading the user agent on the server opts the page out of static rendering; for the page the ads point at, that is the right trade.
The funny part: the redesign's button was correct for in-app visitors and wrong for browsers, and our fix was the reverse. The answer was both, chosen per visitor.
They added the bot and said nothing
Sending people into LINE only helps if something happens there. An earlier count of one-to-one chats with the bot had already told us what usually did: 247 chats, 210 of them with zero translations. That is 85 percent. Almost all of the silent ones had never sent a single message. Nothing was failing; the dead-letter queue was empty. People added a translator and then did not know what to do with it.
A later sweep of 1,251 messages across 234 one-to-one chats made it sharper. Of about 114 moments where someone was clearly looking for something, about 75 were for features that already existed. Only 7 were for things we had not built. The root cause is almost comic: a message aimed atthe bot gets translated instead of answered. Type "help" and you receive the word "help", beautifully rendered in Thai.
So a bare "help" now returns the help card and the greeting carries a one-tap "See an example" chip. A free product's first job is to get used once.
What we threw at the trial
- A wall-free payment start. Three quarters of the early trial cohort were LINE followers with no website account, so they could not pay without a separate signup. A tokenized link from the chat now proves who you are, creates the account inline and goes straight to checkout.
- A nudge engine. One tip a day with a countdown, to people on an active trial. Never into a group, and never to someone already paying.
- A win-back that was broken three ways. Its flag was off, the service that sends it held no messaging credential and would have logged a polite skip forever, and nothing scheduled it. We found all three before the first trial lapsed.
By the time the cohort lapsed, 85 people had the start announcement, 116 had daily tips and 84 had the end-of-trial message. They were told, repeatedly, with a working way to pay.
148 trials, 1 paid.
Where it actually broke
The upgrade funnel over 35 days: 22 people viewed the plans, 5 picked one, 3 began checkout, 2 paid. Checkout converts two in three. The payment plumbing is fine. The collapse is before checkout, at "decide this is worth paying for", and no button fixes that.
Of 148, only 35 were activated users. 61 had no account at all. 41 only ever used the bot in groups, and every in-chat offer was limited to one-to-one chats, so they never saw one. And for everyone, the free tier kept translating after the trial ended. What the paid tier adds is quality, much of it in a language the buyer cannot read. Nobody feels the loss of a thing they could not see.
So the honest state is this. The funnel works mechanically: people can get in from any browser, anyone can pay without a login wall, and we can see each step. When the ads wound down, signups fell to about five a week. The binding constraint is traffic and fit: who arrives, and whether the thing we charge for is the thing they feel. That is not a broken button.
What we would tell ourselves earlier
- Measure before redesigning. We shipped a redesign into a funnel we could not see and spent days learning which half of it we had broken.
- The in-app browser is a different platform. Test your signup from inside the apps your ads run in. Ours did not work there.
- A free product's first job is to get used once. 85 percent silence is not a pricing problem.
- Say the unflattering number out loud.1 in 148 was a much better debugging tool than "conversion is a bit soft".
ThaiPo is designed, built and run by one developer, Steven Acreman.
Try it in your own chats
ThaiPo lives inside LINE and translates every message in both directions, free forever. Get started free or add @thaipo.ai as a friend on LINE and it sends your signup link right in the chat.