--:--:--
§ Blogs/gandhinagar-university

Anyone Can Build a Landing Page. Not Everyone Gets to Build a University Website.

July 4, 2026·15 min read·Case Study
Gandhinagar University Digital Core preview

Introduction: The Weight of the Contract

Let's be honest. As software engineers, we are accustomed to building landing pages, SaaS MVPs, e-commerce integrations, or dashboard mockups. We work in sprints, ship to staging, and iterate.

But every once in a while, a project lands on your desk that makes everyone sit upright. A project where the client isn't a small startup looking to validate an idea, but an entire accredited academic institution.

I'm talking about Gandhinagar University.

Winning a contract to build a university website is a completely different beast. A university isn't a single business. It is an ecosystem. Under one umbrella, you have 16 distinct institutes—ranging from Technology (GIT) and Law (GIL) to Management (GIM), Pharmacy (GIP), and Liberal Studies (GILS). You have an administrative division, an admission portal, thousands of prospective student leads, event management systems, academic calendars, job portals, compliance boards, and a strict requirement to keep page load times fast while giving non-technical staff the power to edit everything.

As the Full Stack Developer on the team, my job was to design the system architecture, write the integrations, build out the dynamic routing, establish the caching layers, and coordinate the deployment. The sheer scope was daunting. If we built it with 16 separate WordPress sites, we would end up in dependency and hosting hell. If we built it as 16 separate React builds, deployment and updates would become a logistical nightmare.

We needed a solution that was unified, scalable, incredibly fast, and maintainable. Here is the story of how our engineering team designed the digital core of Gandhinagar University, the architectural patterns that made it work, the failures that almost derailed the launch, and the lessons learned along the way.

Chapter 1: The Monorepo Strategy (pnpm + Turborepo)

When we first sat down to map out the codebase, the immediate instinct of some stakeholders was to split the project into multiple repositories—one for the student portal, one for the admin panel, one for the API, and one for each major institute.

As a team, we strongly opposed this. In a project of this size, code sharing is paramount. If you have different repositories, sharing typescript interfaces, API validator rules, and common UI components (like buttons, form inputs, and modal wrappers) becomes an exercise in frustration. You end up publishing private npm packages, managing version mismatches, and wasting hours on setup.

Instead, we chose a pnpm monorepo orchestrated by Turborepo.

Our folder structure was organized like this:

├── apps/
│   ├── api/       # Express.js backend API
│   ├── web/       # React + Vite frontend
│   └── public/    # Static assets and docs
├── packages/
│   └── utils/     # Shared helper functions, validators, formatter utilities
│   └── types/     # Common TypeScript types and interfaces
├── package.json   # Monorepo root configuration
├── turbo.json     # Turborepo build pipeline config
└── pnpm-workspace.yaml

Why pnpm and Turborepo?

  • Shared Packages: Inside packages/types/, we defined database entities, request/response structures, and access controls. If we changed a DB field, TypeScript caught the mismatches instantly.
  • Build Cache: Turborepo checks the dependency graph. If only the frontend changed, it served the compiled backend API from local cache, accelerating CI builds.
  • pnpm Workspaces: pnpm content-addressable storage saved gigabytes of disk space on our servers by hard-linking duplicated modules.

Chapter 2: Routing the Multiverse (The SPA Subdomain Router)

The centerpiece of our architectural design was the subdomain routing system. Gandhinagar University has 16 institutes, each requiring a separate URL (e.g., git.gandhinagaruniversity.ac.in for the Institute of Technology).

We built a single, highly dynamic React application that detects the active hostname at runtime and mounts the correct layout. Deploying one React application with wildcard DNS is infinitely easier to maintain than 16 separate apps. If we fix a bug in the global navbar, it immediately rolls out to all 16 subdomains in a single deployment.

Dynamic Hostname Resolution

By parsing the window location hostname at runtime, our routing layer dynamically extracts the subdomain, matches it against our centralized institute configuration registry, and determines user layout privileges. This allows us to serve custom themes and navigation matrices seamlessly without executing separate builds.

Chapter 3: Caching & Performance (Redis Dual Caching)

During peak times—such as academic result announcements or admission openings—traffic spikes drastically. A single uncached request fetching a course catalog with placement statistics requires joining four database tables. If thousands of visitors hit that route simultaneously, the database CPU spikes, causing API timeouts.

To combat this, I designed a multi-layer caching system using Redis:

  • Route-Level Caching: Serves static public API responses (courses, blogs, announcements) directly from Redis, bypassing database hits entirely and returning responses in ~10ms.
  • Service-Level Caching: Caches individual database objects, preventing duplicate lookups for complex business models even when dynamic user interactions skip the route cache.
  • Pattern-Based Cache Invalidation: Programmatically clears related cache keys (e.g., blog:*) as soon as an administrator saves changes to content.

Chapter 4: Real-World Engineering Disasters (And How We Solved Them)

Building software on local machines is easy; building software for production, where humans interact with it, is a chaotic exercise in edge cases. Here are three critical engineering challenges we hit during the project and how we solved them.

Disaster 1: The Media Avalanche & Server Memory Blowout

During the soft launch, administrators began uploading raw 15MB to 20MB images directly from DSLR cameras, and 50MB PDFs for academic disclosures. Node.js was reading these giant files into RAM as buffers before sending them to S3, causing Out-Of-Memory (OOM) process crashes.

The Fix: We overhauled the media pipeline to stream incoming file uploads directly to temporary disk storage rather than memory. We then wrote an image processing utility using the Sharp library to resize, compress into next-generation WebP/AVIF formats, and strip unnecessary EXIF metadata. This reduced page load sizes by 82% and stabilized server memory.

Disaster 2: Payment Webhooks & Race Conditions

When integrating the BillDesk payment gateway for cultural event registrations, concurrent traffic tests revealed that some database transactions remained in a pending state despite successful bank notifications. This was caused by the bank webhook and user redirect API call colliding at the exact same millisecond.

The Fix: We implemented optimistic row-level locking (SELECT FOR UPDATE) on payment records, cryptographically verified all bank payloads using JOSEService, and built a self-healing reconciliation cron worker running in the background to automatically resolve stale pending states.

Disaster 3: Google Sheets API Rate-Limit Walls

The admissions department wanted prospective student leads synced in real-time to a Google Sheet. When admission campaigns launched, concurrent submissions crashed the sync due to Google's strict API rate limits (60 writes/minute).

The Fix: We introduced a background worker queue pattern. Form submissions are saved immediately to PostgreSQL (<50ms). A background sync worker wakes up every 10 seconds, batches all pending lead IDs, aggregates them into a single 2D array, and writes to Google Sheets in a single API call, reducing our rate-limit footprint by 98%.

Chapter 5: The Conversational AI Gateway (Integrating Google Gemini API)

To improve student support, we integrated an AI Chatbot directly into the website shell using the Google Gemini API.

To prevent hallucination, the system loads prompts dynamically from our database, matching them with verified administrative FAQs. The chatbot is also configured for chat-based lead generation, gathering name and email details before resolving complex course-eligibility questions. Endpoints are strictly rate-limited and secured with CSRF session tokens to prevent API quota exploitation.

Conclusion: Lessons from the Academic Trenches

Building the digital core of Gandhinagar University was a trial by fire. It proved that system architecture must precede code, that failures are simply checkpoints to build more resilient, self-healing code, and that a monorepo setup is a massive superpower for small development teams.