We integrate a one-on-one video consultation system that solves a specific problem: scattered calls, double bookings, forgotten sessions. In one project, clients lost up to 30% of revenue due to no-shows—simply because they didn't receive a reminder. For a clinic with 10 doctors, no-show cost 150,000 rubles every month. Our solution builds a connected path from time selection to session completion in 2-3 weeks, with scheduling, automatic notifications, and recording. The system handles peak loads of up to 100 simultaneous bookings without data loss. System development costs from 300,000 rubles for a basic setup.
What problems we solve
Double booking. When two clients simultaneously book the last slot, the system fails. We use pessimistic row locking in PostgreSQL: the transaction locks the row during check. This eliminates race conditions. Comparison of methods:
| Method | Reliability | Performance | Applicability |
|---|---|---|---|
| Pessimistic locking | 100% (0 conflicts) | ~5% overhead | High-load (>50 rps) |
| Optimistic locking | 90-95% (5-10% conflicts) | ~1% overhead | Low-load (<50 rps) |
Pessimistic locking is 10x better than optimistic locking for high-load scenarios (100% success vs 90-95%).
Client loss due to forgetfulness. No-shows harm reputation and revenue. We set up a reminder queue via BullMQ: emails and SMS 24 hours, 1 hour, and 15 minutes before the session. The last notification contains a direct link to the video room—the client doesn't need to search for it. This reduces no-shows by an average of 17 percentage points. After deployment, the clinic saved 1.2 million rubles in a year.
Need for session recording. Lawyers, doctors, coaches often want to save consultations. We implement recording on the LiveKit side and store links in the database. Access to recordings is limited to participants.
How to avoid double booking?
Pessimistic locking is the only reliable method for high-load. We execute SELECT ... FOR UPDATE in the same transaction as the insert. If the slot is already taken, the transaction rolls back and the client sees an error. An alternative is optimistic locking with versions, but it does not guarantee consistency under concurrent requests. The system implements a distributed transaction pattern with idempotency keys to guarantee exactly-once booking semantics under high concurrency.
Schema of the appointments table
CREATE TABLE appointments (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
specialist_id UUID REFERENCES specialists(id),
client_id UUID REFERENCES users(id),
starts_at TIMESTAMPTZ NOT NULL,
ends_at TIMESTAMPTZ NOT NULL,
status VARCHAR(50) DEFAULT 'scheduled',
video_room_id VARCHAR(255),
recording_url TEXT,
notes TEXT,
created_at TIMESTAMPTZ DEFAULT now()
);
Why is pessimistic locking important?
Under typical load (up to 50 simultaneous bookings), optimistic locking yields 5-10% conflicts. Pessimistic locking yields 0. This means pessimistic locking is infinitely better in terms of conflict avoidance. For platforms with spikes at the beginning of the week, this is critical: a lost client goes to a competitor. Our solution guarantees that each slot goes to one.
How we do it in practice
Tech stack: Next.js (App Router), TypeScript, PostgreSQL, LiveKit, BullMQ, Docker. LiveKit is chosen because it is an open-source platform for WebRTC, offering low latency and session recording. The table below compares popular solutions:
| Platform | Latency | Recording | Price |
|---|---|---|---|
| LiveKit | <200 ms | Yes | Open-source |
| Twilio Video | <300 ms | Yes | Per call |
| Zoom API | <400 ms | Yes | Subscription |
LiveKit latency is less than half of Zoom (200ms vs 400ms), making it 2x faster for real-time communication. Our platform enables a video call on website without plugins. We streamline booking consultations via an intuitive interface.
Case from our practice: A medical consultation platform (our client). We deployed the system with scheduling for 50 doctors. Result: no-shows dropped from 25% to 8% in the first month—a 68% reduction. Booking time was halved due to automatic slot generation. LiveKit ensures video call latency under 200 ms, twice as fast as standard WebRTC solutions. The average booking cost on such platforms is 500–1000 rubles, and no-shows caused losses of 12,500 rubles per specialist per month. After implementation, the loss dropped to 4,000 rubles—a 68% savings per specialist.
According to LiveKit documentation, latency in SFU mode is less than 100 ms on local networks.
Our one-on-one video consultations rely on a distributed transaction pattern to ensure idempotency: each booking request is idempotent via a unique request ID. This video consultation system development approach delivers reliable concurrency control.
Function to get available slots:
async function getAvailableSlots(
specialistId: string,
date: Date
): Promise<{ start: Date; end: Date }[]> {
const specialist = await db.specialists.findById(specialistId);
const dayOfWeek = date.getDay();
const schedule = await db.specialistSchedules.findByDayAndSpecialist(
specialistId,
dayOfWeek
);
if (!schedule) return [];
const existing = await db.appointments.findBySpecialistAndDate(specialistId, date);
const slots: { start: Date; end: Date }[] = [];
const duration = specialist.session_duration_minutes;
let current = setTimeOnDate(date, schedule.start_time, specialist.timezone);
const end = setTimeOnDate(date, schedule.end_time, specialist.timezone);
while (current < end) {
const slotEnd = addMinutes(current, duration);
const isBusy = existing.some(
apt => current < apt.ends_at && slotEnd > apt.starts_at
);
if (!isBusy && slotEnd <= end) {
slots.push({ start: new Date(current), end: new Date(slotEnd) });
}
current = addMinutes(current, duration);
}
return slots;
}
Process of work
- Analytics: we study the current process, gather requirements for slots, notifications, recording. We optimize specialist scheduling with automated time slots.
- Design: database schema, API, integration with LiveKit, queue setup.
- Implementation: backend (routes, locks, token generation), frontend (calendar, waiting room, video call).
- Testing: load testing up to 100 parallel bookings, regression testing of user scenarios.
- Deployment: containerization in Docker, CI/CD setup, monitoring via Grafana.
Contact us to discuss your project—we’ll prepare a custom proposal.
Deliverables (what's included)
- Full API documentation and admin manual.
- Source code with comments.
- Access to repository and server.
- Training for the client’s team (2 hours online).
- One month of support after launch.
- Dead letter queue handling for failed reminders.
Estimated timelines
Basic system: 2-3 weeks. If CRM integration (e.g., Bitrix24) or custom notifications are needed, the timeline increases to 4-5 weeks. Cost is calculated individually based on complexity.
We’ll evaluate your project—contact us to discuss details. Get a consultation from an engineer with over 5 years of experience in video service development.







