Auctune — Auction & Bidding Platform
Real-Time WebSocket Bidding with Anti-Sniping Protection
Real-time online auction marketplace featuring auto-bidding algorithms, countdown timers, anti-sniping protection, seller listings, and payment settlement. Built to guarantee bid integrity under heavy concurrent load.
Architecture & System Design
Bid placement runs inside a locked database transaction to guarantee atomicity, with confirmed bids broadcast over WebSockets to every connected viewer. Auctions nearing close auto-extend their countdown to prevent last-second sniping.
- Pessimistic row-locking on bid placement to prevent race conditions under load
- WebSocket broadcasting for instant bid updates across all connected viewers
- Anti-sniping logic that auto-extends the countdown on late bids
- Escrow-based payment settlement triggered on auction close
Engineering Challenges
Race Conditions on Simultaneous Bids
Multiple bidders submitting near-identical bids at the same instant risked accepting an invalid or stale bid as the winner.
Implemented database row-level locking with atomic bid validation inside a single transaction before any bid is accepted.
Zero invalid concurrent bid acceptances observed under load testing with 250+ concurrent bidders.
Last-Second Bid Sniping
Bidders were winning auctions by placing bids in the final second, leaving no chance for others to respond.
Added an auto-extending countdown that pushes the auction end time out whenever a bid lands inside the closing window.
Sniping-related disputes reduced to near zero.
Real-Time State Synchronization
All connected viewers needed to see the current bid state instantly and consistently, even under high concurrency.
Used server-authoritative WebSocket broadcasting so every client reconciles against the same confirmed bid state.
Bid updates propagate to all viewers in under 100ms.
Core Features
Real-Time Bid Broadcasting
WebSocket-powered live bid updates visible to every connected viewer instantly.
Clean Code
1<?php23namespace App\Services;45use App\Models\Auction;6use App\Events\BidPlaced;7use Illuminate\Support\Facades\DB;89class BidService10{11 public function placeBid(Auction $auction, int $userId, float $amount): void12 {13 DB::transaction(function () use ($auction, $userId, $amount) {14 $locked = Auction::where('id', $auction->id)15 ->lockForUpdate()16 ->firstOrFail();1718 if ($amount <= $locked->current_bid) {19 throw new \DomainException('Bid too low');20 }2122 $locked->bids()->create(['user_id' => $userId, 'amount' => $amount]);23 $locked->update(['current_bid' => $amount]);2425 if ($locked->ends_at->diffInSeconds(now()) <= 30) {26 $locked->update(['ends_at' => $locked->ends_at->addSeconds(30)]);27 }2829 broadcast(new BidPlaced($locked))->toOthers();30 });31 }32}