<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dhruv verma</title>
    <description>The latest articles on DEV Community by Dhruv verma (@dhruvermafz).</description>
    <link>https://dev.to/dhruvermafz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1006993%2F63630ded-4660-4ce2-bf95-a6a3cab32e4e.jpeg</url>
      <title>DEV Community: Dhruv verma</title>
      <link>https://dev.to/dhruvermafz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dhruvermafz"/>
    <language>en</language>
    <item>
      <title>Building a High-Concurrency Railway Reservation Engine</title>
      <dc:creator>Dhruv verma</dc:creator>
      <pubDate>Wed, 16 Sep 2026 06:37:23 +0000</pubDate>
      <link>https://dev.to/dhruvermafz/building-a-high-concurrency-railway-reservation-engine-228f</link>
      <guid>https://dev.to/dhruvermafz/building-a-high-concurrency-railway-reservation-engine-228f</guid>
      <description>&lt;h3&gt;
  
  
  Designing a Railway Booking System Where Double-Booking Is Not an Acceptable Failure
&lt;/h3&gt;

&lt;p&gt;Most railway booking projects begin with a relatively simple idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Find a train → choose a seat → make a payment → confirm the ticket.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The difficult part begins when hundreds or thousands of users attempt to book the same limited inventory at almost exactly the same time.&lt;/p&gt;

&lt;p&gt;If two users see the same seat as available and both successfully reserve it, the system has violated one of the most fundamental invariants of a reservation system:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One inventory item cannot be allocated to two passengers for overlapping journeys.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That problem became the central focus of this project.&lt;/p&gt;

&lt;p&gt;I built a railway reservation engine from scratch in &lt;strong&gt;Go and PostgreSQL&lt;/strong&gt;, focusing less on recreating the IRCTC interface and more on the backend engineering problems behind a high-contention reservation system.&lt;/p&gt;

&lt;p&gt;The project is inspired by railway reservation systems such as IRCTC/PRS, but it is not intended to reproduce their internal implementation.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Imagine a train with 100 seats.&lt;/p&gt;

&lt;p&gt;At 10:00:00.000, seat A1 is available.&lt;/p&gt;

&lt;p&gt;Two users send requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User A → Book A1
User B → Book A1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both requests reach the backend nearly simultaneously.&lt;/p&gt;

&lt;p&gt;A naïve implementation might perform:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;seats&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'A1'&lt;/span&gt;
&lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'AVAILABLE'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;followed by:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;seats&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'BOOKED'&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'A1'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem is that both transactions can potentially observe the seat before either transaction has committed its update.&lt;/p&gt;

&lt;p&gt;The result can become:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User A → A1
User B → A1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application has now sold the same inventory twice.&lt;/p&gt;

&lt;p&gt;This isn't merely a theoretical problem.&lt;/p&gt;

&lt;p&gt;Reservation systems are fundamentally &lt;strong&gt;concurrency-control systems&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The UI, REST API and payment integration are secondary to one question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What happens when multiple valid requests compete for the same inventory simultaneously?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  Project Goal
&lt;/h1&gt;

&lt;p&gt;The goal of this project was to build a reservation engine with a strong correctness invariant:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The same inventory cannot be allocated to overlapping journeys.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of relying on a single application-level check, I designed multiple layers of protection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    HTTP Request
                         │
                         ▼
                  Reservation API
                         │
                         ▼
                 Idempotency Layer
                         │
                         ▼
                 Allocation Engine
                         │
              ┌──────────┴──────────┐
              ▼                     ▼
       Candidate Discovery     Lock Ordering
              │                     │
              └──────────┬──────────┘
                         ▼
                 PostgreSQL Transaction
                         │
                         ▼
              Re-validation + Allocation
                         │
                         ▼
              Database Constraint
                         │
                         ▼
                  Inventory State
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important design principle is that the database remains the final authority.&lt;/p&gt;




