API Design · Google Interview
/
★ API Design · System Design Interview

Cómo diseñar APIs para defender cualquier sistema

Plantilla práctica, casos reales y conceptos críticos para Google: REST vs gRPC (lo que usan internamente), autenticación, idempotencia, paginación, real-time. Presiona / para buscar.

1 Framework para diseñar APIs

Sigue estos 7 pasos cuando te pidan "diseña el API de X". Verbaliza cada uno.

PASO 1
Recursos
Identifica sustantivos: users, documents, rides, videos. Plural, en kebab-case.
PASO 2
Operaciones
CRUD + custom actions. List, Get, Create, Update, Delete, Search.
PASO 3
Schema
Request/response shape. Tipos, campos requeridos, validación.
PASO 4
Escala
Cache, paginación, async (queue), CDN, batch endpoints.
PASO 5
Seguridad
Auth (OAuth/JWT), rate limit, idempotency, input validation.
PASO 6
Errores & versionado
Status codes, error format, /v1 vs header, deprecación.
PASO 7
Observabilidad
Logs, métricas (p50/p95/p99), tracing, SLO.

📐 Resource-oriented (Google AIP)

Google prefiere APIs resource-oriented: las URLs son recursos, los métodos HTTP son verbos. POST /users mejor que POST /createUser.

📛 Naming conventions

  • Recursos en plural: /users
  • IDs en path: /users/{userId}
  • Sub-recursos: /users/{id}/posts
  • kebab-case en paths, camelCase en JSON
  • Verbos custom como acciones: POST /videos/{id}:publish

🎯 Frase de oro al iniciar

"Voy a empezar identificando los recursos principales, luego las operaciones por recurso, y de ahí derivo los endpoints. Después hablo de paginación, errores, auth y rate limiting."

2 Métodos HTTP & Status Codes

Los fundamentos. Si confundes idempotencia o status codes, pierdes credibilidad de inmediato.

Métodos HTTP — qué hacen, cuándo, idempotencia
Método Uso Ejemplo Idempotente Status típico
GET Leer un recurso o lista. Cacheable. Nunca modifica estado. GET /api/users/u_42 Safe + idempotent 200 404
POST Crear recurso o disparar acción. Server asigna ID. POST /api/users No Usa Idempotency-Key 201 202
PUT Reemplazar recurso completo. Cliente puede asignar ID. PUT /api/users/u_42 Mismo body = mismo estado 200 204
PATCH Actualizar parcial. Envía solo los campos a cambiar. PATCH /api/users/u_42 Depende Si es JSON-Merge: sí 200 409
DELETE Eliminar (hard) o soft-delete con tombstone. DELETE /api/users/u_42 Borrar dos veces = igual 204 404
HEAD Como GET pero solo headers. Para checks de existencia. HEAD /api/files/abc 200 404
OPTIONS Capabilities y CORS preflight. OPTIONS /api/users 204
Status Codes — los que SÍ se preguntan
Código Nombre Cuándo usarlo Trampa / nota
200 OK Éxito con body. Para GET, PUT, PATCH, DELETE con respuesta. Default success. No abuses si no hay body — usa 204.
201 Created POST exitoso que creó recurso. Devuelve Location header. Solo para creación. POST que dispara acción usa 200/202.
202 Accepted Aceptado para procesamiento async. Devuelve job ID o status URL. Crítico para uploads, batch, transcoding. Mucho mejor que dejar el cliente colgado.
204 No Content Éxito sin body. Para DELETE, PUT que no devuelven nada. Sin body literal. Si quieres devolver el recurso actualizado, usa 200.
301 Moved Permanently Recurso movido de URL para siempre. Cacheable. URL shortener clásico usa 301 (cacheado por browser).
302 Found Redirect temporal. URL puede cambiar después. Para login flows, A/B test redirects.
304 Not Modified Cliente envió If-None-Match o If-Modified-Since y el recurso no cambió. Ahorra bandwidth. Esencial con ETags.
400 Bad Request Request mal formado, JSON inválido, parámetros faltantes. Genérico. Para validación específica de campos, considera 422.
401 Unauthorized No autenticado o token inválido/expirado. Mal nombrado: significa "no auth", no "no permiso". Devuelve WWW-Authenticate.
403 Forbidden Autenticado pero sin permiso para este recurso. Importante distinción con 401. Algunos prefieren 404 para no revelar existencia.
404 Not Found Recurso no existe o user no tiene permiso de saber. Útil para no filtrar info sobre recursos privados.
409 Conflict Conflicto de estado: duplicate, version mismatch (ETag), resource locked. Optimistic concurrency con If-Match → 409 si cambió.
410 Gone Recurso existió, fue eliminado intencionalmente, no volverá. Para deprecation o GDPR delete. Mejor que 404 para SEO.
422 Unprocessable Entity Sintaxis OK pero validación de negocio falló. Email inválido, edad negativa. Ideal con cuerpo de errores por campo (ver sección 5).
429 Too Many Requests Rate limit excedido. Devuelve Retry-After. Imprescindible.
500 Internal Server Error Bug genérico. NO incluyas stack traces en prod. Default cuando nada más aplica. Logueas, alertas, regresas correlationId.
502 Bad Gateway Upstream service devolvió error o no responde. Reverse proxy / API Gateway clásico cuando backend muere.
503 Service Unavailable Sobrecarga, maintenance, o circuit breaker abierto. Devuelve Retry-After. Cliente debe hacer backoff.
504 Gateway Timeout Upstream no respondió a tiempo. Diferenciar de 503: aquí sí intentaste, pero timeout.

