LLD Hub
lldstrategytemplate-methodstate-machine

How to Design a Hotel Booking System (OYO) | LLD Guide

Design a hotel booking platform with room availability, dynamic pricing, cancellation policy, and concurrent reservation safety. Common in product-based SDE rounds.

17 April 2025·8 min read

Practice this problem

Hotel Booking System — get AI-scored feedback on your solution

Solve it →

Designing a Hotel Booking System tests your ability to handle date-range availability, dynamic pricing, multiple room types, and cancellation policies — a great intermediate LLD problem frequently asked at OYO, MakeMyTrip, Cleartrip, and Expedia interviews.

Core Entities

  • Hotel — name, location, amenities, rating
  • Room — number, type, floor, base price
  • RoomType — Single, Double, Suite, Deluxe
  • Reservation — guest, room, checkIn, checkOut, status, price
  • Guest — profile, reservation history
  • PricingRule — defines price multipliers for dates/seasons

Availability Check

class RoomRepository {
  findAvailable(hotelId: string, checkIn: Date, checkOut: Date, type: RoomType): Room[] {
    const allRooms = this.getRoomsByType(hotelId, type);
    const bookedRoomIds = this.reservationRepo.getBookedRoomIds(hotelId, checkIn, checkOut);
    return allRooms.filter(r => !bookedRoomIds.has(r.id));
  }
}

Dynamic Pricing with Strategy

interface PricingStrategy { getPrice(room: Room, checkIn: Date, checkOut: Date): number; }

class DynamicPricing implements PricingStrategy {
  getPrice(room: Room, checkIn: Date, checkOut: Date): number {
    let total = 0;
    for (let d = checkIn; d < checkOut; d.setDate(d.getDate() + 1)) {
      let dayPrice = room.basePrice;
      if (this.isWeekend(d))  dayPrice *= 1.25;
      if (this.isPeakSeason(d)) dayPrice *= 1.5;
      total += dayPrice;
    }
    return total;
  }
}

Cancellation Policy with Template Method

abstract class CancellationPolicy {
  cancel(reservation: Reservation): CancellationResult {
    const refund = this.calculateRefund(reservation);
    reservation.status = ReservationStatus.CANCELLED;
    this.paymentService.refund(reservation.paymentId, refund);
    return { refunded: refund };
  }
  abstract calculateRefund(res: Reservation): number;
}

class FreeCancellationPolicy extends CancellationPolicy {
  calculateRefund(res: Reservation) {
    const hoursToCheckIn = (res.checkIn.getTime() - Date.now()) / 3600000;
    return hoursToCheckIn > 24 ? res.totalPrice : res.totalPrice * 0.5;
  }
}

Common Questions

  • "How do you prevent double booking?" → DB unique constraint on (roomId, date range overlap) + optimistic locking
  • "How do you support early check-in?" → Add checkInTime field; pricing adjusts for partial day
  • "How do you show room recommendations?" → Strategy for ranking (price, rating, availability)

Ready to practice?

Submit your solution and get AI-scored feedback on OOP, SOLID principles, design patterns, and code quality.

Solve Hotel Booking System