Talently
Talently
Arquitecto de Software

Arquitecto de Software

Define las estructuras técnicas que permiten a los sistemas escalar, evolucionar y sobrevivir al tiempo con el menor costo posible.

Un Arquitecto de Software es responsable de tomar y comunicar las decisiones técnicas de alto impacto que definen la estructura de los sistemas de software: qué componentes los componen, cómo se comunican, qué tecnologías los sustentan y cómo evolucionarán con el tiempo. Su trabajo trasciende el código individual: define las restricciones y los patrones dentro de los cuales los equipos de desarrollo toman sus decisiones diarias. Colabora con líderes técnicos, CTO, product managers y stakeholders de negocio para alinear las decisiones arquitectónicas con los objetivos, restricciones y riesgos del negocio.

MicroserviciosDomain-Driven DesignCloud ArchitecturePatrones de diseñoAPI DesignSeguridad

Recluta al mejor Arquitecto de Software aquí

Empieza ahora

Responsabilidades Principales

  • Definir y documentar la arquitectura de sistemas nuevos y la evolución de sistemas existentes con Architecture Decision Records y diagramas C4.
  • Identificar y gestionar los riesgos técnicos de alto impacto: puntos de fallo único, deuda técnica crítica y decisiones irreversibles.
  • Establecer los principios, patrones y estándares técnicos que guían las decisiones de implementación de los equipos de desarrollo.
  • Evaluar y recomendar tecnologías, frameworks y plataformas con criterio técnico y de negocio, no por novedad.
  • Colaborar con los líderes técnicos de cada equipo para garantizar que la implementación es coherente con la arquitectura definida.
  • Participar en la planificación técnica de iniciativas de producto evaluando el impacto arquitectónico de nuevos requerimientos.

Habilidades Clave

Technical Skills

  • Diseño de arquitecturas distribuidas: microservicios, event-driven architecture, CQRS, Event Sourcing y sus trade-offs reales
  • Domain-Driven Design para identificar bounded contexts, definir el lenguaje ubicuo y estructurar equipos alrededor de dominios de negocio
  • Diseño de APIs y contratos de integración: REST, GraphQL, gRPC y estrategias de versionado y evolución
  • Arquitecturas cloud-native en AWS, GCP o Azure con conocimiento de servicios de cómputo, red, mensajería y almacenamiento
  • Seguridad por diseño: modelado de amenazas, principio de mínimo privilegio, zero trust y cifrado en todas las capas
  • Patrones de resiliencia: circuit breakers, bulkheads, retry con backoff, saga pattern y estrategias de degradación elegante

Soft Skills

  • Capacidad de comunicar decisiones técnicas complejas con distintos niveles de abstracción según la audiencia: CTO, desarrolladores o stakeholders de negocio
  • Influencia sin autoridad directa: lograr que los equipos adopten las decisiones arquitectónicas por convicción y no por imposición
  • Pensamiento sistémico para anticipar cómo una decisión local impacta el sistema global a corto, mediano y largo plazo
  • Humildad técnica para reconocer cuando una decisión arquitectónica anterior fue incorrecta y proponer su evolución con datos
  • Criterio para distinguir entre problemas que requieren decisiones arquitectónicas y problemas que los equipos deben resolver de forma autónoma
  • Gestión de la ambigüedad: tomar decisiones técnicas fundadas cuando los requerimientos aún no están completamente definidos

Casos de uso reales

Contexto

Las decisiones tomadas en las primeras semanas de un sistema definen los costos y limitaciones de los próximos años. Una arquitectura inicial bien pensada no elimina el cambio, pero lo hace menos costoso.

Ejemplos reales

  • Definición de bounded contexts y sus interfaces usando Domain-Driven Design
  • Evaluación de opciones arquitectónicas con Architecture Decision Records documentando el razonamiento
  • Diseño de la estrategia de datos: qué datos son propiedad de qué servicio y cómo fluyen
  • Definición de los contratos de integración entre servicios antes de que los equipos comiencen a implementar

Contexto

La mayoría de los arquitectos trabajan sobre sistemas existentes, no sobre hojas en blanco. La modernización incremental es más valiosa y menos riesgosa que la reescritura completa.

