case study · project

VelaBid: case study

Collector-car auctions where sniping doesn’t work.

role
Founder and solo engineer
status
Invite-only public beta at velabid.com
since
October 2025
stack
TypeScript Turborepo · Next.js · NestJS · Drizzle · PostgreSQL (RDS) · Socket.IO · BullMQ/Redis · Stripe · S3/CloudFront
Soft closelate bids extend the auction
Server-sidebid validation
Public betainvite-only, at velabid.com
01

The problem, and who it’s for

VelaBid is an auction marketplace for rare performance and collector cars, for the people buying and selling them. It has listings, timed auctions, real-time bidding, watchlists, messaging and notifications.

02

Why I built it

In a rare-car auction, trust is the product. Buyers need to know that every bid is real and that the close is fair. Sellers need to know the money is there.

So I built VelaBid around the hard parts: bids checked on the server, a soft close that stops sniping, and escrowed payments that recover from failure.

03

What I built

All of it, as founder and the only engineer: 176 commits from October 2025 to January 2026. Here is an auction’s life, step by step.

  • A TypeScript Turborepo: a Next.js web app, and a NestJS API on PostgreSQL through Drizzle.
  • Listings, timed auctions, real-time bidding over Socket.IO, watchlists, messaging and notifications.
  • Bid validation on the server, safeguards that reject conflicting or invalid bids, and a soft close. Reserve prices and buy-now too.
  • Escrowed payments through Stripe, with automated settlement and payouts. Payments, escrow and settlement are modelled as state transitions with failure recovery.
  • Trust and safety: KYC checkpoints, moderated messaging, dispute handling and a full audit log.
  • An event-driven backend: BullMQ workers on Redis for auctions, settlement and notifications.
  • Media from S3/CloudFront. Observability with OpenTelemetry and Prometheus.
  • Integration tests for the flows that move money or pick a winner: bids, the soft close and settlement.
velabid / an auction’s life (simplified)
Listed
A car goes up for auction. Media is served from S3/CloudFront.
Live
Real-time bidding over Socket.IO. Every bid is validated on the server; conflicting or invalid bids are rejected.
Soft close
A late bid extends the auction, so nobody wins by sniping.
Settlement
Escrowed payments through Stripe, in test mode during the beta. Settlement and payouts are state transitions that recover from failure.
Notified
BullMQ workers on Redis send the notifications.
04

The hard parts, and the decisions

  1. The server decides what counts as a bid.Every bid is validated on the server and placed in a transaction with optimistic locking and an atomic Redis step, so conflicting or invalid bids are rejected.
  2. A soft close, so sniping doesn’t work.A bid that arrives late extends the auction, which gives other bidders time to answer.
  3. Money moves as state transitions.Payments, escrow and settlement are modelled as explicit states, so a failed step can be recovered.
  4. Slow work runs on workers.BullMQ workers on Redis handle auctions, settlement and notifications.
05

What happened

VelaBid is in an invite-only public beta at velabid.com. Listing, bidding, messaging and payout flows all work. Payments run in Stripe test mode, and marketplace fees stay off until general availability.

06

What I’d do next

  • Switch payments from Stripe test mode to live, and turn on marketplace fees.
  • Open the beta beyond invites.
  • Let real auctions show where the soft close and settlement need tuning.
want to talk about it?desirekaleba@gmail.com