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.

4
AI Tiers
3
Templates
~30s
Generation
$0
Hosting Cost

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:

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:

Tier 1
Gemini 2.5 Flash (Google) — primary, fast, accurate, generous free tier
Tier 2
Llama 3.3 70B Versatile (Groq) — fires when Gemini fails, fits 12K TPM limit
Tier 3
Qwen 3 32B (Groq) — additional safety net
Tier 4
Llama 4 Scout (Groq) — last resort with extra warning to user

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:

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:

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:

Auth
Google + Microsoft OAuth + email/password, JWT cookies, social provider verification
Database
PostgreSQL with Row-Level Security policies — users only see their own data
Storage
5 MB PDF uploads with per-user folder isolation
Cost
$0/month under 50K monthly active users

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:

  1. 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.
  2. 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.
  3. 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:

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.

SM

Smeet Mehta

Senior Data Analyst · Power BI · BI Lead. A decade in analytics, BI, and reporting governance at Accenture & Vodafone. Based in Ahmedabad, India.

LinkedIn · GitHub · X