I built Resume Tailor over a few weeks in early 2026. It's a SaaS for job seekers — upload your resume, paste a job description, and get back a tailored resume + cover letter + recruiter outreach materials in about 30 seconds.
Most "AI resume tools" you've seen produce generic output, hallucinate skills you don't have, or paste your details into a template that screams "AI-generated." I wanted to prove that a focused tool with proper engineering — anti-hallucination prompts, output validation, fallback chains, real PDF rendering — could ship something a recruiter actually wouldn't immediately discard.
This post walks through what's interesting under the hood. It's written for anyone considering shipping their own AI app, especially on a tight budget.
The problem worth solving
I was applying for senior data analyst roles in India in late 2025. Every job description was different. Each company emphasized different things — some wanted Power BI depth, others healthcare claims experience, others process automation. Tailoring my resume manually was taking 45 minutes per application.
I tried the existing AI tools. Three problems consistently:
- Hallucinations. Tools added skills I didn't have because they appeared in the JD. "Oh, the JD mentions Snowflake? Let's add Snowflake to your resume." This is dangerous — recruiters check.
- Generic output. The cover letters were so formulaic you could spot them from across the room. "I am writing to express my keen interest in this role at your esteemed organization..." dead on arrival.
- Bland templates. Single-column Word-doc styling, mismatched fonts, no real typography. Recruiters scan for visual quality before content quality.
So I built my own. The constraints I gave myself: preserve every fact from the source (no hallucinations), name the company explicitly, and render PDFs at LaTeX quality.
The architecture in one diagram
The whole flow is:
User uploads PDF + pastes JD
│
▼
PDF parser (pdf-parse) extracts text
│
▼
AI orchestration (4-tier fallback chain)
│
▼
Output validator (counts roles/certs/bullets vs source)
│
▼
LaTeX template (Classic / Modern / Compact)
│
▼
Tectonic compiler → PDF
│
▼
Stream to user
Front-end: Next.js 16 with React 19. Auth: Supabase. AI: Google Gemini primary, Groq for fallbacks. PDF: Tectonic (single-binary LaTeX engine). Hosting: Oracle Cloud Free Tier (yes, $0/month, more on this below).
The interesting part: 4-tier AI fallback chain
The single most important architecture decision: don't trust any single AI provider.
I learned this the hard way. During testing, Google's Gemini API hit a 503 outage that lasted hours. Every generation failed with "This model is currently experiencing high demand." — and Gemini wasn't returning. If I'd built only on Gemini, my product would've been dead in the water.
The fallback chain I ended up with:
Each tier gets up to 4 retry attempts with exponential backoff (2s, 3s, 4.5s, 6.75s) before falling through. Total Gemini wait: up to ~17 seconds before moving to Tier 2.
When fallback fires, the user sees a clear amber banner on the results page: "Generated using backup AI — please review extra carefully." Transparent about what's happening rather than hiding it.
Lesson: If your app's value depends on an external API, assume it'll fail at the worst time. Building a fallback chain isn't paranoia — it's the difference between "down for hours" and "users got slightly different output."
The hardest bug: validating that the AI didn't drop content
LLMs sometimes "compress" output. You feed in a resume with 39 certifications and ask for tailoring; sometimes you get back 22 certifications because the model decided to be concise. This is a silent failure — the output looks fine until you compare side-by-side.
I built a validator that runs after every generation:
// Source counts (from input PDF text)
function estimateSourceCounts(resumeText) {
// Count work history entries by year ranges,
// excluding school years (Class X, Class XII)
const roleCount = countRolesExcludingSchools(lines);
const certCount = countCertsBySection(lines);
const bulletCount = countBullets(lines);
return { roleCount, certCount, bulletCount };
}
// After AI returns, compare
if (output.roles.length < source.roleCount * 0.75) {
warnings.push("Possibly dropped roles: source ~" + source.roleCount);
}
The validator's heuristic isn't perfect — sometimes it under-counts. But it's conservatively biased in the right direction: false negatives are fine, false positives would just bother users. If the AI's output is genuinely shorter than expected, the user sees a warning and can regenerate.
Why I picked LaTeX over HTML-to-PDF
The pure-JavaScript route is tempting: build the resume in HTML, use Puppeteer or React-PDF to convert. It works on serverless, no system binaries needed.
But HTML-to-PDF has fundamental problems for resumes:
- Page break control is fragile. Bullets can split across pages mid-sentence.
- Font rendering varies. Output looks different than the preview.
- Multi-column layouts (certifications) are awkward. CSS columns work poorly when content has variable height.
- It looks like an HTML document, not a designed resume. Recruiters notice.
LaTeX solves all of these. It was built for academic papers — page breaks, columns, typography are first-class. The trade-off: you need a LaTeX compiler installed.
I picked Tectonic — a single-binary LaTeX engine that downloads required packages on first run, then runs offline. Easy to install on a VM, hard to use on serverless.
This forced a hosting decision.
Why Oracle Free Tier (and not Vercel/Cloudflare)
Cloudflare Pages and Vercel are wonderful for static sites and serverless apps. They were the wrong fit here for two reasons:
- Tectonic LaTeX needs a system binary. Serverless platforms don't let you install one.
- 30-second timeout. Cloudflare Workers cap at 30 seconds. My slow generations (Gemini under load) hit 45+ seconds. Would've failed.
Oracle Cloud has a genuinely free tier (forever, not a trial) that gives you a small ARM VM with 1 GB RAM and 4 cores. With 2 GB swap added, it runs Next.js + nginx + Tectonic comfortably.
Total monthly hosting cost: $0. The catch is operational overhead — I manage the VM, SSL renewal, deploys, security patches. Worth it for a side project; might not be for a team.
The Supabase decision
I needed auth (Google OAuth, Microsoft, email/password), a database for users + generation history, and file storage for saved resumes. Self-hosting all of that on the same 1GB VM = death.
Supabase's hosted free tier covers all three:
One subtle issue: Supabase's auth cookies are larger (~6-8 KB) than typical session cookies. nginx's default header buffer (4KB) returned 502s on every authenticated request. Took me 30 minutes to debug, 1 minute to fix:
# /etc/nginx/sites-enabled/resume
large_client_header_buffers 4 16k;
proxy_buffer_size 16k;
proxy_buffers 8 16k;
What I'd do differently
Three things I'd change if I started over:
- Build the validator first, not last. I shipped without it and only added it after seeing the AI silently drop content. Should've been day-one.
- Skip GPT-OSS 120B. I tried it as Tier 2 originally. Groq's free tier limits it to 8K tokens-per-minute, but my prompts are 11K tokens. Never worked once. Cut from the chain.
- Start with a single template. I built three (Classic, Modern, Compact) before having any users. Should've shipped with one and added more based on feedback.
What's next
The product is live. Real users are generating real resumes for real applications. Next priorities:
- Payments (Cashfree). Free tier is 5 generations / 30 days; paid tier removes the cap. Pricing TBD — collecting upgrade requests via email first to validate willingness-to-pay.
- Resend email integration. Currently using Microsoft 365 SMTP for sending PDFs to users; Resend would be cleaner.
- Analytics dashboard. Admin-only view of total generations, fallback rates, average generation time.
If you're building something similar, two takeaways:
Don't trust any single AI provider. Build a fallback chain. Test it during a real outage before relying on it.
Free-tier infrastructure works. Oracle + Supabase + Cloudflare DNS = $0/month for production-grade hosting if you're willing to manage some ops.
Try Resume Tailor
Upload your resume, paste a job description, get tailored output in 30 seconds. Free for 5 generations a month.