3 REST vs gRPC vs GraphQL

Google usa gRPC internamente. Mencionar gRPC bien sumará puntos.

Aspecto REST gRPC GraphQL
Transporte HTTP/1.1 (típico) HTTP/2 (multiplexed, header compression) HTTP/1.1 (típico)
Formato JSON (texto) Protocol Buffers (binario, ~3-10× más pequeño) JSON
Schema OpenAPI opcional .proto file obligatorio GraphQL SDL obligatorio
Performance Buena Excelente (binario + HTTP/2) Variable (resolver overhead)
Streaming Limitado (SSE, chunked) Bidirectional nativo (4 modos) Subscriptions (vía WebSocket)
Browser support Nativo Necesita gRPC-Web + proxy Nativo
Caching Excelente (HTTP cache, CDN, ETag) No nativo (HTTP/2 push o app-level) Difícil (queries únicas)
Code-gen Manual u OpenAPI generators Automático en muchos lenguajes Tools maduras (Apollo, urql)
Mejor para APIs públicas, integraciones B2B, mobile. Microservicios internos, baja latencia, polyglot. Frontends con muchas vistas, agregación.
Uso en Google Cloud APIs públicas (con gRPC subyacente) Default interno · Stubby precursor Menos común

🟦 Cuándo elegir REST

  • API pública, partners externos
  • Necesitas caching agresivo (CDN)
  • Clientes heterogéneos (curl, browsers)
  • Recursos claros, CRUD-heavy
  • Discoverability importa (OpenAPI)

🟩 Cuándo elegir gRPC

  • Microservicios internos
  • Latencia crítica (mobile, edge)
  • Streaming bidireccional (chat, video)
  • Polyglot teams (auto-gen clients)
  • Schema evolution importante

🟪 Cuándo elegir GraphQL

  • Frontends con muchas vistas distintas
  • Reducir over-fetching móvil
  • Aggregar múltiples backends (BFF)
  • Schema-driven dev workflow
  • Cuidado: N+1 queries, caching difícil

📡 gRPC streaming modes

  • Unary: request → response (como REST normal)
  • Server streaming: 1 request → N responses (feed, logs)
  • Client streaming: N requests → 1 response (upload chunks)
  • Bidirectional: N ↔ N (chat, gaming, real-time)

🇬 Tip Google-specific

Google publicó las API Improvement Proposals (AIP) en aip.dev — son sus reglas internas. Menciona resource-oriented design, standard methods (List, Get, Create, Update, Delete), field masks para updates parciales (en lugar de PATCH), y nombres pluralizados.

4 Autenticación & Autorización

Auth = quién eres. Authz = qué puedes hacer. No los confundas.

