Backend Developer
Updated for 2026: Backend Developer interview questions and answers covering core skills, tools, and best practices for roles in the US, Europe & Canada.
What are REST API best practices for backend development?
Strong REST APIs are consistent, predictable, and secure. **Best practices:** - Use nouns for resources (`/users`, `/orders/{id}`) - Use correct HTTP methods (GET/POST/PUT/PATCH/DELETE) - Return proper status codes and structured errors - Support pagination, filtering, and sorting - Use versioning strategy when needed - Validate input and enforce authz on every request **Interview tip:** mention idempotency for PUT/DELETE and clear error contracts for clients.
What is idempotency in APIs and why does it matter?
An operation is **idempotent** if repeating it produces the same result. **Examples:** - GET is idempotent. - PUT/DELETE should be idempotent. - POST is usually not idempotent unless designed with an idempotency key. **Why it matters:** retries happen due to timeouts and network failures. Idempotency prevents double-charging, duplicate orders, and inconsistent state.
Offset vs cursor pagination: what’s the difference and when to use each?
**Offset pagination** (`?page=10`) is simple but can be slow and inconsistent on changing datasets. **Cursor pagination** uses a stable cursor (e.g., `createdAt` + `id`) and is faster for large lists and more consistent. **Trade-offs:** cursor pagination is more complex but scales better. Use cursor for high-traffic feeds and large datasets.
Authentication vs authorization: what’s the difference?
**Authentication** verifies who the user is (login). **Authorization** verifies what the user can do (permissions). A common pattern: authenticate once (session/JWT), then authorize on every request using roles/permissions/policies. **Interview tip:** mention least privilege and that authorization must be enforced server-side regardless of frontend checks.
How do access tokens and refresh tokens work with JWT authentication?
**Access tokens** are short-lived and used on each request. **Refresh tokens** are longer-lived and used to obtain new access tokens. **Best practices:** - Keep access tokens short TTL - Store refresh tokens securely (httpOnly cookies or secure storage) - Rotate refresh tokens and revoke on compromise JWTs are convenient for stateless auth, but token revocation and rotation must be designed carefully.
What is OpenID Connect and how is it different from OAuth 2.0?
OAuth 2.0 is for authorization (access to resources). **OpenID Connect (OIDC)** adds an identity layer on top of OAuth to enable authentication. OIDC introduces: - **ID token** (identity claims) - Standardized discovery and user info endpoints Use OAuth when you need delegated access; use OIDC when you need login/authentication via an identity provider.
How do database indexes work and how do you choose the right indexes?
Indexes speed up reads by allowing the DB to avoid full table scans. **Indexing tips:** - Index columns used in WHERE/JOIN/ORDER BY - Use composite indexes based on query patterns - Consider selectivity (high-cardinality columns help more) - Avoid over-indexing (slower writes, more storage) Always verify with EXPLAIN/ANALYZE and measure before/after.
Explain SQL joins (INNER, LEFT, RIGHT) with practical use cases.
Joins combine rows from multiple tables. - **INNER JOIN:** only matching rows - **LEFT JOIN:** all left rows + matching right rows (NULL when missing) - **RIGHT JOIN:** opposite of LEFT (less common) **Use cases:** - INNER for required relationships (orders with customers) - LEFT for optional relationships (users with optional profiles) **Interview tip:** mention join keys should be indexed and types should match.
What are transaction isolation levels and which problems do they prevent?
Isolation levels control how concurrent transactions interact. Common phenomena: - Dirty reads - Non-repeatable reads - Phantom reads Typical levels (weak → strong): Read Uncommitted, Read Committed, Repeatable Read, Serializable. **Trade-off:** stronger isolation improves correctness but can reduce throughput due to locking or serialization.
Optimistic vs pessimistic locking: what’s the difference?
**Pessimistic locking** locks rows/resources up front to prevent conflicts. **Optimistic locking** assumes conflicts are rare; it detects conflicts at commit time (version column/ETag) and retries. Use pessimistic locking for high-contention updates (inventory). Use optimistic locking for mostly-read, low-conflict workloads (profiles).
How does Redis caching work with the cache-aside pattern?
Cache-aside means the application manages the cache. **Flow:** - Read: check Redis → on miss, read DB → write Redis - Write: update DB → invalidate or update Redis **Key decisions:** TTL, key design, stampede protection (locks/jitter), and invalidation strategy.
What are practical cache invalidation strategies in backend systems?
Cache invalidation is hard because data changes. **Practical strategies:** - TTL for eventual freshness - Delete keys on writes (write-through invalidation) - Versioned keys to avoid stale collisions - Event-driven invalidation (pub/sub) Pick based on consistency needs and acceptable staleness. Measure hit rate and correctness impact.
How do you implement rate limiting on the backend?
Backend rate limiting protects services from abuse and overload. **Where to enforce:** API gateway, load balancer, or app layer. **Common algorithms:** token bucket, sliding window. **Distributed enforcement:** use Redis for counters/buckets (atomic updates) or a gateway that supports distributed limits. Always return clear errors (429) and consider per-user vs per-IP limits.
How do you design timeouts and retries without causing outages?
Retries can amplify load during incidents. **Guidelines:** - Set sensible timeouts per dependency - Retry only safe operations (idempotent) - Use exponential backoff + jitter - Add circuit breakers and bulkheads - Prefer async processing for non-critical work **Interview tip:** mention “retry storms” and why jitter matters in distributed systems.
What is the circuit breaker pattern and when do you use it?
A circuit breaker prevents repeated calls to a failing dependency. **States:** closed (normal), open (fail fast), half-open (probe). **Benefits:** protects resources, avoids cascading failures, improves recovery. Use it for remote calls (HTTP/DB/queues) where failures can pile up and degrade the whole system.
When should backend systems use message queues?
Queues help decouple services and handle asynchronous work. **Use cases:** - Background jobs (emails, reports) - Smoothing traffic spikes - Integrations between services **Key concerns:** delivery semantics (at-least-once), idempotent consumers, retries, dead-letter queues, and monitoring lag.
What is event-driven architecture and what are its pros and cons?
Event-driven architecture communicates via events (publish/subscribe). **Pros:** loose coupling, scalability, extensibility, async workflows. **Cons:** harder debugging, eventual consistency, schema evolution challenges. **Best practices:** define event contracts, version events, and use an outbox pattern when publishing from a DB transaction.
Microservices vs monolith: how do you choose the right architecture?
A **monolith** is simpler to build, test, and deploy early. **Microservices** can scale teams and parts of a system independently. **Choose microservices when:** clear domain boundaries exist, teams need independent deployments, and you can invest in observability and platform tooling. **Interview tip:** emphasize that microservices add operational complexity (distributed tracing, deployments, data consistency).
What are common API versioning strategies and their trade-offs?
API versioning manages breaking changes. **Options:** - URL versioning (`/v1/...`) - Header-based versioning - Content negotiation **Best practice:** avoid breaking changes when possible by adding fields, keeping backward compatibility, and deprecating gradually with clear timelines.
How do you run zero-downtime database migrations?
Zero-downtime migrations avoid breaking production traffic. **Common approach:** - Expand/contract pattern - Add nullable columns first - Backfill data in batches - Deploy code that writes both old/new (dual-write) if needed - Switch reads to new column - Remove old column later Always test on staging and monitor during rollout.
What is structured logging and why is it important?
Structured logging writes logs as machine-readable fields (usually JSON) instead of unstructured text. **Benefits:** - Easier search/filtering - Better correlation across services - Works well with log aggregation tools Include request IDs, user IDs (non-sensitive), latency, status codes, and error types to make production debugging faster.
What metrics should you monitor in backend services?
Monitor what impacts reliability and user experience. **Core metrics:** - Latency (p50/p95/p99) - Error rate - Traffic (RPS) - Saturation (CPU, memory, DB connections) Also track dependency health, queue lag, and business KPIs. Alerts should be actionable and tied to SLOs when possible.
What is distributed tracing and how does it help debugging?
Distributed tracing tracks a request across multiple services using trace/span IDs. **Why it helps:** - Find the slowest hop in a request - Understand dependencies and call graphs - Debug timeouts and cascading failures **Interview tip:** mention propagation via headers and correlating traces with logs and metrics.
What is the N+1 query problem and how do you fix it?
N+1 happens when you fetch a list (1 query) and then fetch related data per item (N queries). **Fixes:** - Use joins or eager loading - Batch queries (IN clause) - Add caching for repeated lookups **Interview tip:** mention ORMs often hide this problem; profiling and query logging are essential.
How do you prevent SQL injection in backend applications?
SQL injection happens when user input changes query structure. **Prevention:** - Use parameterized queries / prepared statements - Avoid string concatenation for SQL - Validate input and use least-privilege DB accounts - Add WAF rules where appropriate **Interview tip:** mention that ORMs help but raw queries still need parameters.
What are best practices for secure file uploads?
File uploads are a common attack vector. **Best practices:** - Validate MIME type and file signatures - Limit size and rate - Store outside web root and use random file names - Virus/malware scan when needed - Use pre-signed URLs and object storage (S3-like) Never trust user-provided filenames or content types.
How do you design background jobs and worker systems?
Background jobs offload long-running work from request/response paths. **Design points:** - Use a queue, workers, and retry policies - Ensure idempotency (at-least-once delivery) - Add DLQs and monitoring (lag, failures) - Use backoff and rate limits **Interview tip:** mention job deduplication and visibility timeouts for queue systems.
WebSockets vs Server-Sent Events (SSE): when would you use each?
**WebSockets** are full-duplex (client and server can push messages). **SSE** is server → client only over HTTP. **Use SSE for:** live updates/notifications, simpler infrastructure. **Use WebSockets for:** chat, multiplayer, bi-directional real-time apps. Consider load balancing, connection limits, and message ordering guarantees.
How do you design a multi-tenant backend application?
Multi-tenancy means serving multiple customers (tenants) safely. **Key decisions:** - Data isolation (shared DB with tenant_id vs separate DB per tenant) - Tenant-aware authz and queries - Rate limits and noisy-neighbor protection - Configuration and feature flags per tenant Start with shared DB + strong isolation, then split high-value tenants if needed for scale or compliance.
What is the outbox pattern and why is it useful?
The outbox pattern reliably publishes events when a DB transaction commits. **How it works:** - Write business data + an outbox row in the same transaction. - A worker reads outbox rows and publishes events. - Mark rows as sent (idempotent publishing). This prevents “DB updated but event not published” inconsistencies in event-driven and microservice architectures.