&lt;h1&gt;
  
  
  Technology Stack
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Backend
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Go 1.22+&lt;/li&gt;
&lt;li&gt;&lt;code&gt;net/http&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;PostgreSQL 15+&lt;/li&gt;
&lt;li&gt;SQL migrations&lt;/li&gt;
&lt;li&gt;PostgreSQL transactions&lt;/li&gt;
&lt;li&gt;PostgreSQL row locking&lt;/li&gt;
&lt;li&gt;GiST exclusion constraints&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Concurrency &amp;amp; Reliability
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SELECT ... FOR UPDATE&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Canonical lock ordering&lt;/li&gt;
&lt;li&gt;Bounded retries&lt;/li&gt;
&lt;li&gt;Jittered retries&lt;/li&gt;
&lt;li&gt;Idempotency keys&lt;/li&gt;
&lt;li&gt;Transactional outbox&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FOR UPDATE SKIP LOCKED&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Domain Components
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Inventory&lt;/li&gt;
&lt;li&gt;Allocation&lt;/li&gt;
&lt;li&gt;Reservations&lt;/li&gt;
&lt;li&gt;Payments&lt;/li&gt;
&lt;li&gt;Waitlist&lt;/li&gt;
&lt;li&gt;RAC&lt;/li&gt;
&lt;li&gt;Quotas&lt;/li&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;RBAC&lt;/li&gt;
&lt;li&gt;Event publishing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The repository currently contains 15 database migrations and separate packages for these major domains.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Most Important Design Decision: Segment-Based Inventory
&lt;/h1&gt;

&lt;p&gt;One subtle problem with railway inventory is that a seat isn't necessarily unavailable for an entire train journey.&lt;/p&gt;

&lt;p&gt;Consider a route:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Delhi → Agra → Gwalior → Bhopal → Nagpur
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suppose passenger A books:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Delhi → Gwalior
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same physical seat could potentially be allocated to passenger B for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Gwalior → Nagpur
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Therefore, inventory isn't simply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;seat = occupied / free
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is actually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;seat + journey segment + time/range
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This led to representing allocations using segment ranges.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Seat A1

Delhi ───── Agra ───── Gwalior ───── Bhopal ───── Nagpur
       [──────────────]
          Passenger A

                            [──────────────────────]
                              Passenger B
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These allocations don't overlap.&lt;/p&gt;

&lt;p&gt;But this would be invalid:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Seat A1

Delhi ───── Agra ───── Gwalior ───── Bhopal ───── Nagpur
       [──────────────────────]
                Passenger A

                  [────────────────]
                    Passenger B
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database therefore needs to understand &lt;strong&gt;range overlap&lt;/strong&gt;, not simply a boolean seat status.&lt;/p&gt;




&lt;h1&gt;
  
  
  PostgreSQL as the Final Safety Layer
&lt;/h1&gt;

&lt;p&gt;The most important piece of the system is a PostgreSQL exclusion constraint.&lt;/p&gt;

&lt;p&gt;The inventory allocation table contains a constraint equivalent to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;EXCLUDE&lt;/span&gt; &lt;span class="k"&gt;USING&lt;/span&gt; &lt;span class="n"&gt;gist&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;inventory_id&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;segment_range&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'HELD'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'CONFIRMED'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a database-level invariant:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Same inventory
      +
Overlapping segment
      +
Active reservation
      ↓
       REJECT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In other words, even if an application bug somehow causes two concurrent transactions to attempt the same allocation, PostgreSQL remains the final line of defense.&lt;/p&gt;

&lt;p&gt;The project explicitly treats this constraint as the ultimate correctness mechanism rather than relying exclusively on application-level checks.&lt;/p&gt;

&lt;p&gt;This is one of the most important lessons from the project:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Concurrency correctness should not depend on application code alone.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  Why Locking Alone Isn't Enough
&lt;/h1&gt;

&lt;p&gt;A common solution is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;FOR&lt;/span&gt; &lt;span class="k"&gt;UPDATE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Row-level locking is useful, but it isn't the entire solution.&lt;/p&gt;

&lt;p&gt;The system uses several mechanisms together.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Candidate discovery
&lt;/h3&gt;

&lt;p&gt;First, the allocation engine identifies potentially available inventory.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Canonical lock ordering
&lt;/h3&gt;

&lt;p&gt;Multiple inventory records are locked in a deterministic order.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Seat 1
Seat 2
Seat 3
Seat 4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;rather than allowing transactions to acquire locks in arbitrary order.&lt;/p&gt;

&lt;p&gt;This helps reduce deadlock scenarios.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Re-validation
&lt;/h3&gt;

&lt;p&gt;After acquiring locks, availability is checked again.&lt;/p&gt;

&lt;p&gt;This is important because the world may have changed between:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;candidate discovery
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lock acquisition
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Allocation
&lt;/h3&gt;

&lt;p&gt;Only after the candidate has survived those checks does the system create the allocation.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Database constraint
&lt;/h3&gt;

&lt;p&gt;Finally, PostgreSQL independently enforces the no-overlap invariant.&lt;/p&gt;

&lt;p&gt;The allocation flow therefore becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DISCOVER
   ↓
LOCK
   ↓
RE-VALIDATE
   ↓
RANK
   ↓