Ejemplos reales

  • Aplicación del patrón strangler fig para extraer módulos del monolito sin interrumpir el negocio
  • Identificación y priorización de la deuda técnica con mayor impacto en la velocidad de desarrollo
  • Migración incremental de una arquitectura monolítica a servicios con boundaries bien definidos
  • Diseño de una capa anti-corruption para integrar el sistema legacy con nuevos servicios sin acoplar los dominios

Contexto

En organizaciones con varios equipos de desarrollo, los estándares arquitectónicos garantizan coherencia, reducen la fricción de colaboración y evitan la proliferación de soluciones incompatibles.

Ejemplos reales

  • Definición de golden paths: conjuntos de herramientas y patrones recomendados para casos de uso comunes
  • Guías de diseño de APIs con estándares de nomenclatura, paginación, manejo de errores y versionado
  • Proceso de Architecture Decision Records para documentar y comunicar decisiones técnicas transversales
  • Revisiones de arquitectura para nuevos proyectos antes de que comiencen a implementarse

Contexto

Los sistemas distribuidos fallan de formas complejas y no siempre predecibles. El arquitecto debe identificar los riesgos antes de que se materialicen y diseñar mecanismos de mitigación.

Ejemplos reales

  • Mapeo de puntos de fallo único y diseño de estrategias de redundancia y failover
  • Ejercicios de chaos engineering para validar que los mecanismos de resiliencia funcionan como se espera
  • Definición de SLOs por servicio y diseño de la arquitectura para cumplirlos con el presupuesto de errores disponible
  • Threat modeling para identificar superficies de ataque y diseñar controles preventivos

Contexto

Cada nueva tecnología que entra al stack es una deuda de conocimiento, operación y mantenimiento. La evaluación rigurosa previene la proliferación de herramientas sin criterio.

Ejemplos reales

  • Technology radar interno que clasifica tecnologías en adoptar, evaluar, mantener y evitar
  • Spikes técnicos con criterios de evaluación predefinidos antes de adoptar una tecnología en producción
  • Evaluación del total cost of ownership: no solo el costo de adopción sino el de operación y migración futura
  • Proceso de RFC para propuestas de adopción de nuevas tecnologías que involucre a los equipos afectados

Preguntas básicas

Comenzar con un monolito bien estructurado en la mayoría de los casos: menor complejidad operacional, más fácil de refactorizar cuando los bounded contexts no están claros, y suficiente para la mayoría de los productos en etapas tempranas. Migrar a microservicios cuando el monolito tiene problemas reales y medibles: equipos que se bloquean mutuamente, necesidades de escala independiente por módulo, o tecnologías incompatibles por dominio. La complejidad de los microservicios debe justificarse con problemas concretos, no con aspiraciones de escala futura.
Un ADR documenta el contexto del problema, las opciones consideradas con sus pros y contras, la decisión tomada y las consecuencias anticipadas. Es más valioso que solo la decisión porque: permite entender por qué se descartaron las alternativas (evitando reevaluar las mismas opciones en el futuro), comunica las restricciones que existían en ese momento, y permite revisitar la decisión cuando el contexto cambia. Un ADR es una herramienta de comunicación tanto como de documentación.
Requiere decisión arquitectónica cuando: la decisión es difícil de revertir, afecta a múltiples equipos o sistemas, tiene implicaciones de seguridad, compliance o costo a escala, o establece un patrón que otros equipos seguirán. Los equipos resuelven de forma autónoma cuando: la decisión está dentro de los límites de un solo servicio, es técnicamente reversible, y no afecta los contratos con otros sistemas. Un arquitecto que toma todas las decisiones técnicas se convierte en un cuello de botella; uno que no toma ninguna deja a los equipos sin coherencia.
Alta cohesión: cada servicio o módulo contiene lógica que cambia junta y por las mismas razones (mismo dominio de negocio). Bajo acoplamiento: los servicios dependen de interfaces estables, no de detalles de implementación de otros servicios. En la práctica: un servicio de pagos no debe conocer la estructura interna del servicio de usuarios; se comunica a través de un contrato de API o eventos. El acoplamiento alto genera que un cambio en un servicio requiera cambios coordinados en otros, la principal causa de lentitud en arquitecturas distribuidas.
Definir criterios de evaluación antes de evaluar: madurez y estabilidad, comunidad y soporte a largo plazo, integración con el stack existente, costo de operación y de migración futura, curva de aprendizaje del equipo. Ejecutar un spike técnico acotado con un caso de uso real del producto, no un hello world. Evaluar no solo si resuelve el problema actual sino si crea problemas nuevos. La adopción debe justificarse con evidencia de que resuelve mejor el problema que las alternativas ya en el stack.
Modelado de amenazas al inicio para identificar las superficies de ataque más relevantes. Principio de mínimo privilegio en todos los niveles: servicios, bases de datos, usuarios. Cifrado en tránsito y en reposo para datos sensibles. Autenticación y autorización como capas transversales, no como responsabilidad de cada servicio individual. Segmentación de red para que los servicios solo puedan comunicarse con los que necesitan. La seguridad por diseño es exponencialmente más barata que la seguridad añadida después.
Conectar la decisión con un riesgo o costo de negocio concreto que evita: no como 'es la mejor práctica' sino como 'sin este cambio, en seis meses tendremos este problema medible'. Mostrar el costo de no hacerlo con datos o analogías del propio sistema. Involucrar al equipo en el diseño de la solución para que sea parte de la decisión, no solo receptor. Proponer una implementación incremental que distribuye el trabajo adicional en el tiempo sin bloquear la entrega de valor.
Un bounded context es un límite explícito dentro del cual un modelo de dominio específico es válido y consistente. El mismo concepto puede tener significados distintos en diferentes bounded contexts: 'cliente' en el contexto de ventas tiene atributos distintos que en el contexto de soporte. Los límites del servicio deben coincidir con los del bounded context para que cada servicio tenga un modelo de dominio coherente y no dependa de los detalles del modelo de otro. Cuando dos servicios comparten el mismo modelo, hay acoplamiento de dominio que complica la evolución independiente.

