When I started building PrismaTest — a multilingual psychology testing platform — I made the classic mistake: I stored every quiz result in PostgreSQL.
It lasted about two weeks before I realized it was a terrible idea.
The Problem
PrismaTest serves 80+ psychological assessments (Big Five, MBTI, Enneagram, IQ tests, career aptitude, and more) translated into 20 languages. Users take tests without registration, get instant visual results with charts and diagrams, and share them with friends.
Storing results in a database created several headaches:
- Privacy concerns — anonymous users don't want their psychological data stored anywhere
- Database bloat — thousands of test completions per day, each with 20-300 answers
- Sharing problem — how do you let users share results without creating accounts?
- GDPR compliance — storing personal psychological assessments is a liability
The Solution: Encode Everything into the URL
Instead of persisting results server-side, I encode the entire test state — answers, scores, and display parameters — into a Base64 URL string. The result page is completely stateless.
Here's the approach:
// After test completion, encode results into URL params
const resultData = {
scores: calculateScores(answers, test.scoring),
display: test.display.type,
timestamp: Date.now()
};
const encoded = Buffer.from(JSON.stringify(resultData)).toString('base64url');
router.push(`/${locale}/tests/${slug}/result?d=${encoded}`);
The result page reads the d parameter, decodes it, and renders everything client-side. No database query, no API call, no stored data.
Benefits
Zero storage costs for results. My PostgreSQL instance stays lean — it only stores user preferences and aggregate statistics, not individual test results.
Instant sharing. Users copy the URL and send it to friends. The friend opens it and sees the exact same result page with all the charts and scores. No authentication needed.
Privacy by design. I literally cannot see your test results because they only exist in your URL. This makes GDPR compliance trivial.
Blazing fast result pages. No server round-trip to fetch data. The result page is a pure client-side render from URL params.
The Tradeoff
The main limitation is URL length. For tests with 300 questions (like IPIP-NEO-300), the encoded string can get long. Most browsers support URLs up to 2,000+ characters, so in practice this hasn't been an issue — but I do compress the data for larger tests.
// For tests with many questions, compress before encoding
import { deflate, inflate } from 'pako';
const compressed = deflate(JSON.stringify(resultData));
const encoded = Buffer.from(compressed).toString('base64url');
Tech Stack
For context, PrismaTest is built with:
- Next.js 14 with App Router — server components for SEO, client components for interactivity
- TypeScript end-to-end
- Tailwind CSS for styling
- PostgreSQL for user data (not quiz results!)
- Redis for caching test metadata
- Docker + Traefik for deployment
- next-intl for 20-language support (EN, ES, DE, FR, PT, RU, JA, KO, AR, and 11 more)
Each test is a single JSON file containing all translations, questions, scoring logic, and result descriptions. Adding a new test = adding one file. No database migrations, no code changes.
Would I Recommend This Approach?
For quiz/assessment platforms — absolutely. If your results are deterministic (same answers → same scores), there's no reason to store them server-side. Put the state in the URL and let the client render it.
For apps where results change over time or need history tracking — stick with a database. But for one-shot assessments, URL state is simpler, faster, and more private.
If you're curious, you can try any test on PrismaTest — everything is free, no registration needed. The Big Five (IPIP-NEO-300) is the most comprehensive one, and the MBTI is the most popular.
Happy to answer questions about the architecture! 🧠
**Ссылки в статье:**
- `https://prismatest.com/en` — главная (3 раза)
- `https://prismatest.com/en/tests/ipip-neo-300` — Big Five тест
- `https://prismatest.com/en/tests/mbti` — MBTI тест
- **Тип ссылки:** Анкор (`PrismaTest`, `multilingual quiz platform`, `Big Five (IPIP-NEO-300)`, `MBTI`)
Top comments (0)