ALLOCATE
   ↓
DATABASE CONSTRAINT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The implementation follows this general flow inside the allocation engine.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Reservation State Machine
&lt;/h1&gt;

&lt;p&gt;A reservation isn't simply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BOOKED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are several states involved.&lt;/p&gt;

&lt;p&gt;The system models the lifecycle as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATED
   │
   ▼
 HELD
   │
   ▼
PAYMENT_PENDING
   │
   ▼
CONFIRMED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with failure paths:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HELD ─────────────→ EXPIRED
  │
  └───────────────→ CANCELLED

PAYMENT_PENDING ──→ FAILED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This distinction is critical.&lt;/p&gt;

&lt;p&gt;For example, imagine a user selects a seat but doesn't complete payment.&lt;/p&gt;

&lt;p&gt;If the system immediately treats that seat as permanently booked, inventory becomes unavailable indefinitely.&lt;/p&gt;

&lt;p&gt;Instead, the reservation can enter a temporary hold state.&lt;/p&gt;

&lt;p&gt;A background worker periodically finds expired holds and releases the inventory.&lt;/p&gt;




&lt;h1&gt;
  
  
  Temporary Holds
&lt;/h1&gt;

&lt;p&gt;The system therefore separates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Available
Held
Confirmed
Expired
Cancelled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives the booking flow a much more realistic lifecycle.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User starts booking
       │
       ▼
Seat HELD
       │
       ├──── Payment succeeds ────→ CONFIRMED
       │
       └──── Timeout ─────────────→ EXPIRED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;ExpireWorker&lt;/code&gt; periodically sweeps for expired reservations.&lt;/p&gt;

&lt;p&gt;This is implemented as part of the reservation package.&lt;/p&gt;




&lt;h1&gt;
  
  
  Idempotency: Handling Retries Safely
&lt;/h1&gt;

&lt;p&gt;Another subtle problem appears when clients retry requests.&lt;/p&gt;

&lt;p&gt;Suppose a user clicks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Confirm Booking
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the request reaches the server successfully.&lt;/p&gt;

&lt;p&gt;But the network connection dies before the client receives the response.&lt;/p&gt;

&lt;p&gt;The client doesn't know whether the booking succeeded.&lt;/p&gt;

&lt;p&gt;So it retries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /reservations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without idempotency, the backend could create a second reservation.&lt;/p&gt;

&lt;p&gt;The system therefore supports durable idempotency keys.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Idempotency-Key: 8f2c...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server records the operation associated with that key.&lt;/p&gt;

&lt;p&gt;If the same request arrives again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;same key
   ↓
existing operation
   ↓
return previous result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;rather than executing the booking again.&lt;/p&gt;

&lt;p&gt;This makes retries safe.&lt;/p&gt;




&lt;h1&gt;
  
  
  Payment Is Deliberately Decoupled From Inventory Locks
&lt;/h1&gt;

&lt;p&gt;Another important architectural decision was separating payment processing from the inventory transaction.&lt;/p&gt;

&lt;p&gt;A dangerous architecture would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BEGIN TRANSACTION

Lock seat

Call payment provider
      ↓
Wait...

Payment response
      ↓
Commit

COMMIT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is problematic because external payment systems can be slow or unavailable.&lt;/p&gt;

&lt;p&gt;Holding database locks while waiting for an external service increases contention.&lt;/p&gt;

&lt;p&gt;Instead, the system separates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Inventory transaction
        │
        ▼
Reservation / Payment Intent
        │
        ▼
External payment provider
        │
        ▼
Webhook
        │
        ▼
Confirm reservation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The payment package therefore handles payment intents and idempotent webhook processing without unnecessarily coupling external payment latency to inventory locks.&lt;/p&gt;




&lt;h1&gt;
  
  
  Transactional Outbox
&lt;/h1&gt;

&lt;p&gt;Once a reservation is confirmed, the system may need to publish events:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ReservationConfirmed
PaymentCompleted
ReservationCancelled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A classic distributed-systems problem appears here.&lt;/p&gt;

&lt;p&gt;Suppose the application does:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UPDATE reservation
INSERT event into message broker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the database update succeeds but the broker operation fails.&lt;/p&gt;

&lt;p&gt;Now the reservation exists but the event was never published.&lt;/p&gt;

&lt;p&gt;The system uses the &lt;strong&gt;transactional outbox pattern&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of directly publishing an event:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DB Transaction
 ├── Update reservation
 └── Insert outbox event
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both operations happen in the same database transaction.&lt;/p&gt;

&lt;p&gt;A separate worker then publishes events from the outbox.&lt;/p&gt;