Preguntas técnicas

Microservicios ganan en: despliegue independiente por servicio, escalado granular, aislamiento de fallos, y posibilidad de tecnologías distintas por dominio. Pierden en: complejidad operacional (N servicios que monitorear, desplegar y operar), latencia de red en comunicaciones entre servicios, consistencia de datos distribuida (sin transacciones ACID entre servicios), y observabilidad distribuida más compleja. Un monolito modular bien estructurado captura muchos de los beneficios de diseño de los microservicios sin la complejidad operacional. El trade-off más subestimado es el costo humano: los microservicios requieren madurez de DevOps que muchos equipos no tienen.
Sin transacciones distribuidas (two-phase commit es frágil y genera acoplamiento). El patrón saga gestiona la consistencia eventual: cada servicio ejecuta su transacción local y emite un evento; el siguiente servicio reacciona al evento. Si un paso falla, se ejecutan transacciones compensatorias para deshacer los pasos anteriores. Saga con orquestación tiene un coordinador central que controla el flujo; con coreografía, cada servicio reacciona a los eventos de los demás. La orquestación es más fácil de monitorear y debuggear; la coreografía tiene menos acoplamiento pero más complejidad de trazabilidad.
CQRS separa el modelo de escritura (commands que modifican estado) del modelo de lectura (queries que consultan estado), con modelos de datos optimizados para cada caso. Justificado cuando: el modelo óptimo para escrituras (normalizado, con validaciones de negocio) es incompatible con el modelo óptimo para lecturas (desnormalizado, pre-agregado). Introduce complejidad: dos modelos de datos que mantener en sincronía, consistencia eventual entre escritura y lectura, y mayor superficie de código. No adoptar por defecto: la mayoría de los sistemas CRUD no se benefician de CQRS y cargan con su complejidad innecesariamente.
Principio base: nunca introducir breaking changes en una versión existente. Breaking changes son: eliminar campos, cambiar tipos, cambiar semántica de campos existentes, o eliminar endpoints. Non-breaking: añadir campos opcionales, añadir endpoints nuevos. Cuando se necesita un breaking change: crear una nueva versión (/v2/) y mantener la versión anterior con un período de deprecación comunicado. Usar consumer-driven contract testing (Pact) para saber exactamente qué consumidores usan qué parte del contrato antes de eliminar algo.
El circuit breaker tiene tres estados: cerrado (tráfico normal), abierto (el servicio falla, se corta el tráfico y se devuelve una respuesta de fallback inmediatamente), y half-open (se deja pasar una fracción del tráfico para verificar si el servicio se recuperó). Configuración requiere tres decisiones: el umbral de fallos para abrir el circuito (por ejemplo, 50% de errores en los últimos 10 segundos), el tiempo que permanece abierto antes de intentar half-open, y el comportamiento del fallback (respuesta cacheada, respuesta por defecto, o error explícito). Resilience4j para JVM y Polly para .NET son implementaciones maduras. Los valores deben calibrarse con el comportamiento real del servicio en producción.
Cada servicio debe autenticarse ante los servicios que consume, no solo los usuarios finales ante el sistema. Mutual TLS (mTLS) entre servicios para verificar identidad en ambas direcciones. Service mesh como Istio o Linkerd gestiona mTLS transparentemente sin modificar el código de la aplicación. Autorización granular: el servicio A puede leer del servicio B pero no escribir. Logs de auditoría de todas las comunicaciones entre servicios. En cloud: IAM roles para servicios en lugar de credenciales estáticas. Zero trust incrementa la superficie de configuración; un error en las políticas puede generar outages, por lo que el rollout debe ser incremental.
Event-driven es adecuado cuando: múltiples consumidores necesitan reaccionar al mismo evento sin que el productor los conozca, se necesita desacoplamiento temporal (el productor no espera a que los consumidores procesen), o el audit trail de eventos tiene valor de negocio propio. No es adecuado cuando: se necesita una respuesta síncrona inmediata (request-response directo es más simple), la cantidad de eventos es baja y la complejidad del broker no se justifica, o cuando el equipo no tiene experiencia operando sistemas de mensajería. El mayor costo oculto es la observabilidad: trazar un flujo de negocio a través de múltiples consumidores asíncronos es significativamente más complejo que en un sistema síncrono.
Los tres pilares son necesarios pero no suficientes por separado: logs estructurados con correlation ID que atraviesa todos los servicios, métricas con percentiles (p95, p99) de latencia y error rate por servicio y endpoint, y trazas distribuidas con OpenTelemetry que muestran el camino completo de un request. Para el diagnóstico en 15 minutos: las métricas muestran que hay un problema y en qué servicio, las trazas muestran en qué operación específica falla, y los logs dan el contexto detallado del error. Sin los tres, el diagnóstico es iterativo y lento. El correlation ID es el hilo conductor que conecta los tres.

