Design APIs, data models, and reliable server systems.
3 topics
Backend development focuses on the server-side logic of a web application, handling data storage, processing, and security. Your first decision is choosing a programming language. Node.js (JavaScript/TypeScript) is excellent for full-stack developers and real-time applications. Python is great for rapid prototyping and data-heavy apps. Go excels at high-performance concurrent services. Java and C# dominate enterprise environments. Rust provides memory safety for systems-level backends. Pick one language and go deep — the concepts (HTTP handling, database access, authentication) transfer across languages. Most companies use Node.js or Python for startups, and Java/Go for scale.
2 resources
Backend developers need to understand the operating system their code runs on. Learn how processes and threads work, how memory is managed, file systems and I/O operations, and inter-process communication. Networking is equally critical: understand the TCP/IP model, how DNS resolution works, what sockets are and how they enable communication, the difference between TCP (reliable, ordered) and UDP (fast, unordered), and how HTTP sits on top of TCP. You should be comfortable with ports, IP addresses, subnets, firewalls, and TLS/SSL. This knowledge helps you debug connection issues, optimize performance, and architect systems that communicate reliably across networks.
Git is the industry-standard version control system that tracks changes to your code over time. Every backend developer must master: initializing repos, staging and committing changes, creating and merging branches, resolving merge conflicts, interactive rebasing for clean history, cherry-picking commits, using git stash for work-in-progress, and understanding the reflog for recovery. Beyond Git basics, learn collaborative workflows: feature branches, pull requests with code reviews, conventional commit messages, semantic versioning, and Git hooks for automation. Platforms like GitHub and GitLab add issue tracking, CI/CD pipelines, and project management on top of Git.
4 topics
Relational databases store data in tables with rows and columns, enforcing relationships through foreign keys. PostgreSQL is the most advanced open-source relational database. You need to understand: tables, columns, data types, and constraints (PRIMARY KEY, UNIQUE, NOT NULL, CHECK, FOREIGN KEY). Master SQL queries — SELECT with WHERE, JOIN (INNER, LEFT, RIGHT, FULL), GROUP BY with aggregation functions, subqueries, CTEs (Common Table Expressions), and window functions. Learn about indexes (B-tree, GIN, GiST) and how they speed up queries, transactions with ACID properties (Atomicity, Consistency, Isolation, Durability), isolation levels, and query planning with EXPLAIN ANALYZE. PostgreSQL also supports JSON, full-text search, and extensions like PostGIS.
MongoDB is a document database that stores data as flexible JSON-like documents (BSON). Unlike relational databases, documents in a collection can have different structures, making it ideal for rapid development and data with varying schemas. Key concepts include: documents and collections, the _id field and ObjectId, embedded documents vs references (and when to use each), CRUD operations, the aggregation pipeline (match, group, project, lookup, unwind), indexes (single field, compound, multikey, text, geospatial), and the MongoDB query language. Understand data modeling strategies — when to embed (one-to-few, data accessed together) vs reference (one-to-many, independent access) — and how MongoDB handles replication (replica sets) and sharding for horizontal scaling.
Redis is an in-memory data store used primarily for caching, session management, real-time leaderboards, rate limiting, and pub/sub messaging. It is incredibly fast because all data lives in RAM. Key data structures include: strings (simple key-value), hashes (object-like fields), lists (ordered collections), sets (unique values), sorted sets (ranked data), and streams (event logs). Important concepts include: TTL (time-to-live) for automatic expiration, cache patterns (cache-aside, write-through, write-behind), eviction policies (LRU, LFU, random), persistence options (RDB snapshots, AOF logging), and Redis Cluster for horizontal scaling. Redis dramatically reduces database load and response times — a typical cache hit takes under 1ms compared to 10-100ms for a database query.
Object-Relational Mappers (ORMs) provide a high-level abstraction over raw SQL, letting you interact with databases using your programming language's objects and methods. Prisma is the most popular ORM in the Node.js/TypeScript ecosystem — it uses a declarative schema file to define your data model, generates a type-safe client, handles migrations, and provides an intuitive query API. Drizzle ORM is a newer alternative that is more SQL-like and lightweight. For Python, SQLAlchemy is the gold standard. ORMs handle connection pooling, query building, relationship loading (eager vs lazy), transactions, and schema migrations. While ORMs boost productivity, you should still understand raw SQL for complex queries, debugging, and performance optimization — the N+1 query problem is a classic ORM pitfall.
REST (Representational State Transfer) is the most common architectural style for web APIs. RESTful APIs use HTTP methods as verbs: GET (read), POST (create), PUT (full update), PATCH (partial update), DELETE (remove). Resources are identified by URLs (/api/users/123), and responses typically use JSON. Key principles include: statelessness (each request contains all needed info), proper use of HTTP status codes (200 OK, 201 Created, 400 Bad Request, 401 Unauthorized, 404 Not Found, 500 Server Error), pagination for large collections, filtering and sorting via query parameters, HATEOAS (including links to related resources), and versioning strategies (URL path /v1/ or headers). Well-designed REST APIs are predictable, consistent, and self-documenting.
GraphQL is a query language for APIs that lets clients request exactly the data they need. Unlike REST where each endpoint returns a fixed structure, GraphQL has a single endpoint and clients specify their data requirements in the query. Key concepts include: the schema (types, queries, mutations, subscriptions), resolvers (functions that fetch the actual data), the type system (scalar types, object types, enums, interfaces, unions), arguments and variables, fragments for reusable query pieces, and directives. GraphQL solves REST's over-fetching (getting too much data) and under-fetching (needing multiple requests) problems. Popular server implementations include Apollo Server and GraphQL Yoga. Understanding the N+1 problem and DataLoader pattern is essential for performance.
gRPC is a high-performance Remote Procedure Call (RPC) framework developed by Google. It uses Protocol Buffers (protobuf) as its interface definition language and serialization format, which is much faster and smaller than JSON. gRPC supports four communication patterns: unary (request-response like REST), server streaming, client streaming, and bidirectional streaming. It is built on HTTP/2, providing multiplexing, header compression, and binary framing. gRPC is ideal for microservice communication where performance matters, real-time data streaming, and polyglot environments (auto-generated clients in any language from .proto files). It is less suited for browser-to-server communication (though gRPC-Web exists) and is overkill for simple CRUD APIs.
OpenAPI (formerly Swagger) is a specification for describing REST APIs in a machine-readable format (YAML or JSON). An OpenAPI document defines your API's endpoints, request/response schemas, authentication methods, and error formats. From this single source of truth, you can auto-generate interactive documentation (Swagger UI, Redoc), client SDKs in any language, server stubs, mock servers for frontend development, and contract tests. This "API-first" or "design-first" approach means you design the API contract before writing code, align frontend and backend teams early, catch breaking changes, and maintain always-up-to-date documentation. Tools like Stoplight and Postman provide visual editors for creating OpenAPI specs.
Authentication verifies who a user is, while authorization determines what they can do. Session-based auth stores a session ID in a cookie — the server keeps session data in memory or a database. JWT (JSON Web Tokens) are stateless — the token itself contains user claims, is signed by the server, and verified on each request without database lookups. OAuth 2.0 is the standard for third-party authentication (Sign in with Google/GitHub) — it uses authorization codes, access tokens, and refresh tokens. OpenID Connect (OIDC) adds an identity layer on top of OAuth2. You should understand: password hashing (bcrypt, argon2), multi-factor authentication (TOTP, SMS), API keys for service-to-service auth, and role-based access control (RBAC) for authorization. Always store secrets securely and never expose tokens in URLs.
3 resources
The OWASP Top 10 is the most recognized list of critical web application security risks. Every backend developer must understand and defend against: Injection attacks (SQL injection, NoSQL injection — use parameterized queries), Broken Authentication (weak passwords, missing rate limits), Sensitive Data Exposure (encrypt at rest and in transit), XML External Entities (disable external entity processing), Broken Access Control (always check permissions server-side), Security Misconfiguration (default credentials, open ports, verbose errors), Cross-Site Scripting (XSS — sanitize output, use CSP headers), Insecure Deserialization (validate and sanitize input), Using Components with Known Vulnerabilities (keep dependencies updated with npm audit), and Insufficient Logging and Monitoring (log security events, set up alerts).
Rate limiting controls how many requests a client can make to your API within a time window. It protects against denial-of-service attacks, brute-force login attempts, API abuse, and resource exhaustion. Common algorithms include: fixed window (simple counter per time window), sliding window (smoother distribution), token bucket (allows bursts), and leaky bucket (constant rate). Implementation can be per-IP, per-user, per-API-key, or per-endpoint. HTTP headers like X-RateLimit-Limit, X-RateLimit-Remaining, and Retry-After communicate limits to clients. Return 429 Too Many Requests when limits are exceeded. In distributed systems, use Redis or a shared store for rate limit counters. API gateways (Kong, AWS API Gateway) and reverse proxies (Nginx) can handle rate limiting at the infrastructure level.
Caching is storing frequently accessed data in a faster storage layer to reduce latency and database load. The most common pattern is cache-aside (lazy loading): check the cache first, if miss then query the database and store the result in cache. Write-through writes to cache and database simultaneously for consistency. Write-behind (write-back) writes to cache immediately and asynchronously syncs to the database for better write performance. Cache invalidation is one of the hardest problems in computer science — strategies include TTL (time-based expiration), event-driven invalidation (purge cache when data changes), and versioned keys. Layer your caching: browser cache (HTTP headers), CDN (edge caching), application cache (Redis/Memcached), and database query cache. Monitor cache hit rates — below 90% suggests your caching strategy needs work.
Message queues enable asynchronous communication between services by decoupling the sender (producer) from the receiver (consumer). Instead of processing everything in the request-response cycle, you place tasks in a queue and process them in the background. This improves reliability (messages persist if a consumer is down), scalability (add more consumers to handle load), and user experience (respond to the user immediately, process later). Apache Kafka is a distributed event streaming platform ideal for high-throughput, real-time data pipelines and event sourcing. RabbitMQ is a traditional message broker with flexible routing. AWS SQS is a fully managed queue service. BullMQ is popular for Node.js background jobs. Key concepts include: topics/queues, producers/consumers, dead letter queues, message ordering, at-least-once vs exactly-once delivery, and idempotency.
Microservices architecture breaks a large application into small, independently deployable services, each owning its own data and business logic. Each service communicates via APIs (REST, gRPC, or message queues). Benefits include independent scaling, technology flexibility (each service can use different languages/databases), and team autonomy. Challenges include distributed system complexity, network latency, data consistency across services, service discovery, and debugging across boundaries. Key patterns include: API Gateway (single entry point), Circuit Breaker (graceful degradation when a service is down), Saga pattern (distributed transactions), CQRS (separate read/write models), and Event Sourcing (storing state as a sequence of events). Start with a monolith and extract microservices only when you have clear boundaries — premature microservices is a common mistake.
Observability is the ability to understand what is happening inside your system by examining its external outputs. The three pillars are: Logs (discrete events — use structured logging with JSON, include request IDs for tracing, use log levels appropriately), Metrics (numerical measurements over time — request rate, error rate, latency percentiles, CPU/memory usage, queue depth), and Traces (following a request across multiple services — distributed tracing shows the complete journey). OpenTelemetry is the vendor-neutral standard for instrumentation, supporting all three pillars. Prometheus collects and stores metrics, Grafana visualizes them in dashboards, and Jaeger or Zipkin handle distributed tracing. Set up alerts on key metrics (error rate spikes, latency increases, resource exhaustion) so you know about problems before users report them.
Continuous Integration (CI) automatically builds and tests your code every time you push changes. Continuous Deployment (CD) automatically deploys tested code to production. Together, CI/CD reduces risk by making deployments small, frequent, and reversible. A typical pipeline: push code → run linter → run unit tests → run integration tests → build Docker image → deploy to staging → run E2E tests → deploy to production. GitHub Actions is the most popular CI/CD platform for open source — it uses YAML workflow files, supports matrix builds, caching, secrets management, and reusable workflows. GitLab CI, CircleCI, and Jenkins are alternatives. Key practices: keep builds fast (under 10 minutes), fail fast (run fastest tests first), and implement automatic rollback on failure.
Containers package your application with all its dependencies into a single, portable unit that runs consistently across any environment. Docker is the standard container runtime. A Dockerfile defines how to build your image — starting from a base image, copying code, installing dependencies, and specifying the start command. Key concepts include: images vs containers, layers and caching for fast builds, multi-stage builds (build in one stage, copy artifacts to a minimal runtime image), Docker Compose for local multi-container setups (app + database + cache), volumes for persistent data, networks for container communication, and environment variables for configuration. Docker ensures "it works on my machine" problems disappear — the same container runs identically in development, CI, staging, and production.
Cloud platforms provide on-demand computing resources without managing physical hardware. AWS (Amazon Web Services) is the market leader with 200+ services. Essential services every backend developer should know: EC2 (virtual servers), S3 (object storage for files and static assets), RDS (managed databases — PostgreSQL, MySQL), Lambda (serverless functions — pay only for execution time), CloudFront (CDN for global content delivery), SQS/SNS (messaging and notifications), IAM (identity and access management), and CloudWatch (monitoring and logging). Google Cloud Platform offers equivalent services (Compute Engine, Cloud Storage, Cloud SQL, Cloud Functions). The key principle is using managed services over self-hosted when possible — let the cloud provider handle scaling, patching, backups, and availability while you focus on your application logic.