FitVision
Showing a shopper what a garment looks like on them, without a photoshoot and without a studio.
- Role
- Sole engineer
- Context
- Personal project
- Stack
- Next.js · TypeScript · Prisma
- Status
- Not deployed
Not currently deployed. The source is the best look at this one.
A Next.js application in front of a RunPod GPU worker running the IDM-VTON diffusion model. The interesting engineering is not the model — it is everything around keeping inference reliable and affordable when a cold GPU takes tens of seconds to wake.
The inference path
A request travels from the browser to a Next.js route handler, through Prisma for job state, out to a RunPod serverless GPU worker running IDM-VTON with a CLIP vision encoder, and back. The worker is a container built in CI and pushed to GitHub Container Registry, which is what makes the model version reproducible rather than something that lives on one machine.
Serverless GPU over an always-on box
A dedicated GPU sits idle most of the day and costs the same whether anyone uses it. Serverless trades that fixed cost for a cold start measured in tens of seconds. For a try-on feature where traffic is bursty and nobody expects an instant answer, that is the right trade — provided the interface is honest about the wait rather than pretending the request is instant.
What the cold start costs
The first request after an idle period is dramatically slower than the rest. Hiding that behind an ordinary spinner makes the product feel broken. The job state in Postgres exists so the UI can say which stage the work has reached instead of showing an undifferentiated loading state.
What I would change
The container is pushed to GHCR as a secondary target because pushing to the primary registry was rate-limited. That works, but the fallback is manual. A proper release pipeline would pick a registry by policy rather than by whichever one is not currently refusing the push.
- Next.js
- TypeScript
- Prisma
- PostgreSQL
- RunPod
- IDM-VTON
- CLIP
- Docker
- GitHub Actions
- GHCR