Preguntas avanzadas

A esa escala, cada decisión de arquitectura tiene impacto medible en el SLA. Eliminar latencia en cada capa: caching agresivo en memoria para evitar I/O, procesamiento asíncrono para operaciones no críticas en el path de respuesta, particionamiento de datos para distribuir la carga de escritura. Diseñar para escala horizontal: sin estado en las instancias de la aplicación, coordinación mínima entre nodos. El p99 de 50ms requiere que el p99 de cada componente en el camino sea una fracción de ese total. Perfilar el sistema bajo carga real antes de optimizar: las suposiciones sobre el bottleneck frecuentemente son incorrectas sin datos.
Hacer la deuda visible con métricas de impacto concreto: tiempo de desarrollo de features ralentizado por la deuda, número de incidentes relacionados con componentes de deuda alta, costo de operación de sistemas legacy. Proponer un modelo de presupuesto de deuda técnica: un porcentaje fijo del capacity de ingeniería (20% es un punto de partida común) dedicado a reducción de deuda en cada sprint, sin negociación por feature. El argumento más efectivo no es técnico sino económico: cuánto más lenta es la entrega de features por la deuda acumulada. La deuda arquitectónica ignorada tiene intereses compuestos que eventualmente paralizan la organización.
Separar las decisiones por nivel de impacto: las de bajo impacto (dentro de un servicio, reversibles) las toman los equipos de forma autónoma dentro de los guardrails establecidos. Las de impacto medio (nuevo servicio, nueva tecnología) pasan por una lightweight review con un ADR. Las de alto impacto (cambio de plataforma, nuevo estilo arquitectónico, decisiones irreversibles) pasan por un Architecture Review Board. Publicar los ADRs y los estándares para que los equipos puedan tomar decisiones autónomas informadas. El arquitecto como consultor y reviewer, no como aprobador de todo.
La migración de datos es el paso más arriesgado de la descomposición de un monolito. Estrategia: primero identificar qué tablas pertenecen a qué dominio (algunas serán compartidas, el punto de mayor fricción). Para las tablas claramente de un dominio: crear el nuevo servicio leyendo de la BD del monolito via una capa de acceso controlada, luego migrar los datos a la BD propia del servicio, luego cortar la dependencia. Para las tablas compartidas entre dominios: definir cuál es el dominio dueño, crear APIs de acceso para los otros dominios, y eventualmente replicar solo los datos necesarios. La sincronización dual escritura durante la transición aumenta la complejidad pero es esencial para un rollback seguro.
DDD a escala requiere prerequisitos que van más allá de lo técnico. Organizacional: los equipos deben alinearse con bounded contexts de negocio, no con capas técnicas. Los expertos de dominio deben participar activamente en el diseño del modelo, no solo como validadores al final. El negocio debe comprometerse con el lenguaje ubicuo: si el código usa términos distintos a los del negocio, DDD no se está aplicando. Técnico: los equipos deben tener experiencia con las tácticas de DDD (aggregates, value objects, domain events) antes de aplicar los patrones estratégicos. El mayor riesgo es aplicar DDD como un ejercicio técnico sin el compromiso organizacional que requiere.
Identity provider centralizado (Okta, Auth0, Keycloak o propio) como fuente de verdad de identidad con soporte de OIDC/OAuth2 para SSO entre productos. Los tokens emitidos incluyen claims básicos de identidad; la autorización granular (qué puede hacer el usuario en cada producto) se evalúa localmente en cada servicio usando los claims del token más el contexto del recurso. Esto evita que el IDP se convierta en un cuello de botella con lógica de negocio de cada producto. Para equipos independientes: definir el contrato de claims mínimo que todos los productos consumen, y dejar que cada producto extienda con claims propios. El proceso de onboarding de nuevos productos al SSO debe ser self-service con documentación clara.