&lt;p&gt;The project uses PostgreSQL's &lt;code&gt;SKIP LOCKED&lt;/code&gt; mechanism for worker-side claiming.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             PostgreSQL
                  │
        ┌─────────┴─────────┐
        │                   │
 reservation              outbox
        │                   │
        └─────────┬─────────┘
                  │
                  ▼
            Outbox Worker
                  │
                  ▼
             Event System
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes event publication much more resilient to process crashes.&lt;/p&gt;




&lt;h1&gt;
  
  
  Waitlist
&lt;/h1&gt;

&lt;p&gt;Railway inventory isn't always simply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AVAILABLE
or
SOLD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When inventory is exhausted, passengers may enter a waitlist.&lt;/p&gt;

&lt;p&gt;The project implements a priority-ordered waitlist.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Train full

Passenger A → WL 1
Passenger B → WL 2
Passenger C → WL 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When inventory becomes available:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cancellation
     │
     ▼
Available inventory
     │
     ▼
Promotion Worker
     │
     ▼
Waitlist candidate
     │
     ▼
Allocation Engine
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An important architectural choice is that waitlist promotion does not implement a completely separate seat-allocation algorithm.&lt;/p&gt;

&lt;p&gt;It reuses the existing allocation engine.&lt;/p&gt;

&lt;p&gt;That means the same concurrency guarantees apply to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Normal booking
Waitlist promotion
RAC promotion
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This avoids having multiple implementations of the most critical piece of business logic.&lt;/p&gt;




&lt;h1&gt;
  
  
  RAC
&lt;/h1&gt;

&lt;p&gt;The project also models &lt;strong&gt;Reservation Against Cancellation (RAC)&lt;/strong&gt; as a separate domain.&lt;/p&gt;

&lt;p&gt;Instead of treating RAC as simply another waitlist status, it has its own queue and promotion flow.&lt;/p&gt;

&lt;p&gt;The architecture follows the same general principle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cancellation
     │
     ▼
RAC Queue
     │
     ▼
Promotion Worker
     │
     ▼
Allocation Engine
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, the allocation engine remains the central authority for assigning inventory.&lt;/p&gt;




&lt;h1&gt;
  
  
  Quotas
&lt;/h1&gt;

&lt;p&gt;Railway reservations can also have inventory divided into different quotas.&lt;/p&gt;

&lt;p&gt;The project models quota-scoped inventory assignment and eventual release back to general inventory.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                Inventory
                    │
       ┌────────────┼────────────┐
       ▼            ▼            ▼
    General       Quota A       Quota B
       │            │            │
       └────────────┴────────────┘
                    │
             Release Policy
                    │
                    ▼
             General Inventory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This introduces another interesting consistency problem:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Inventory isn't merely "available or unavailable"; it can belong to different allocation pools with different release rules.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  API Architecture
&lt;/h1&gt;

&lt;p&gt;The backend exposes REST endpoints for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Train availability&lt;/li&gt;
&lt;li&gt;PNR lookup&lt;/li&gt;
&lt;li&gt;Reservation creation&lt;/li&gt;
&lt;li&gt;Reservation confirmation&lt;/li&gt;
&lt;li&gt;Reservation cancellation&lt;/li&gt;
&lt;li&gt;Payment webhooks&lt;/li&gt;
&lt;li&gt;Administrative operations&lt;/li&gt;
&lt;li&gt;RBAC/role management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The public read path is separated from authenticated booking operations, while administrative operations require authorization and permission checks.&lt;/p&gt;

&lt;p&gt;A simplified API structure looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/v1
 ├── /trains
 │    └── /{id}/availability
 │
 ├── /pnr
 │    └── /{pnr}
 │
 ├── /reservations
 │    ├── POST
 │    ├── GET
 │    ├── /confirm
 │    └── /cancel
 │
 ├── /payments
 │    └── /webhook
 │
 └── /admin
      └── RBAC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Authentication and RBAC
&lt;/h1&gt;

&lt;p&gt;The project intentionally keeps authentication relatively small.&lt;/p&gt;

&lt;p&gt;Requests can carry bearer tokens, while administrative actions additionally go through role/permission checks.&lt;/p&gt;

&lt;p&gt;An important design choice is that authorization isn't treated purely as middleware.&lt;/p&gt;

&lt;p&gt;Policy checks also happen inside handlers.&lt;/p&gt;

&lt;p&gt;This makes authorization closer to the actual business operation rather than relying entirely on route-level protection.&lt;/p&gt;




&lt;h1&gt;
  
  
  Background Workers