Mecanismo Cómo funciona Cuándo usarlo Pros / Contras
API Keys Header X-API-Key: abc o query param. Server valida en DB. APIs server-to-server, integraciones simples, tracking de quotas. + Simple · − Sin expiración nativa, mismo nivel de acceso, no auditable a nivel user.
Basic Auth Authorization: Basic base64(user:pass) Solo internal/testing sobre TLS. + Trivial · − Credenciales en cada request. Evítalo en producción.
JWT (Bearer) Token firmado (HS256/RS256) con claims. Authorization: Bearer eyJ.... Stateless. Microservicios, mobile/web apps, sesiones distribuidas. + Stateless, escala · − Revocación difícil, tamaño grande, no incluyas datos sensibles.
OAuth 2.0 Delegated auth con scopes. Auth Code (web), Client Credentials (s2s), Device (TVs), PKCE (mobile/SPA). "Login con Google". APIs de terceros. Scopes granulares. + Estándar industria · − Complejidad. Implícito está deprecated; usa PKCE.
OIDC Capa de identidad sobre OAuth 2.0. ID Token (JWT) + UserInfo endpoint. Cuando además de auth necesitas saber quién es el user. + Identity estándar · − Otra capa más, depende de un IdP.
Session cookies Server crea sesión, manda cookie firmada. State server-side. Web apps tradicionales, mismo dominio. + Revocable trivial · − CSRF, escala (Redis sessions), no funciona cross-domain.
mTLS Mutual TLS: cliente y servidor presentan certs. Verificación criptográfica. Service-to-service en zero-trust networks. PCI, banking, GovCloud. + Muy seguro, sin secret en banda · − Cert management complejo, rotación.
IAM (cloud) Service accounts con roles. GCP/AWS firma requests con SDK. Apps corriendo en GCP/AWS hablando con APIs cloud. + Sin secrets gestionados, audit log automático · − Vendor lock-in.

🔑 JWT structure

3 partes base64 separadas por puntos:

// Header
{ "alg": "RS256", "typ": "JWT" }

// Payload (claims)
{
  "sub": "user_42",
  "iss": "auth.example.com",
  "aud": "api.example.com",
  "exp": 1735689600,
  "iat": 1735686000,
  "scope": "read:users write:posts"
}

// Signature: RSA-sign(header.payload, private_key)

🛂 Authorization (RBAC vs ABAC)

  • RBAC: Roles → Permissions. Simple. "Editor puede actualizar posts"
  • ABAC: Atributos contextuales. "Puede leer SI: dueño OR rol = admin OR documento es público"
  • ReBAC (Zanzibar): Google Drive style — relaciones (owner, editor, viewer) entre user y recurso. Spanner-backed.
  • Tip: En Google interview, menciona Zanzibar si el problema involucra permisos complejos (Drive, Docs).

5 Patrones API críticos

Paginación, versionado, errores, idempotencia, rate limiting. Lo que diferencia diseño junior de senior.

📑 Paginación — 4 estrategias
Estrategia Ejemplo Pros Contras
Offset/Limit GET /items?offset=100&limit=20 Simple, jump a página N. Lento en datasets grandes (DB skip), inconsistente si insertas/borras durante pagination.
Page-based GET /items?page=5&size=20 Como offset, más amigable para UI. Mismos problemas que offset.
Cursor GET /items?cursor=eyJpZCI6MTIzfQ&limit=20 Estable, escala, opaco al cliente. No puedes saltar a página N; solo siguiente/anterior.
Keyset (seek) GET /items?after_id=123&limit=20 Más rápido (índice), determinístico. Requiere campo ordenable único; tampoco hay "ir a página 5".

📤 Response shape recomendado

{
  "data": [ /* items */ ],
  "pagination": {
    "next_cursor": "eyJpZCI6MTQzfQ==",
    "has_more": true,
    "total": 10000  // opcional, costoso
  }
}
🔢 Versionado — 4 estrategias
Estrategia Ejemplo Pros Contras
URL path /v1/users · /v2/users Visible, fácil debug, fácil routing. Default Google Cloud. "REST puristas" objetan que la versión está en el recurso.
Query param /users?v=2 Fácil rollback con feature flag. Cache complica, fácil olvidar.
Header custom Accept-Version: 2 URL limpia, separación de concerns. No visible en logs/curl, harder debug.
Media type Accept: application/vnd.api.v2+json "REST puro", content negotiation. Verbose, casi nadie lo usa, herramientas no lo respetan.

Recomendación: URL path (/v1/). Es lo que Google, Stripe, Twilio y AWS usan. Solo hace breaking changes en major versions; cambios aditivos compatibles van en v1. Anuncia deprecation con header Sunset + 6-12 meses de aviso.

❌ Formato de errores — RFC 7807 + estilo Google

📋 RFC 7807 (Problem Details)

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/problem+json

{
  "type": "https://api.x/errors/validation",
  "title": "Validation failed",
  "status": 422,
  "detail": "Email format invalid",
  "instance": "/users/u_42",
  "errors": [
    { "field": "email", "code": "format" }
  ]
}

🇬 Google API Error Format

HTTP/1.1 404 Not Found

