Discover route checks inside Railway
The main-inclusive release candidate passed all eight phases of a bounded Railway testing job: 96 HTTP requests, 1,890 instrumented SQL calls and zero SQL errors. All 713 eligible synthetic story families were reached in fifteen pages without duplicate IDs/families or premature exhaustion. Saving two families left exactly 711 reachable families, including exclusion through a saved translated sibling. This establishes bounded route correctness, not recommendation uplift or production capacity.
Execution and isolation
Code: b4c32d1f150385bcf4ccb3a9ebe7171d36459b01, combining current main with controller 4c724abcd621fa1ef3470c6f45fb3e4c14454192. Runtime was Node 22.23.2 inside a temporary Railway testing service. A new disposable PostgreSQL database received the current schema and the three discovery installers. A new limited role had table CRUD/sequence access and a twelve-connection ceiling; the application pool was capped at eight plus one fixture connection.
The job used only three synthetic accounts, 713 eligible English families, one Spanish sibling and five hard-filter controls. No real catalog, reader history, private chat, provider credentials or model profiles were copied. The parent verified testing Redis differed from production by endpoint and server identity. Only a fresh random Redis namespace was writable. Cursor/measurement were on in this job; semantic personalization and onboarding were off.
Four real route modules, the PostgreSQL driver, Better Auth/Drizzle adapter, recommendation/session code and Redis Lua ran over container-loopback HTTP. Checks verified stored auth sessions and rejection of an unknown token, cursor ownership, committed replay/receipt identity, impression idempotence, confirmed save idempotence, guest identity linkage and translated-family Library exclusion.
The bundle disabled dotenv and inactive local database/image/email-rendering branches. It suppressed import-time intervals, general app Redis and PostHog, and blocked outbound HTTP. It did not start the full application entrypoint or exercise Railway's public proxy/CDN/TLS, production middleware composition, Neon/replica topology, background jobs or a representative production catalog.
Timing observations
Two rounds per actor count issued one first page and one continuation per actor. The following are nearest-rank summaries in milliseconds:
| Concurrent actors | Samples per page type | First page p50 / p95 | Continuation p50 / p95 |
|---|---|---|---|
| 1 | 2 | 374.33 / 398.41 | 127.40 / 142.89 |
| 4 | 8 | 587.92 / 665.14 | 203.05 / 224.95 |
| 8 | 16 | 1,069.18 / 1,341.88 | 263.41 / 419.48 |
Each split's p95 is its maximum because these are tiny samples. Combined first/ continuation p95 at eight actors was 1,329.09 ms. Do not treat these as stable production tail estimates or choose an admission limit from them.
The sampled application pool reached eight connections and 51 pending connection acquisitions. That is not 51 readers or executing SQL statements. The 20 ms gauge records a cumulative maximum, not waiting duration. SQL timers begin at pg.Client.query: they exclude pool-acquisition waiting, and their overlapping durations cannot be subtracted from HTTP latency. The raw report's general "queueing" wording must not be interpreted as measured pool wait. Request attribution captured after checkout also needs tightening before causal profiling.
Every Lua operation awaited a serialized Redis safety audit, including sequential string-length reads. Audits revisited earlier tracked keys after cleanup, so later phases had more audit work. This overhead is included but was not timed separately. Consequently the observed concurrency difference cannot be attributed solely to application SQL, ranking, serialization or Redis.
Raw encoding peaked at 7,345,727 bytes of sampled owned Redis memory and 6,989,038 bytes of sampled aggregate string payload. The latter is not one session's body. Limits were 400 HTTP requests, twenty thousand instrumented SQL calls, eight minutes of work, a 16 MiB synchronous payload reservation and a 32 MiB sampled memory stop. Sampling does not prove a hard transient memory ceiling.
Cleanup and next check
Runtime cleanup closed the server, timers, SQL pool/clients and Redis connection, then verified zero remaining keys among 69 exact tracked keys. Parent cleanup independently rechecked the complete owned namespace, found it empty, and removed the temporary service, database and role. No forced disconnect, shared-table reset or production write was used. Independent review covered the guards and cleanup; 23 offline guard tests and both zero-network import checks had passed before deploy.
The next profiling target is the first page: capture context at SQL submission, time pool acquisition separately, and distinguish query groups, retrieval/ranking, Redis I/O and audit queue/execution. Correct the accumulating audit overhead before comparing concurrency or changing pool sizes. Full deployment capacity, complete CDC/erasure observations and reader-outcome experiments remain separate gates.
Ignored evidence: origin-controller-result.json (SHA-256 940a8b95860c1af24a3338f2ec657be10a68a3fb14bf7151d8b0cfa1f7978bc1), origin-controller-resource.json, the runtime logs and full-origin-* bundle, guard tests, build manifest and reproduction instructions. The frozen artifact is retained with the interpretation corrections above.