&lt;/h1&gt;

&lt;p&gt;Some operations should not happen synchronously inside a user's HTTP request.&lt;/p&gt;

&lt;p&gt;The server therefore wires several background workers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Expiry Worker
     │
     └── Expire temporary holds

Outbox Worker
     │
     └── Publish pending events

Waitlist Worker
     │
     └── Promote eligible passengers

RAC Worker
     │
     └── Promote RAC passengers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows the API layer to remain focused on request/response operations while asynchronous domain processing happens independently.&lt;/p&gt;




&lt;h1&gt;
  
  
  Testing the Actual Concurrency Problem
&lt;/h1&gt;

&lt;p&gt;One of the most important parts of the project is that concurrency correctness isn't tested purely with mocks.&lt;/p&gt;

&lt;p&gt;The repository contains a dedicated concurrency test suite that runs against a real PostgreSQL instance.&lt;/p&gt;

&lt;p&gt;This is important because the behavior being tested depends on PostgreSQL itself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Row locks
Exclusion constraints
Transactions
SKIP LOCKED
Concurrent transactions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mocking these mechanisms would not actually prove that PostgreSQL behaves correctly under contention.&lt;/p&gt;

&lt;p&gt;The repository documents 11 concurrency/integration scenarios, including a test that exposed an actual bug during development.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Testing Philosophy
&lt;/h1&gt;

&lt;p&gt;The project deliberately separates two kinds of testing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unit tests
&lt;/h3&gt;

&lt;p&gt;Used for deterministic domain behavior:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go &lt;span class="nb"&gt;test&lt;/span&gt; ./internal/...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These don't require a database.&lt;/p&gt;

&lt;h3&gt;
  
  
  Concurrency integration tests
&lt;/h3&gt;

&lt;p&gt;Used for database behavior:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go &lt;span class="nb"&gt;test&lt;/span&gt; ./tests/concurrency/... &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These require a real PostgreSQL instance.&lt;/p&gt;

&lt;p&gt;This distinction matters.&lt;/p&gt;

&lt;p&gt;A unit test can prove:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;allocateSeat()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;returns the expected result.&lt;/p&gt;

&lt;p&gt;It cannot prove that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;100 concurrent transactions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;cannot violate a PostgreSQL locking invariant.&lt;/p&gt;

&lt;p&gt;For that, the actual database needs to participate in the test.&lt;/p&gt;




&lt;h1&gt;
  
  
  Architecture at a Glance
&lt;/h1&gt;

&lt;p&gt;The complete system can be thought of as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                        CLIENT
                          │
                          ▼
                     REST API
                          │
                ┌─────────┴─────────┐
                │                   │
             Auth/RBAC         Idempotency
                │                   │
                └─────────┬─────────┘
                          ▼
                 Reservation
                  Coordinator
                          │
              ┌───────────┼───────────┐
              ▼           ▼           ▼
          Inventory    Payment      Rules
              │           │           │
              └─────┬─────┴───────────┘
                    ▼
               PostgreSQL
                    │
       ┌────────────┼────────────┐
       ▼            ▼            ▼
   Outbox       Waitlist        RAC
   Worker        Worker        Worker
       │            │            │
       └────────────┴────────────┘
                    │
                    ▼
             Event Processing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database is at the center because correctness depends heavily on transactional guarantees.&lt;/p&gt;




&lt;h1&gt;
  
  
  Project Structure
&lt;/h1&gt;

&lt;p&gt;The repository is intentionally divided by domain rather than putting all business logic into one large service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;internal/
├── inventory/
├── allocation/
├── rules/
├── reservation/
├── idempotency/
├── payment/
├── outbox/
├── waitlist/
├── rac/
├── quota/
├── auth/
├── rbac/
├── api/
└── platform/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The repository also keeps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docs/
├── architecture.md
├── concurrency.md
├── status.md
└── adr/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;alongside:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tests/concurrency/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This separation makes the repository itself part of the design documentation rather than simply being a collection of source files.&lt;/p&gt;




&lt;h1&gt;
  
  
  Architecture Decision Records
&lt;/h1&gt;

&lt;p&gt;The project contains individual ADRs documenting major architectural trade-offs.&lt;/p&gt;

&lt;p&gt;This was intentional.&lt;/p&gt;

&lt;p&gt;In real systems, architecture isn't simply:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I chose PostgreSQL."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There is usually a question behind every decision:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Why PostgreSQL?

Why database-level exclusion?

Why row locking?

Why canonical lock ordering?

Why idempotency?

Why an outbox?

Why SKIP LOCKED?