Errores comunes en entrevistas

Los microservicios resuelven problemas reales a escala pero introducen complejidad operacional, de datos distribuidos y de observabilidad que muchos equipos no están preparados para gestionar. Un arquitecto que propone microservicios sin evaluar el tamaño del equipo, la madurez de DevOps y la complejidad del dominio demuestra pensamiento de moda tecnológica, no de criterio arquitectónico.
Toda decisión arquitectónica implica compromisos. Un arquitecto que describe sus decisiones pasadas como obviamente correctas sin mencionar qué se sacrificó, qué alternativas se descartaron y por qué, no demuestra el pensamiento crítico que el rol requiere. Los entrevistadores sénior siempre preguntan qué harías diferente hoy.
La ley de Conway establece que los sistemas tienden a reflejar la estructura de comunicación de la organización que los construye. Un arquitecto que diseña sin considerar cómo están organizados los equipos producirá una arquitectura que el equipo no puede implementar de forma natural. La arquitectura y la organización del equipo deben diseñarse juntas.
Un diagrama sin el razonamiento detrás es decoración. Los entrevistadores de nivel arquitecto preguntan por qué cada elemento del diagrama está ahí, qué alternativas se consideraron y cuáles son los riesgos conocidos. Un arquitecto que solo puede dibujar cajas y flechas sin articular las decisiones que las justifican no está cumpliendo la función más valiosa del rol.
Una arquitectura hermosa en papel que es imposible de operar en producción no tiene valor. El costo de operar la arquitectura (monitoreo, deployment, recovery) debe ser parte del diseño desde el inicio. Un arquitecto que no pregunta cómo se operará el sistema antes de diseñarlo está transfiriendo deuda operacional al equipo de infraestructura.
Event sourcing, CQRS, sagas distribuidas y otros patrones avanzados resuelven problemas específicos a escala. Aplicarlos a sistemas que no tienen esos problemas añade complejidad sin beneficio. Un arquitecto maduro puede articular exactamente qué problema específico del sistema justifica la adopción de cada patrón complejo, y cuál es el sistema más simple que también resolvería el problema.