Work - Budkrig
Budkrig
A public pay-to-rank leaderboard for the Swedish market. Anyone can put a product link or an @handle on the board and pay to hold a spot - rank is decided by the amount paid, nothing else. Bids are cumulative, non-refundable, and never expire.
- Role
- Architecture · Development
- Stack
- Next.js · TypeScript · PostgreSQL · Drizzle · Redis · BullMQ · Stripe

“Budkrig” is Swedish for bidding war, and the site is exactly that: one public leaderboard where the only thing that sets your rank is how much you have paid to hold it. It is a Swedish-market take on outbid.lol (opens in a new tab) - anyone can add a product link or an @handle, pay to claim a position, and get bumped the moment someone pays more.
What it does
- Claim a rank. Add a link or @handle, pick a category, and pay to take a spot. To pass the listing above you, you cover the difference over what they paid.
- Cumulative, non-refundable bids. The amount you pay becomes the new floor for the next challenger. Nothing decays and nothing expires - a position holds until someone outbids it.
- Swedish payment methods. Stripe Checkout with Swish, Klarna, and cards. The full claim -> Checkout -> webhook -> queued fulfilment loop is built and tested.
- Categories, time windows, click tracking. The board filters by category and by “today” versus “all time”, and every listing counts the outbound clicks it has sent.
How it’s built
| Layer | Choice |
|---|---|
| Framework | Next.js (App Router, TypeScript) |
| Database | PostgreSQL with Drizzle ORM |
| Queue | Redis + BullMQ for asynchronous payment fulfilment |
| Payments | Stripe Checkout - Swish, Klarna, cards - reconciled by webhook |
| UI | Tailwind + shadcn/ui |
| Hosting | Self-hosted on Coolify |
The interesting part is the money model. Bids only ever go up, they are non-refundable, and ranks have to stay consistent while several people claim at once - so a payment that half-completes must never leave the board in a bad state. The flow is deliberately asynchronous: a claim writes a pending record, Stripe confirms out of band, and a BullMQ worker is what actually promotes the listing. It is documented the way I would hand it to a team - an architecture brief with C4 diagrams, a domain model that writes down every invariant, ADRs for the decisions, and a ranked risk register.
Status
Deployed at budkrig.viktordo.dev (opens in a new tab) with the board, the claim flow, the redirect handler, and the legal pages all live. The payment loop is built and tested end to end; taking real money is one Stripe key away.