Senior Backend Engineer
Backend development patterns, API design, database optimization, and security practices for any language or framework.
Step 1: Detect the Stack
Before writing any code, identify the language and framework from project signals:
| Signal file / pattern |
Stack |
package.json with express/fastify/hono/koa |
Node.js |
package.json with nest |
NestJS |
go.mod |
Go |
Cargo.toml |
Rust |
pyproject.toml / requirements.txt + FastAPI/Django/Flask |
Python |
pom.xml / build.gradle |
Java/Spring |
*.csproj / Program.cs |
.NET/C# |
mix.exs |
Elixir/Phoenix |
Gemfile with rails/sinatra |
Ruby |
Check: ls -la, cat package.json, cat go.mod, cat pyproject.toml — whichever exists.
Step 2: Research Current Practices
Once you know the stack, search for current best practices before making recommendations:
WebSearch: "<framework> REST API best practices 2025"
WebSearch: "<framework> authentication JWT best practices 2025"
WebSearch: "<database> query optimization <framework> 2025"
WebSearch: "<framework> microservices patterns 2025"
Use the search results to ground your recommendations in current community standards.
Step 3: Universal Backend Principles
These apply regardless of language or framework.
API Design
- REST resource naming: nouns, plural, lowercase (
/users, /orders/{id})
- Versioning:
/api/v1/ prefix or Accept: application/vnd.api+json;version=1 header
- Status codes: 200 OK, 201 Created, 204 No Content, 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict, 422 Unprocessable Entity, 429 Too Many Requests, 500 Internal Server Error
- Pagination: cursor-based for large/changing datasets, offset-based for small/stable ones
- Idempotency: PUT and DELETE must be idempotent; POST uses idempotency keys for critical operations
- Error shape: consistent
{ error: { code, message, details } } across all endpoints
Database
- N+1 prevention: use eager loading / joins — never query in a loop
- Index strategy: index foreign keys, columns in WHERE/ORDER BY/GROUP BY; composite indexes for multi-column filters
- Transactions: wrap multi-step mutations; use the lowest isolation level that preserves correctness
- Migrations: always reversible (up + down); never drop columns in same deploy as code change
- Connection pooling: always use a pool; size = (2 x CPU cores) + effective spindle count as starting point
Authentication and Authorization
- Password storage: bcrypt/argon2/scrypt — never MD5, SHA1, or plain SHA256
- JWT: short-lived access tokens (15m), long-lived refresh tokens (7d) stored httpOnly cookie; validate
alg, iss, aud, exp
- Session tokens: cryptographically random, 128+ bits, stored server-side
- RBAC: check permissions at the service layer, not just the route layer
- Rate limiting: per-user and per-IP on auth endpoints; exponential backoff on failures
Error Handling
- Never swallow errors: log with context (user ID, request ID, stack trace)
- Distinguish errors: validation (400), auth (401/403), not found (404), conflict (409), server (500)
- Structured logging: JSON logs with
level, timestamp, requestId, userId, message, error
- Circuit breakers: wrap external service calls; fail fast when downstream is degraded
Security
- Input validation: validate at the boundary — type, range, format, length
- SQL injection: always use parameterized queries / prepared statements
- Command injection: never interpolate user input into shell commands
- CORS: explicit allowlist — never
* in production for credentialed requests
- Secrets: environment variables or secret manager — never hardcoded, never in version control
- Dependencies: audit regularly (
npm audit, cargo audit, pip-audit, govulncheck)
Performance
- Caching strategy: cache at the right layer (CDN -> reverse proxy -> app -> DB); set explicit TTLs and cache-control headers
- Async processing: move slow work (email, image processing, reports) to a queue
- Payload size: paginate large responses; use field selection (GraphQL) or sparse fieldsets (JSON:API)
- Database reads: read replicas for reporting queries; connection pooling for all queries
Review Checklist
Before any backend PR:
1---2name: senior-backend-23description: This skill should be used when the user asks to "design REST APIs", "optimize database queries", "implement authentication", "build microservices", "review backend code", "set up GraphQL", "handle database migrations", or "load test APIs".4---5
6# Senior Backend Engineer
7
8Backend development patterns, API design, database optimization, and security practices for any language or framework.
9
10---
11
12## Step 1: Detect the Stack
13
14Before writing any code, identify the language and framework from project signals:
15
16| Signal file / pattern | Stack |
17|----------------------|-------|
18| `package.json` with express/fastify/hono/koa | Node.js |
19| `package.json` with nest | NestJS |
20| `go.mod` | Go |
21| `Cargo.toml` | Rust |
22| `pyproject.toml` / `requirements.txt` + FastAPI/Django/Flask | Python |
23| `pom.xml` / `build.gradle` | Java/Spring |
24| `*.csproj` / `Program.cs` | .NET/C# |
25| `mix.exs` | Elixir/Phoenix |
26| `Gemfile` with rails/sinatra | Ruby |
27
28Check: `ls -la`, `cat package.json`, `cat go.mod`, `cat pyproject.toml` — whichever exists.
29
30---
31
32## Step 2: Research Current Practices
33
34Once you know the stack, search for current best practices before making recommendations:
35
36```
37WebSearch: "<framework> REST API best practices 2025"
38WebSearch: "<framework> authentication JWT best practices 2025"
39WebSearch: "<database> query optimization <framework> 2025"
40WebSearch: "<framework> microservices patterns 2025"
41```
42
43Use the search results to ground your recommendations in current community standards.
44
45---
46
47## Step 3: Universal Backend Principles
48
49These apply regardless of language or framework.
50
51### API Design
52
53- **REST resource naming**: nouns, plural, lowercase (`/users`, `/orders/{id}`)
54- **Versioning**: `/api/v1/` prefix or `Accept: application/vnd.api+json;version=1` header
55- **Status codes**: 200 OK, 201 Created, 204 No Content, 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict, 422 Unprocessable Entity, 429 Too Many Requests, 500 Internal Server Error
56- **Pagination**: cursor-based for large/changing datasets, offset-based for small/stable ones
57- **Idempotency**: PUT and DELETE must be idempotent; POST uses idempotency keys for critical operations
58- **Error shape**: consistent `{ error: { code, message, details } }` across all endpoints
59
60### Database
61
62- **N+1 prevention**: use eager loading / joins — never query in a loop
63- **Index strategy**: index foreign keys, columns in WHERE/ORDER BY/GROUP BY; composite indexes for multi-column filters
64- **Transactions**: wrap multi-step mutations; use the lowest isolation level that preserves correctness
65- **Migrations**: always reversible (up + down); never drop columns in same deploy as code change
66- **Connection pooling**: always use a pool; size = (2 x CPU cores) + effective spindle count as starting point
67
68### Authentication and Authorization
69
70- **Password storage**: bcrypt/argon2/scrypt — never MD5, SHA1, or plain SHA256
71- **JWT**: short-lived access tokens (15m), long-lived refresh tokens (7d) stored httpOnly cookie; validate `alg`, `iss`, `aud`, `exp`
72- **Session tokens**: cryptographically random, 128+ bits, stored server-side
73- **RBAC**: check permissions at the service layer, not just the route layer
74- **Rate limiting**: per-user and per-IP on auth endpoints; exponential backoff on failures
75
76### Error Handling
77
78- **Never swallow errors**: log with context (user ID, request ID, stack trace)
79- **Distinguish errors**: validation (400), auth (401/403), not found (404), conflict (409), server (500)
80- **Structured logging**: JSON logs with `level`, `timestamp`, `requestId`, `userId`, `message`, `error`
81- **Circuit breakers**: wrap external service calls; fail fast when downstream is degraded
82
83### Security
84
85- **Input validation**: validate at the boundary — type, range, format, length
86- **SQL injection**: always use parameterized queries / prepared statements
87- **Command injection**: never interpolate user input into shell commands
88- **CORS**: explicit allowlist — never `*` in production for credentialed requests
89- **Secrets**: environment variables or secret manager — never hardcoded, never in version control
90- **Dependencies**: audit regularly (`npm audit`, `cargo audit`, `pip-audit`, `govulncheck`)
91
92### Performance
93
94- **Caching strategy**: cache at the right layer (CDN -> reverse proxy -> app -> DB); set explicit TTLs and cache-control headers
95- **Async processing**: move slow work (email, image processing, reports) to a queue
96- **Payload size**: paginate large responses; use field selection (GraphQL) or sparse fieldsets (JSON:API)
97- **Database reads**: read replicas for reporting queries; connection pooling for all queries
98
99---
100
101## Review Checklist
102
103Before any backend PR:
104
105- [ ] All inputs validated and sanitized at the boundary
106- [ ] Auth checked — correct user can do this, others cannot
107- [ ] N+1 queries absent — checked with query logging or explain
108- [ ] Error paths return correct status codes and structured errors
109- [ ] Secrets in env vars, not source
110- [ ] DB migrations are reversible
111- [ ] Logging includes requestId and userId for traceability
112- [ ] Rate limiting on public/auth endpoints
113- [ ] No shell command injection surface
114- [ ] Dependencies pinned and audited