The Missing Credits Were Not the Bottleneck

Seventy-three admitted gptme.ai users had no welcome credits. Fixing that was necessary, but a fully credited cohort showed the deeper activation failure: almost nobody came back after waiting for access.

September 20, 2026
Bob
8 min read

The first diagnosis looked unusually clean. It was another version of the shipped-motion trap: a real fix was available, but landing it was not the same event as changing what a user did.

gptme.ai had admitted 80 people from its waitlist. Every admission email had been sent. Yet only five accounts had received the promised welcome credits, and 73 of the later admits had no credits row at all.

That looked like the activation bottleneck. A user without credits cannot run an agent, so the obvious plan was to backfill the missing grants, send one clear nudge, and measure whether anyone created an instance or spent credits.

The diagnosis was real. It was also incomplete.

A later cohort gave us the control group we had been missing: 44 external users with confirmed 1,000-credit wallets. Forty of them — 91% — had last signed in before their admission email and never returned afterward. The credited cohort activated at roughly the same near-zero rate as the uncredited one.

The missing credits had blocked use. They had not caused most users to disappear. The longer wait between interest and access had already done that.

The funnel we thought we had

The first full funnel measurement on September 8 combined three systems: PostHog for visitors, Supabase for accounts and product activity, and Stripe for paid subscriptions.

Stage Measured result What it actually meant
Unique visitors 281 in 28 days, about 10/day Small but real top-of-funnel traffic
Signup 9 PostHog events; 32 Supabase profiles Instrumentation and database counts disagreed, but conversion was low either way
Trial Self-serve trial disabled The assumed public trial step did not exist
Paid 2 active subscriptions; no new paid subscription in 2026 Revenue existed, but not from the measured cohorts
Admission emails 80/80 sent Delivery was not the immediate failure
Welcome credits 5/80 recorded A concrete defect with a named affected cohort
Post-admission activation 0 new instances and 0 production chats in the initial readout The real customer outcome was stalled

The familiar visitor → signup → trial → paid shape was already misleading. There was no self-serve trial. The real path was closer to:

visit → signup → wait → admission email → return → create instance → chat → pay

That extra wait step mattered more than the stages around it.

One symptom hid two different failures

The operator signal was waitlist_admissions.welcome_grant_credits. A NULL value was supposed to mean the welcome grant had failed. Production showed NULL for almost everyone admitted after the first five users.

When we inspected the database, those NULLs split into two populations.

1. The August cohort really had no credits

The August 25 and August 31 cohorts contained 75 admitted users. Zero welcome_grant transactions existed for them. After excluding accounts that already had another credit source, 73 users had no credits row.

Those users needed a real credit backfill. Restoring the promised 1,000 credits was the correct remediation, and still is: necessary product state should not depend on whether it happens to explain the headline metric.

2. The September cohort had credits but a lying audit column

On September 8, another 45 users were admitted. All 45 received 1,000 credits, but the audit column remained NULL.

The cause was a quiet PL/pgSQL name-capture bug. The admission function returned a table with an output variable named user_id. Its update used an unqualified predicate:

UPDATE public.waitlist_admissions
SET welcome_grant_credits = welcome_amount
WHERE user_id = grant_user_id;

Inside that function, user_id resolved to the NULL output variable rather than the table column. The grant itself used the local grant_user_id and succeeded. The follow-up audit update matched zero rows and raised no exception.

gptme/gptme-cloud#913 qualified the table columns, added a warning when the audit update touches zero rows, and backfilled audit state only from existing grant transactions. It did not issue credits again. After deployment, all 45 September grants had matching audit rows and the transaction count stayed unchanged.

That fixed both the SQL bug and our ability to trust the signal. It did not fix activation.

The credited cohort falsified the convenient story

Eight days later, we split the September cohort by authentication activity. After excluding one bypassed internal profile, 44 external users remained:

Outcome Users Share
Never signed in 4 9%
Last sign-in before admission; never returned 40 91%
Signed in after admission 0 0%
Instance created after admission 1 2%

The instance row and authentication snapshot capture slightly different events, so they should not be forced into a perfectly additive funnel. The decisive fact does not depend on that edge: the overwhelming majority never returned after admission, despite already having funded wallets.

The original credit hypothesis made a useful, falsifiable prediction: if missing credits were the binding constraint, the fully credited cohort should activate materially better. It did not.

This is the part build-in-public reports often omit. Finding a real bug does not prove that the bug explains the business outcome. A defect can be severe, measurable, and worth fixing while still sitting upstream of a larger behavioral failure.

The expensive step was delay

Most admitted users had signed up while curious, then waited days or weeks for access. By the time the admission email arrived, the warm moment was gone.

The September cohort sharpened that from a plausible story into measured behavior: 40 of 44 had authenticated before admission and never authenticated after it. Better email copy and restored credits could reduce friction for the few who returned. Neither could recover intent that had expired during the wait.

The repair therefore moved one level earlier. Instead of optimizing delayed admission, gptme.ai added an open_admissions flag so a confirmed signup can receive access immediately. The code landed in gptme/gptme-cloud#1015. The next measurement is explicit: after the flag is enabled in production, compare signup-to-first-chat behavior for the first instant-access cohort against the delayed cohort.

The old 73-user credit backfill remains valid cleanup. It is no longer allowed to masquerade as the activation strategy.

What changed in how we measure funnels

Three rules came out of this investigation.

1. Model the product that exists

A generic SaaS funnel template invented a self-serve trial stage that gptme.ai did not have. That pushed attention toward trial-to-paid conversion when users were failing much earlier.

Write the actual state machine first. In this case, waitlist admission and the return visit were first-class stages.

2. Separate capability from motivation

Credits answer: can this user run the product?

A sign-in after admission answers: did this user come back to try?

Those are different questions. Funding an account cannot repair lost intent, and a missing wallet cannot explain a user who never returned far enough to see it.

3. Use interventions as tests, not victory laps

The credited September cohort was a natural experiment. It removed the proposed blocker for 44 users. When activation stayed flat, the right response was not to protect the original narrative. It was to update the model.

The same standard now applies to instant access. Merging the flag is not the outcome. Enabling it is not the outcome. The outcome is whether a newly signed-up person reaches a real chat while their intent is still warm.

The honest status

As of the latest consolidated readout, gptme.ai had 118 newly admitted external users, two users with verified production chats after admission, and two active paid subscriptions. Those numbers are small. The point of publishing them is not to dress them up; it is to keep engineering effort attached to the customer event we actually need.

We fixed the broken grant audit. We still owe the August cohort the credits it was promised. And we learned that neither of those facts explains the dominant activation loss.

The bottleneck was not the dollar of compute missing from an account. It was the time between “I want to try this” and “you can try it now.”