Why a state machine?

Why separate payment from inventory?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Writing these decisions down makes the system easier to reason about and makes trade-offs explicit.&lt;/p&gt;




&lt;h1&gt;
  
  
  What I Learned
&lt;/h1&gt;

&lt;p&gt;The biggest lesson from building this system was that high-concurrency backend engineering is fundamentally about &lt;strong&gt;invariants&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is tempting to think about a booking system as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;API → Database → Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But the more useful model is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Invariant
   ↓
Concurrency model
   ↓
Transaction boundaries
   ↓
Database constraints
   ↓
Recovery mechanisms
   ↓
Tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;/p&gt;

&lt;h3&gt;
  
  
  Invariant
&lt;/h3&gt;

&lt;p&gt;A seat cannot be allocated twice for overlapping journey segments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Concurrency mechanism
&lt;/h3&gt;

&lt;p&gt;Locks + canonical ordering + transactions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Database guarantee
&lt;/h3&gt;

&lt;p&gt;PostgreSQL exclusion constraint.&lt;/p&gt;

&lt;h3&gt;
  
  
  Recovery
&lt;/h3&gt;

&lt;p&gt;Bounded/jittered retries.&lt;/p&gt;

&lt;h3&gt;
  
  
  Verification
&lt;/h3&gt;

&lt;p&gt;Real PostgreSQL concurrency tests.&lt;/p&gt;

&lt;p&gt;This approach changes how I think about backend architecture.&lt;/p&gt;




&lt;h1&gt;
  
  
  What I Would Build Next
&lt;/h1&gt;

&lt;p&gt;The current implementation intentionally focuses on correctness rather than claiming production-scale performance.&lt;/p&gt;

&lt;p&gt;There are several areas still left for future work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OpenTelemetry tracing&lt;/li&gt;
&lt;li&gt;Prometheus metrics&lt;/li&gt;
&lt;li&gt;Docker / Docker Compose setup&lt;/li&gt;
&lt;li&gt;k6 load-testing scenarios&lt;/li&gt;
&lt;li&gt;Formal throughput benchmarks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are explicitly tracked as unfinished areas in the repository.&lt;/p&gt;

&lt;p&gt;That distinction is important.&lt;/p&gt;

&lt;p&gt;The current concurrency suite demonstrates &lt;strong&gt;correctness under contention&lt;/strong&gt;, but it does not claim a particular production throughput or capacity figure.&lt;/p&gt;

&lt;p&gt;The next stage would therefore be to measure the system rather than simply assume it scales.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why This Project Exists
&lt;/h1&gt;

&lt;p&gt;I didn't want to build another CRUD-heavy railway booking application where the main engineering challenge was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /book
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead, I wanted to investigate a question that appears simple but becomes difficult under concurrent load:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How do you safely allocate scarce, segment-based inventory when many independent requests arrive simultaneously?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That question naturally led into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;database transactions&lt;/li&gt;
&lt;li&gt;row-level locking&lt;/li&gt;
&lt;li&gt;deadlock avoidance&lt;/li&gt;
&lt;li&gt;exclusion constraints&lt;/li&gt;
&lt;li&gt;idempotency&lt;/li&gt;
&lt;li&gt;state machines&lt;/li&gt;
&lt;li&gt;payment boundaries&lt;/li&gt;
&lt;li&gt;transactional outbox&lt;/li&gt;
&lt;li&gt;background workers&lt;/li&gt;
&lt;li&gt;waitlists&lt;/li&gt;
&lt;li&gt;RAC&lt;/li&gt;
&lt;li&gt;quota management&lt;/li&gt;
&lt;li&gt;concurrency testing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The resulting system is therefore less about building an "IRCTC clone" and more about building a &lt;strong&gt;concurrency-correct reservation engine&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  Final Takeaway
&lt;/h1&gt;

&lt;p&gt;A railway booking system looks like a straightforward application until you introduce concurrency.&lt;/p&gt;

&lt;p&gt;Then the problem becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    MANY USERS
                        │
                        ▼
                LIMITED INVENTORY
                        │
                        ▼
              CONCURRENT REQUESTS
                        │
                        ▼
              TRANSACTION CONTROL
                        │
                        ▼
             DATABASE INVARIANTS
                        │
                        ▼
                 CORRECT RESULT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The most important architectural decision in this project is that correctness is not entrusted to a single &lt;code&gt;if seat.available&lt;/code&gt; check.&lt;/p&gt;

&lt;p&gt;Instead, correctness is defended through multiple layers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Idempotency
     +
Canonical locking
     +
Re-validation
     +
Transactions
     +