{
  "error": {
    "code": 404,
    "message": "User not found",
    "status": "NOT_FOUND",
    "details": [{
      "@type": "...ErrorInfo",
      "reason": "USER_NOT_FOUND",
      "domain": "googleapis.com"
    }]
  }
}

Reglas de oro: (1) Status code HTTP correcto · (2) Mensaje legible para humano · (3) Código de error machine-readable estable · (4) correlationId para soporte · (5) NUNCA stack traces en prod · (6) En 4xx ayuda al cliente a corregir; en 5xx solo loguea internamente.

🔁 Idempotencia — el patrón que SIEMPRE preguntan

🤔 Por qué importa

El cliente pierde la conexión justo cuando el server procesó el POST. ¿Reintenta? Si lo hace, ¿creará 2 órdenes? La idempotencia previene duplicados en pagos, órdenes, transferencias.

  • GET, PUT, DELETE: idempotentes por definición
  • POST: NO. Necesita Idempotency-Key
  • PATCH: depende de la operación

⚙️ Implementación

  1. Cliente genera UUID en Idempotency-Key header
  2. Server hash(key + request_fingerprint) → busca en Redis/DB
  3. Si existe + mismo body → devuelve respuesta cacheada
  4. Si existe + body distinto → 409 Conflict
  5. Si no existe → procesa, guarda (key, response, hash) por 24h
  6. TTL típico: 24-72h
POST /api/payments
Idempotency-Key: "client-generated-uuid-abc-123"
Content-Type: application/json

{ "amount": 5000, "to": "acct_xyz" }

// Server: si ya vió esa key con mismo body → devuelve la response original
// Si vió la key con body distinto → 409 Conflict
// Si nunca vió la key → procesa, guarda (key → response) en Redis 24h
🚦 Rate Limiting — algoritmos & headers

🪣 Algoritmos

  • Token bucket: permite bursts, refill constante. Default.
  • Leaky bucket: tasa fija de salida, suaviza tráfico.
  • Fixed window: simple, problema de doble pico al borde.
  • Sliding window log: preciso, mucha memoria.
  • Sliding window counter: aproximación buena con poca memoria.

📨 Headers obligatorios

HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 37
X-RateLimit-Reset: 1735689600

// Cuando excedes:
HTTP/1.1 429 Too Many Requests
Retry-After: 42  // segundos

Rate limit por: user, API key, IP, endpoint, o combinación. Distribuido: Redis con INCR + EXPIRE atómico (Lua script). Tiers: free (10 RPM), basic (100), pro (1K), enterprise (custom). Documenta los límites en docs públicas.

6 Real-time & comunicación bidireccional

Chat, notificaciones, live updates, multiplayer. Cuándo elegir cada tecnología.

Tecnología Cómo funciona Cuándo usar Pros / Contras
Short polling Cliente hace GET cada N segundos. Updates de baja frecuencia (status de un job, dashboard refresh). + Trivial, funciona con cualquier infra · − Wasteful (la mayoría devuelve nada).
Long polling Server retiene la request hasta que hay update o timeout. Cuando WS no es opción (firewalls), updates ocasionales. + Real-time-ish sobre HTTP simple · − Conexiones largas, server resources.
SSE Server-Sent Events. HTTP/1.1 stream. Solo server → client. Notificaciones, live feed, AI tokens streaming, stock prices. + Auto-reconnect, simple, funciona con CDN · − Unidireccional.
WebSocket Upgrade desde HTTP. TCP persistente bidireccional. Chat, gaming, colaboración (Docs), trading, multiplayer. + Full duplex, baja latencia · − Stateful (sticky LB), proxies a veces, no caching.
gRPC streaming HTTP/2 streams. 4 modos (unary, server, client, bidi). Servicio interno con streaming + tipos fuertes. + Eficiente, schema, multiplexing · − Browser necesita gRPC-Web.
Webhooks Server A llama a un endpoint público de server B (HTTP POST). Stripe → tu app, GitHub events, async callbacks B2B. + Server-to-server, simple · − Tu endpoint debe ser público + idempotente + verificar firma.
Push (FCM/APNs) Notificación a OS de mobile/desktop. Vendor-mediated. App cerrada, ahorro de batería. + Funciona offline · − No garantizado, latencia variable.

📡 SSE en 30 segundos

// Server response:
Content-Type: text/event-stream
Cache-Control: no-cache

event: update
data: {"price": 42.5}

event: update
data: {"price": 42.7}

