In short
Server-side web development is the part of a web application that runs on the server: it accepts an HTTP request, executes program logic, talks to databases and other services, and returns a response (HTML, JSON or a file). It matters because business rules, data integrity, authentication and security can only be trusted where the user cannot tamper with the code. University syllabi examine it as "Web Technology"/"Web Programming" (servlets, JSP, PHP, sessions, MVC, three-tier architecture) and GATE-level CS papers touch it through HTTP, cookies and concurrency. Every Indian IT employer — TCS, Infosys, Wipro, Cognizant, Accenture, Zoho, Freshworks, Zoho/Zomato/Flipkart-type product firms and every bank's digital team — hires for it, and India-specific systems (UPI, Aadhaar e-KYC, GST returns, DigiLocker, IRCTC) are built on it.
Explained
The request-response cycle and where server code sits
- Client-server model: browser (client) sends an HTTP request over TCP (port 80, or 443 with TLS); the server program computes a response and closes or reuses the connection.
- Full path of one request: DNS lookup → TCP handshake → TLS handshake (HTTPS) → HTTP request line + headers (+ body) → web server receives → routes to application code → code queries database/cache → builds response → status line + headers + body → browser parses and renders.
- HTTP is stateless: the server keeps no memory of the previous request; any continuity (login, cart) must be re-established on every request using cookies, tokens or server-side sessions.
- Request anatomy: method (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS), path + query string, headers (Host, Cookie, Authorization, Content-Type, Accept), body for POST/PUT.
- Status families: 1xx informational, 2xx success (200 OK, 201 Created, 204 No Content), 3xx redirect (301 permanent, 302/303 temporary, 304 Not Modified), 4xx client error (400, 401 unauthenticated, 403 unauthorised, 404, 409 conflict, 422, 429 too many requests), 5xx server error (500, 502 bad gateway, 503 unavailable, 504 timeout).
- Safe vs idempotent: GET/HEAD are safe (no side effect); GET, PUT, DELETE are idempotent (repeating gives the same state); POST is neither — hence duplicate payments on a double-click if not guarded.
- Web server vs application server: a web server (Apache HTTPD, Nginx, IIS) serves static files and proxies; an application server (Tomcat, JBoss/WildFly, GlassFish, Gunicorn, PHP-FPM) executes program code and manages its lifecycle, threads and pooling.
Server-side execution models
- CGI (Common Gateway Interface): the server forks a new process per request, passes data in environment variables and stdin. Simple and language-agnostic but one process per request makes it very slow under load.
- FastCGI / SCGI / PHP-FPM: long-lived worker processes reused across requests — removes the fork cost; PHP-FPM behind Nginx is the standard LAMP deployment today.
- Server extension APIs: modules loaded inside the web server (mod_php, ISAPI) — fast, but a crash can take the server down.
- Container/servlet model (Java): the servlet container keeps one servlet instance and serves concurrent requests on multiple threads — fast, but instance variables are shared, so servlets must be written thread-safe.
- Process-per-worker vs thread-per-request vs event loop: Apache prefork/worker uses processes/threads; Nginx and Node.js use an event loop with non-blocking I/O (Nginx runs several such single-threaded worker processes), which handles many idle connections cheaply (the C10K problem).
- Interface standards: WSGI/ASGI (Python — Django, Flask, FastAPI), Rack (Ruby), Servlet API (Java), PSR-7/PSR-15 (PHP).
- Scaling: *vertical* (bigger machine) vs *horizontal* (more instances behind a load balancer). Horizontal scaling requires the application to be stateless — no session data in local memory; keep it in Redis, a database or a signed token.
Java servlets and JSP (the exam core)
- Servlet: a Java class extending
HttpServlet, mapped to a URL byweb.xmlor@WebServlet, overridingdoGet/doPost. - Lifecycle: class loaded →
init(ServletConfig)once →service()per request, which dispatches todoGet/doPost→destroy()once on shutdown. Only one instance exists by default (unlessSingleThreadModel, now deprecated). - Key objects:
HttpServletRequest(getParameter,getHeader,getSession,getAttribute),HttpServletResponse(setContentType,getWriter,sendRedirect,addCookie),ServletContext(application-wide),ServletConfig(per-servlet init parameters). - Forward vs redirect:
RequestDispatcher.forward()happens on the server in the same request (URL unchanged, request attributes survive);response.sendRedirect()sends 302 to the browser, which makes a fresh request (URL changes, attributes lost). - Four scopes: page, request, session, application — in increasing lifetime and visibility.
- JSP: HTML with embedded Java; translated by the container into a servlet (
.java→.class) on first request, then reused. Elements: directives<%@ page %>,<%@ include %>, declarations<%! %>, scriptlets<% %>, expressions<%= %>, EL${...}, actions<jsp:include>,<jsp:useBean>, and JSTL tags. - Implicit objects: request, response, session, application, out, config, pageContext, page, exception.
- Why scriptlets are discouraged: they mix logic with presentation; modern practice uses EL + JSTL, or a template engine (Thymeleaf, Freemarker, Twig, Jinja2, EJS), keeping JSP/templates to display only.
- Filters and listeners: filters wrap requests for cross-cutting work (authentication, logging, compression, CORS, character encoding); listeners react to context/session/attribute events.
Architecture: MVC, layers and rendering strategies
- MVC: Model (data + business rules), View (template producing output), Controller (receives the request, calls the model, selects the view). Keeps logic testable and views replaceable.
- Model 1 vs Model 2: Model 1 = JSP handles both logic and display (fine only for toy apps); Model 2 = servlet controller + JSP views = proper MVC.
- Three-tier architecture: presentation tier (browser/UI) → application/logic tier (server code) → data tier (RDBMS). A physical separation that allows independent scaling and security zones; "n-tier" adds caching, queueing and integration tiers.
- Common layers inside the app tier: controller → service (business rules, transactions) → repository/DAO (persistence) → entity/model. DTOs carry data across layers.
- Rendering choices: *SSR* (server builds full HTML — best first-paint and SEO), *CSR* (server returns JSON, browser renders), *SSG* (HTML built at deploy time), *hybrid/islands*. Server-side rendering remains the default for content and form-heavy Indian government and banking portals.
- Frameworks by language: Java — Spring Boot/Spring MVC, Jakarta EE; PHP — Laravel, CodeIgniter, Symfony; Python — Django, Flask, FastAPI; Ruby — Rails; C# — ASP.NET Core; Go — Gin/Echo. Conventions they provide: routing, ORM, validation, templating, migrations, dependency injection.
- ORM and the N+1 problem: an ORM (Hibernate/JPA, Eloquent, Django ORM) maps objects to tables; lazily loading a collection inside a loop fires one query per row — fix with a join/eager fetch.
- Connection pooling: opening a DB connection costs milliseconds; a pool (HikariCP, c3p0, PDO persistent) keeps a fixed set open. Pool size is a hard upper bound on concurrent DB work.
State, sessions and authentication
- Cookie: a small name=value pair the server sets with
Set-Cookieand the browser returns on matching requests. Attributes:Expires/Max-Age(persistent vs session cookie),Domain,Path,Secure(HTTPS only),HttpOnly(hidden from JavaScript),SameSite=Strict/Lax/None. - Server-side session: the server stores state in memory/Redis/DB under a session ID sent in a cookie (
JSESSIONID,PHPSESSID). Methods:getSession(),setAttribute,invalidate,setMaxInactiveInterval. - Other state techniques: URL rewriting (session id appended when cookies are disabled), hidden form fields, and client-side storage (not trustworthy for authorisation).
- Token-based auth: a signed JWT (header.payload.signature, base64url) or opaque token sent in
Authorization: Bearer ...; stateless and scalable, but hard to revoke before expiry — hence short access tokens plus a refresh token. - Session vs token: sessions are easy to revoke but need shared storage or sticky sessions; tokens scale without shared state but carry revocation and size costs.
- Password storage: never plaintext or plain MD5/SHA — use bcrypt, scrypt or Argon2 with a per-user salt and a tuned work factor.
- Authorisation: role-based (RBAC) or attribute-based checks enforced on the server for every request — hiding a button is not security.
- OAuth 2.0 / OpenID Connect: delegated authorisation and login ("Sign in with Google"); in India also used by account aggregator and DigiLocker flows.
Security, performance and Indian compliance
- OWASP Top 10 concerns on the server: injection, broken access control, cryptographic failures, insecure design, misconfiguration, vulnerable components, authentication failures, data integrity failures, logging gaps, SSRF.
- SQL injection: never concatenate user input into SQL; use prepared statements / parameterised queries (
PreparedStatement, PDO bound parameters, ORM parameters) and least-privilege DB accounts. - XSS: escape output by context (HTML, attribute, JavaScript, URL); set
Content-Security-Policy; template engines auto-escape by default. - CSRF: a logged-in user's browser is tricked into submitting a request; defend with per-session CSRF tokens on state-changing requests and
SameSitecookies. - Other server-side defences: validate and whitelist all input server-side, rate limiting (429), file-upload type/size checks and storage outside the webroot, HTTPS with HSTS, secrets in environment variables or a vault (never in Git), generic error pages with detail only in logs.
- Performance levers: HTTP caching (
Cache-Control,ETag,Last-Modified, 304), server-side caching (Redis/Memcached), CDN for static assets, gzip/Brotli compression, database indexes, asynchronous queues for slow work (email, PDF, SMS), pagination, keep-alive and HTTP/2 multiplexing. - Observability: structured logs, health-check endpoints, metrics (requests/sec, p95 latency, error rate), distributed tracing.
- Indian legal and regulatory frame (verify current text before relying on it): the Information Technology Act, 2000 — Section 43A/72A on data protection and compensation, Section 65B of the Evidence framework for electronic records, and the CERT-In directions of 28 April 2022 requiring reportable cyber incidents to be reported within 6 hours and ICT logs to be maintained for 180 days within India. The Digital Personal Data Protection Act, 2023 governs processing of personal data (consent notice, purpose limitation, breach notification, data-principal rights); its rules were notified in 2025 with phased commencement, so check the latest notification for effective dates. RBI mandates payment-system data storage within India (2018 directive) and prescribes digital-payment security controls; UIDAI rules bar storing Aadhaar numbers in plain form and require Aadhaar-based data in a hardware-secured vault; SEBI and IRDAI add sector cloud and audit requirements. Government portals are expected to follow GIGW guidelines and WCAG-based accessibility.
Key points
- Server-side code - runs on the server, cannot be read or altered by the user, so it owns business rules and security.
- Statelessness - HTTP remembers nothing between requests; sessions and tokens re-create continuity.
- Web server vs app server - the first serves static content and proxies, the second executes application code.
- CGI vs FastCGI - process per request vs reusable worker processes; FastCGI/FPM is the modern form.
- Servlet lifecycle -
init()once,service()/doGet/doPostper request,destroy()once; single instance, many threads. - Forward vs redirect - server-side same-request dispatch (URL unchanged) vs 302 telling the browser to request a new URL.
- Scopes - page < request < session < application, in order of lifetime.
- JSP translation - JSP is converted to a servlet on first request and compiled, then reused.
- MVC / Model 2 - controller servlet + service/DAO layers + template views; Model 1 (logic inside JSP) does not scale.
- Three-tier - presentation, application logic, data; each tier can be scaled and secured separately.
- Cookie flags -
HttpOnlystops JS theft,Secureforces HTTPS,SameSiteblunts CSRF. - Session vs JWT - revocable but stateful vs stateless but hard to revoke; short expiry + refresh token is the compromise.
- Password hashing - bcrypt/Argon2 with salt and work factor; never MD5, SHA-1 or plaintext.
- Prepared statements - the single most effective defence against SQL injection.
- Connection pool - bounds concurrent DB work; pool exhaustion shows up as request queueing, not DB errors.
- Caching tiers - browser → CDN → reverse proxy → application cache → database; cheapest hit is the earliest one.
- Horizontal scaling needs stateless apps - externalise session state or use sticky sessions.
- Indian compliance - IT Act 2000, DPDP Act 2023 (rules phased from 2025), CERT-In 6-hour incident reporting and 180-day log retention, RBI data localisation.
Formulas and examples
Required worker threads ≈ λ × W (add headroom; blocking I/O workers scale with W)
Server utilisation ρ = λ / (c × μ) — c = number of workers, μ = requests/second one worker can finish (μ = 1/service time); ρ must stay < 1
Average wait (M/M/1 approximation): W = 1 / (μ − λ) seconds
Availability: Uptime % = (total time − downtime) / total time × 100
Cache effective latency = h × T_cache + (1 − h) × T_origin — h = hit ratio (0-1), T in milliseconds
Bandwidth per second = requests/second × average response size (bytes); 1 Mbps = 125 kB/s
Cost per request (₹) = monthly infrastructure cost (₹) / monthly request count
Example 1 — Sizing worker threads from Little's Law. A Spring Boot result portal receives 600 requests/minute with an average response time of 250 ms.
- λ = 600/60 = 10 requests/second; W = 0.25 s.
- L = λ × W = 10 × 0.25 = 2.5 concurrent requests — so even 8 threads are ample at this load.
- At exam-result peak the rate rises to 5,000 requests/minute (λ = 83.33/s) and a slow DB pushes W to 1.2 s: L = 83.33 × 1.2 = 100 concurrent requests. With a 20-connection DB pool the extra 80 requests queue — the fix is caching the result page, not more threads.
Example 2 — Utilisation and queueing. Each worker can serve one request in 200 ms, so μ = 5 requests/second. The app runs c = 10 workers and λ = 40 requests/second.
- ρ = λ / (c × μ) = 40 / (10 × 5) = 40/50 = 0.8 (80% utilisation).
- Treating the pool as a single server of capacity c × μ = 50/s: W ≈ 1/(50 − 40) = 0.1 s = 100 ms — note this single-server aggregation ignores the 200 ms per-request service time, so read it only as a trend: queueing delay grows sharply as ρ rises.
- If λ grows to 48/s, ρ = 0.96 and W ≈ 1/(50 − 48) = 0.5 s — a 20% traffic rise multiplies latency fivefold. This is why capacity plans target ρ ≤ 0.7.
Example 3 — Cache hit ratio pays for itself. A fee-payment dashboard query takes 180 ms from PostgreSQL and 4 ms from Redis.
- At hit ratio h = 0.90: effective latency = 0.90 × 4 + 0.10 × 180 = 3.6 + 18 = 21.6 ms (an 8.3× improvement).
- At h = 0.99: 0.99 × 4 + 0.01 × 180 = 3.96 + 1.8 = 5.76 ms.
- DB queries avoided per day at h = 0.90 on 2,00,000 requests = 1,80,000, leaving 20,000 to the database.
Example 4 — Bandwidth and cost. An e-commerce API serves 250 requests/second with an average JSON response of 12 kB.
- Bandwidth = 250 × 12 kB = 3,000 kB/s = 3 MB/s ≈ 24 Mbps.
- Per day: 3 MB/s × 86,400 = 2,59,200 MB ≈ 253 GB/day egress.
- If the server bill is ₹45,000/month and traffic is 250 × 86,400 × 30 = 64.8 crore requests/month, cost per request = 45,000 / 64,80,00,000 ≈ ₹0.00007 (about 7 paise per 1,000 requests).
- Enabling gzip at a 4:1 ratio on JSON cuts egress to about 63 GB/day.
Example 5 — Servlet counter: why threads matter.
@WebServlet("/hits")
public class HitServlet extends HttpServlet {
private int hits = 0; // shared by ALL threads - unsafe
protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws IOException {
hits++; // read-modify-write, not atomic
res.setContentType("text/plain");
res.getWriter().println("Hits: " + hits);
}
}
With 1,000 concurrent requests the printed total is often less than 1,000 because two threads read the same value. Fix: private final AtomicInteger hits = new AtomicInteger(); then hits.incrementAndGet(), or keep per-user counts in the session.
Comparison tables
| Aspect | Server-side rendering | Client-side rendering |
|---|---|---|
| HTML built by | Server, per request | Browser JavaScript |
| First paint | Fast | Slower (JS download + fetch) |
| SEO | Native | Needs prerender/SSR fallback |
| Server CPU | Higher | Lower (JSON only) |
| Interactivity after load | Full page reloads unless hybrid | Smooth, app-like |
| Typical fit | Government portals, banking, content sites | Dashboards, SPAs, internal tools |
| Technique | Where stored | Scales horizontally | Revocable | Typical use |
|---|---|---|---|---|
| Server session (in-memory) | App server RAM | Only with sticky sessions | Instantly | Small single-node apps |
| Session in Redis/DB | Shared store | Yes | Instantly | Most web apps |
| Signed cookie | Client, signed | Yes | Only at expiry | Small preference data |
| JWT bearer token | Client | Yes | Hard (needs denylist) | APIs, mobile backends |
| Model | Concurrency unit | Memory cost | Blocking I/O | Examples |
|---|---|---|---|---|
| CGI | Process per request | Very high | Tolerable | Legacy Perl scripts |
| FastCGI/FPM | Pooled processes | Medium | Tolerable | PHP + Nginx |
| Thread per request | Thread | Medium | Tolerable | Tomcat, Spring MVC |
| Event loop | Callbacks/async tasks | Low | Must be avoided | Node.js, Nginx, FastAPI |
Where it is used
- IT services and GCCs: TCS, Infosys, Wipro, HCLTech, Cognizant, Accenture and Capgemini staff large Java/Spring Boot and .NET teams for banking, insurance and telecom clients; servlets/JSP still appear in legacy maintenance work.
- Banking and payments: core-banking web channels, UPI and payment-gateway backends (Razorpay, PayU, Paytm, PhonePe), where idempotency keys, double-entry integrity, RBI localisation and audit logging are non-negotiable.
- Government and public digital infrastructure: IRCTC, GST portal, Income Tax e-filing, DigiLocker, UMANG, state revenue and university result portals — mostly server-rendered, high-burst traffic, GIGW compliant.
- Product companies and startups: Zoho, Freshworks, Zomato, Swiggy, Flipkart, Meesho, Razorpay, CRED build multi-service backends in Java, Go, Python and Node.js with Redis, Kafka and PostgreSQL.
- Job roles: backend developer, full-stack developer, Java/Spring developer, PHP/Laravel developer, Python/Django developer, API engineer, DevOps/SRE, application security engineer.
- Campus and exam relevance: "Web Technology" lab vivas on servlets/JSP/PHP sessions, and placement rounds that combine SQL, HTTP, design of a URL shortener or booking system, and a security question.
Interview questions
- Q: Why is HTTP called stateless, and how do web apps keep a user logged in? A: Each request is independent and carries no memory of earlier ones; applications re-establish identity on every request using a session ID cookie or a signed token sent in the Authorization header.
- Q: What is the difference between
forward()andsendRedirect()? A:forward()transfers control on the server within the same request, so the URL and request attributes are preserved;sendRedirect()returns a 302 and the browser issues a new request, changing the URL and losing request attributes. - Q: Describe the servlet lifecycle and how many instances exist. A: The container loads the class, calls
init()once,service()for every request (dispatching todoGet/doPost), anddestroy()once at shutdown; normally a single instance serves all requests on multiple threads. - Q: Why are servlet instance variables dangerous? A: They are shared by concurrent request threads, so unsynchronised read-modify-write produces lost updates and data leaking between users; keep state in local variables, request or session scope.
- Q: When would you choose a server-side session over a JWT? A: When you need instant revocation, large or sensitive state, or server-controlled expiry; JWTs are preferable when you must scale statelessly across services and accept revocation only at token expiry.
- Q: How do you prevent SQL injection? A: Use parameterised/prepared statements or an ORM's bound parameters, validate and whitelist input, restrict database privileges, and never build SQL by string concatenation — escaping alone is unreliable.
- Q: What is CSRF and how is it different from XSS? A: CSRF makes a victim's authenticated browser send an unwanted state-changing request (defence: per-session tokens plus
SameSitecookies); XSS injects attacker script into your page (defence: contextual output escaping and CSP). - Q: What does a reverse proxy add in front of an application server? A: TLS termination, load balancing, static-file serving, compression, caching, rate limiting and request buffering, while shielding the app server from slow clients.
- Q: Why do we pool database connections, and what happens when the pool is exhausted? A: Opening connections is expensive and the database limits them; when the pool is exhausted, requests block waiting for a connection, so latency rises and timeouts appear even though the database looks idle.
- Q: How do you make a POST endpoint safe against double submission? A: Make it idempotent with a client-supplied idempotency key (or unique constraint) stored with the result, so a repeat request returns the original outcome instead of creating a second record.
- Q: A page is slow only under load. How do you diagnose it? A: Check p95 latency and error rate, then look for serial bottlenecks — slow queries and N+1 patterns, thread or connection pool saturation, lock contention, GC pauses, missing indexes or absent caching — and load-test the fix.
- Q: Where should application secrets live? A: In environment variables or a managed secret store injected at runtime, never in source control or client-side code; rotate them and scope them to least privilege.
Common mistakes
- Trusting client-side validation or hidden form fields; all validation and authorisation must be repeated on the server.
- Storing mutable per-user state in servlet instance variables or module-level globals, which breaks under concurrency.
- Confusing
forwardwithsendRedirect, or expecting request attributes to survive a redirect. - Using GET for state-changing operations, which makes them cacheable, bookmarkable, logged in URLs and repeatable.
- Writing business logic in JSP scriptlets or PHP mixed into HTML, then being unable to test or reuse it.
- Leaving sessions and cookies unprotected — no
HttpOnly/Secure/SameSite, no session invalidation on logout, no session-ID regeneration after login (session fixation). - Printing raw stack traces or SQL errors to the browser, which leaks schema and framework details to an attacker.
- Forgetting the Indian compliance layer — CERT-In log retention and incident reporting, DPDP consent and breach duties, RBI payment-data localisation — until an audit forces a rewrite.
Related topics
Back-end development with Node.js · REST APIs · API integration and middleware · Web fundamentals: HTML, CSS and JavaScript · Database management systems and SQL · Computer networks: HTTP, TCP/IP and TLS · Cloud deployment and DevOps