Database exclusion constraints
     +
Retry handling
     +
Concurrency integration tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result is a backend reservation engine designed around a very specific principle:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;When inventory is scarce and requests are concurrent, correctness has to be designed into the system — not assumed from the application code.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Research &amp;amp; Architectural References
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Architecture disclaimer:&lt;/strong&gt; This project is an independent engineering implementation inspired by publicly available information about Indian Railways' Passenger Reservation System (PRS), CONCERT and CRIS. It does &lt;strong&gt;not&lt;/strong&gt; claim to reproduce IRCTC/CRIS's proprietary production architecture, implementation, infrastructure, algorithms, or internal systems.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The architecture and engineering problems explored in this project were informed by publicly available government, academic, and institutional material describing the evolution and architecture of Indian Railways' computerized reservation systems.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. CRIS — CONCERT / Passenger Reservation System
&lt;/h2&gt;

&lt;p&gt;The Centre for Railway Information Systems (CRIS) describes &lt;strong&gt;CONCERT&lt;/strong&gt; as a mission-critical online transaction-processing application built around a distributed database model and a three-tier client-server architecture.&lt;/p&gt;

&lt;p&gt;This provided the primary architectural context for treating railway reservation as a distributed, high-concurrency transaction-processing problem rather than as a conventional CRUD application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Relevant concepts:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Distributed reservation infrastructure&lt;/li&gt;
&lt;li&gt;Online Transaction Processing (OLTP)&lt;/li&gt;
&lt;li&gt;Three-tier architecture&lt;/li&gt;
&lt;li&gt;Distributed databases&lt;/li&gt;
&lt;li&gt;Geographically distributed reservation infrastructure&lt;/li&gt;
&lt;li&gt;Mission-critical transaction processing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Reference:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cris.org.in/loadpage?page=proPRS" rel="noopener noreferrer"&gt;CRIS — Passenger Reservation System / CONCERT&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. CAG of India — Computerised Passenger Reservation System
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Comptroller and Auditor General of India (CAG)&lt;/strong&gt; published an audit report covering the Computerised Passenger Reservation System of Indian Railways.&lt;/p&gt;

&lt;p&gt;The report provides historical information about the evolution of the reservation system, including the earlier &lt;strong&gt;IMPRESS&lt;/strong&gt; system, its deployment across multiple PRS locations, and the subsequent evolution toward &lt;strong&gt;CONCERT&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is particularly useful for understanding the historical distributed architecture of Indian Railways' reservation infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Relevant concepts:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Evolution from IMPRESS to CONCERT&lt;/li&gt;
&lt;li&gt;Distributed PRS locations&lt;/li&gt;
&lt;li&gt;Reservation database architecture&lt;/li&gt;
&lt;li&gt;Networked reservation terminals&lt;/li&gt;
&lt;li&gt;Transaction processing&lt;/li&gt;
&lt;li&gt;Capacity and operational constraints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Reference:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://saiindia.gov.in/uploads/old_reports/union/union_performance/2006_2007/Railways/Report_no_11/chap_1.pdf" rel="noopener noreferrer"&gt;CAG of India — Computerised Passenger Reservation System of Indian Railways&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Computerized Passenger Reservation System for Indian Railways — System Architecture
&lt;/h2&gt;

&lt;p&gt;Seema Agarwal's research paper, &lt;strong&gt;"Computerized Passenger Reservation System for Indian Railways — Its Development and System Architecture,"&lt;/strong&gt; examines the evolution and architecture of India's computerized railway reservation system.&lt;/p&gt;

&lt;p&gt;The paper discusses the transition from earlier reservation platforms toward CONCERT and describes the architectural characteristics of the system, including its three-tier client-server model.&lt;/p&gt;

&lt;p&gt;This research was particularly useful for understanding how a railway reservation system evolved from individual reservation systems into a connected, distributed reservation environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Relevant concepts:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PRS evolution&lt;/li&gt;
&lt;li&gt;IMPRESS&lt;/li&gt;
&lt;li&gt;CONCERT&lt;/li&gt;
&lt;li&gt;Three-tier architecture&lt;/li&gt;
&lt;li&gt;Distributed reservation systems&lt;/li&gt;
&lt;li&gt;Centralized vs. distributed processing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;References:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.researchgate.net/publication/338229391_Computerized_Passenger_Reservation_System_for_Indian_Railways_-Its_Development_and_System_Architecture" rel="noopener noreferrer"&gt;ResearchGate — Computerized Passenger Reservation System for Indian Railways&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://citeseerx.ist.psu.edu/document?doi=fb65dcce584615fff5db44d203c7e18e955916c7&amp;amp;repid=rep1&amp;amp;type=pdf" rel="noopener noreferrer"&gt;CiteSeerX — Paper PDF&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  4. IIM Ahmedabad — Passenger Reservation System of Indian Railways
&lt;/h2&gt;