🔌 WebSocket scaling

  • Sticky LB (mismo cliente → misma instancia)
  • Pub/Sub backplane (Redis/Pub-Sub) para fan-out
  • Heartbeat (ping/pong) cada 30s
  • Reconnect con exponential backoff
  • Auth en query/cookie (no header en handshake)

🪝 Webhooks bien hechos

  • HMAC signature en header (verifica origen)
  • Endpoint idempotente + dedup por event_id
  • Retry con exponential backoff (24h)
  • Dead letter queue tras N fallos
  • Devuelve 200 rápido, procesa async

7 Casos típicos & APIs sugeridas

10 problemas frecuentes. La clave no es memorizar, es reconocer recursos y flujos.

1. E-commerce: top productos

Ranking

Top 10 productos más comprados en 1h, 4h o 24h.

  • Problema central: ranking en ventanas de tiempo.
  • Solución: eventos de compra → Pub/Sub → agregador (Dataflow) → Bigtable counters → cache.
  • No hagas: SCAN sobre tabla de orders en cada click.
GET /api/products/top?window=1h&limit=10
GET /api/products/top?window=4h&limit=10
GET /api/products/top?window=24h&limit=10
POST /api/orders

2. Ride-sharing

Uber/Lyft

Clientes piden viaje; drivers cercanos reciben notificación en segundos.

  • Problema central: matching geoespacial en tiempo real.
  • Solución: location updates, geohash/S2, Pub/Sub, WebSocket/push.
  • Riesgo: ubicación vieja, drivers duplicados aceptando el mismo ride (race condition).
POST /api/rides (con Idempotency-Key)
PATCH /api/drivers/{driverId}/location
GET /api/drivers/nearby?lat=&lng=&radius=
POST /api/rides/{rideId}:accept

3. YouTube / streaming

Video

Subir, transcodificar, almacenar y reproducir videos a gran escala.

  • Problema central: ingestión pesada + entrega de baja latencia.
  • Solución: signed URL upload → Cloud Storage → Pub/Sub → transcoding workers → CDN.
  • No hagas: servir videos directo desde el app server. Eso es CDN territory.
POST /api/videos/upload-url
POST /api/videos/{videoId}:complete-upload
GET /api/videos/{videoId}
GET /api/videos/{videoId}/manifest.m3u8

4. Spotify

Music

Reproducir música, playlists, búsqueda y recomendaciones.

  • Problema central: catálogo + streaming + personalización.
  • Solución: metadata DB + Cloud Storage/CDN para audio + search index + reco service.
  • Cuidado: licencias por región, cache por usuario, derechos.
GET /api/tracks/{trackId}
GET /api/search?q=&type=track
POST /api/playlists/{id}/tracks
GET /api/recommendations?seed=...

5. TikTok feed

Feed ranking

Mostrar videos cortos personalizados con scroll infinito.

  • Problema central: ranking personalizado en baja latencia.
  • Solución: candidate generation + ranking model + feature store + cache.
  • Cuidado: cold start, diversidad, duplicados, freshness.
GET /api/feed?cursor=...&limit=10
POST /api/events/watch
POST /api/events/like
GET /api/videos/{videoId}

6. Google Docs

Collaboration

Documentos editados por varios usuarios al mismo tiempo.

  • Problema central: concurrencia y colaboración real-time.
  • Solución: OT/CRDT, WebSocket, version vector, conflict resolution.
  • Cuidado: lost updates, permisos (Zanzibar), audit log.
POST /api/documents
GET /api/documents/{documentId}
POST /api/documents/{documentId}/operations
WebSocket /ws/documents/{documentId}

7. Recommendations

ML

Recomendar productos, videos, canciones o documentos relevantes.

  • Problema central: candidates + ranking + feedback loop.
  • Solución: eventos de usuario, feature store, modelo offline+online, cache.
  • Cuidado: latencia (<100ms), sesgo, cold start, métricas A/B.
GET /api/recommendations?userId=&context=home
POST /api/events/impression
POST /api/events/click
POST /api/events/purchase

8. Link shortener

TinyURL/Bitly

URLs largas → links cortos, redirección de baja latencia.

  • Problema central: generar IDs cortos únicos, redirigir rápido.
  • Solución: base62 de counter (Spanner) o hash + colisión-check; cache; analytics async.
  • Cuidado: colisiones, links maliciosos, rate limits.
POST /api/links
GET /{shortCode} (301 redirect)
GET /api/links/{shortCode}/stats
DELETE /api/links/{shortCode}

9. File system (Drive)

Dropbox/GDrive

Carpetas, uploads, metadata, versionado, sharing.

  • Problema central: metadata tree + blobs grandes + permisos.
  • Solución: Spanner/Firestore metadata, Cloud Storage blobs, chunk upload, dedup por hash.
  • Cuidado: rename/move atómico, permisos heredados, dedup chunk-level.
POST /api/files:initiate-upload
POST /api/folders
GET /api/files/{fileId}
POST /api/files/{fileId}:share

10. DBMS / motor de BD

Difícil pero defendible

Sistema que recibe queries, indexa, transacciona.

  • Problema central: storage engine + indexes + query planner + transactions.
  • Solución: B+ trees/LSM, buffer pool, WAL, locks/MVCC, replication.
  • Cuidado: ACID, recuperación tras crash, isolation levels.
POST /api/query
POST /api/transactions
POST /api/transactions/{txId}:commit
POST /api/transactions/{txId}:rollback

8 Qué mencionar para verte fuerte

Estas palabras elevan tu respuesta si las conectas con el problema correcto.

Tema Cuándo lo mencionas Frase de entrevista
Cache Lecturas frecuentes, rankings, perfiles, feed, metadata. "Cachearía respuestas calientes con TTL para no servir datos eternamente viejos."
Queue / Pub/Sub Procesos pesados, emails, transcoding, analytics, indexing. "Lo haría asíncrono con Pub/Sub para desacoplar el request del procesamiento pesado."
CDN Videos, imágenes, audio, archivos públicos o estáticos. "El app server no debe servir blobs grandes; uso Cloud Storage + Cloud CDN."
Idempotency-Key Pagos, órdenes, creación de rides, retries del cliente. "Para evitar duplicados en retries, acepto un Idempotency-Key por request."
Rate limit APIs públicas, login, short links, feed, scraping. "Aplicaría rate limit por user/IP/key con token bucket en Redis para protección."
ETag / If-Match Docs, archivos, edición colaborativa, updates concurrentes. "Para evitar lost updates, uso ETag con If-Match — devuelve 412 si cambió."
Cursor pagination Feeds, búsquedas, listas grandes, historial. "Uso cursor pagination porque escala mejor que offset en datasets grandes."
Field masks Update parciales, GET con campos selectivos. "Usaría field mask ?fields=id,name al estilo Google APIs para reducir payload."
Observability Siempre. "Mediría latencia p50/p95/p99, error rate, saturación y throughput. SLO 99.9%."
gRPC / protobuf Microservicios internos, mobile, streaming. "Para servicio interno usaría gRPC sobre HTTP/2 — schema fuerte y mejor performance."
Circuit breaker Llamadas a servicios externos o críticos. "Aplico circuit breaker para evitar cascada de fallos cuando un upstream se degrade."
Backoff + jitter Cualquier retry — cliente o entre servicios. "Retry con exponential backoff y jitter para no causar thundering herd."

9 Scripts listos para usar

Aprénde estas frases de memoria. Te ahorran 30 segundos de tartamudeo.

🎬 Apertura: cualquier "diseña X"

"Voy a empezar identificando los recursos principales y las APIs por recurso. Después explico el flujo de escritura y lectura, dónde uso cache o colas, cómo manejo consistencia, seguridad, rate limits y observabilidad. Finalmente reviso tradeoffs y posibles bottlenecks."

🎯 Cierre fuerte (escala)

"El diseño funciona para escala moderada. Para 10× tráfico: separo ruta crítica de procesos asíncronos, agrego cache para lecturas calientes, particiono por userId o region, y mido p95/p99 para detectar bottlenecks. Plan B: read replicas y CDN edge caching."

Defender una decisión técnica

"Hay un trade-off entre [X] y [Y]. Yo elegiría [X] porque [razón concreta]. Si los requisitos cambian a [escenario], reconsideraría [Y]. Esto se monitorea con [métrica]."

🛡️ Cuando preguntan "¿y si falla?"

"Para failure de [componente]: timeout corto + retry con exponential backoff + circuit breaker. Si persiste, fallback a [degraded mode]. El cliente ve un error claro, no un cuelgue. Alertamos con SLO budget burn."

Pro tip Google: Cuando hables de APIs públicas, menciona que seguirías las Google API Improvement Proposals (AIP.dev): resource-oriented design, standard methods (List, Get, Create, Update, Delete, custom como :cancel), field masks para updates, error model estándar. Esto demuestra que conoces sus estándares internos.