&lt;p&gt;The Indian Institute of Management Ahmedabad published a case study titled:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Management of Large IT Projects: The Passenger Reservation System of Indian Railways."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The study examines the PRS as a large-scale information technology project and provides historical architectural context around its distributed database infrastructure and geographically distributed reservation terminals.&lt;/p&gt;

&lt;p&gt;This was useful for understanding the reservation system not merely as a ticket-booking application, but as a large-scale distributed information system with significant operational and transaction-processing requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Relevant concepts:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large-scale IT systems&lt;/li&gt;
&lt;li&gt;Distributed databases&lt;/li&gt;
&lt;li&gt;Geographically distributed infrastructure&lt;/li&gt;
&lt;li&gt;Transaction processing&lt;/li&gt;
&lt;li&gt;System evolution&lt;/li&gt;
&lt;li&gt;Operational scalability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Reference:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.iima.ac.in/publication/management-large-it-projects-passenger-reservation-system-indian-railways" rel="noopener noreferrer"&gt;IIM Ahmedabad — Management of Large IT Projects: The Passenger Reservation System of Indian Railways&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Modernization of Passenger Reservation System
&lt;/h2&gt;

&lt;p&gt;The paper &lt;strong&gt;"Modernization of Passenger Reservation System: Indian Railways' Dilemma"&lt;/strong&gt;, published in the &lt;em&gt;Journal of Information Technology&lt;/em&gt;, examines the challenges involved in modernizing a large, established railway reservation system.&lt;/p&gt;

&lt;p&gt;The paper is useful for understanding the architectural tension between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Existing reliable infrastructure&lt;/li&gt;
&lt;li&gt;New functional requirements&lt;/li&gt;
&lt;li&gt;Changing user expectations&lt;/li&gt;
&lt;li&gt;Legacy system constraints&lt;/li&gt;
&lt;li&gt;Modernization of large-scale information systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These considerations influenced the decision to build this project as a modern independent reservation engine rather than attempting to replicate the historical architecture directly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://journals.sagepub.com/doi/10.1057/palgrave.jit.2000112" rel="noopener noreferrer"&gt;Journal of Information Technology — Modernization of Passenger Reservation System: Indian Railways' Dilemma&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DOI:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://doi.org/10.1057/palgrave.jit.2000112" rel="noopener noreferrer"&gt;10.1057/palgrave.jit.2000112&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  6. CRIS — New PRS in RDBMS Platform and NGeT
&lt;/h2&gt;

&lt;p&gt;A historical CRIS presentation discussing the modernization of the Passenger Reservation System provides additional technical context around:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CONCERT&lt;/li&gt;
&lt;li&gt;RDBMS migration&lt;/li&gt;
&lt;li&gt;Distributed architecture&lt;/li&gt;
&lt;li&gt;Transaction routing&lt;/li&gt;
&lt;li&gt;Reliability&lt;/li&gt;
&lt;li&gt;Next Generation e-Ticketing (NGeT)&lt;/li&gt;
&lt;li&gt;Reservation system modernization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This material is particularly useful for understanding the transition from older reservation infrastructure toward newer database and Internet-based architectures.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This is historical material and should not be interpreted as a specification of the current production IRCTC/CRIS architecture.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Reference:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://studylib.net/doc/10134552/new-prs-in-rdbms-platform-and-nget" rel="noopener noreferrer"&gt;CRIS — New PRS in RDBMS Platform and NGeT&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  What These References Contributed to This Project
&lt;/h1&gt;

&lt;p&gt;The purpose of researching these systems was &lt;strong&gt;not&lt;/strong&gt; to reproduce IRCTC's internal implementation.&lt;/p&gt;

&lt;p&gt;Instead, the research helped identify the fundamental engineering characteristics of railway reservation systems:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
text
                    Railway Reservation
                           │
                           ▼
                  Distributed System
                           │
             ┌─────────────┼─────────────┐
             ▼             ▼             ▼
        High Volume    Limited       Distributed
        Transactions   Inventory      Infrastructure
             │             │             │
             └─────────────┼─────────────┘
                           ▼
                  Concurrency Control
                           │
                           ▼
                  Transaction Integrity
                           │
                           ▼
                 Inventory Correctness
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
    </item>
  </channel>
</rss>
