Mejores prácticas para Architecture Decision Records (ADRs) - Archyl Blog

Pasamos dos semanas debatiendo una elección de base de datos que ya habíamos hecho y rechazado un año antes. Ahí fue cuando descubrí los ADRs, y nos han ahorrado incontables horas desde entonces.

Mejores prácticas para Architecture Decision Records (ADRs)

La reunión llevaba dos horas. Estábamos debatiendo si usar PostgreSQL o MongoDB para un nuevo servicio. Los argumentos volaban de un lado a otro — integridad relacional, esquemas flexibles, familiaridad del equipo, complejidad operacional.

Luego alguien mencionó: "¿No tuvimos exactamente esta discusión el año pasado para el servicio de usuarios?"

Silencio. La tuvimos. Un año atrás, habíamos pasado una cantidad similar de tiempo debatiendo la misma pregunta, eligiendo finalmente PostgreSQL. Pero nadie recordaba el razonamiento. El ingeniero que lideró esa discusión había dejado la empresa. Así que aquí estábamos, teniendo exactamente el mismo debate desde cero.

Ahí fue cuando descubrí los Architecture Decision Records (ADRs), y nos han ahorrado incontables horas de re-litigar debates ya resueltos.

¿Qué es un ADR?

Un ADR es un documento corto que captura una sola decisión arquitectural. No un documento de diseño cubriendo todo sobre un sistema, solo una decisión:

  • Qué decidimos
  • Por qué lo decidimos
  • Qué alternativas consideramos
  • Cuáles son las consecuencias

El formato es deliberadamente ligero. Un ADR debería caber en una página. Si es más largo, probablemente estás documentando más de una decisión.

La anatomía de un buen ADR

Después de escribir docenas de ADRs y leer cientos más, he encontrado que los mejores siguen una estructura consistente:

Título y número

Cada ADR recibe un número secuencial y un título conciso:

ADR-0042: Usar PostgreSQL para el Servicio de Órdenes

El número importa. Crea una línea de tiempo de decisiones y hace que los ADRs sean fáciles de referenciar en discusiones: "Como decidimos en ADR-42..."

Estado

Los ADRs tienen estados de ciclo de vida:

  • Propuesto: Todavía en discusión
  • Aceptado: Decisión tomada, estamos siguiendo esto
  • Deprecado: Ya no es relevante (un nuevo ADR lo reemplaza)
  • Rechazado: Lo consideramos pero decidimos en contra

El estado rechazado es particularmente valioso. A veces quieres capturar por qué no hiciste algo, para que futuros equipos no propongan lo mismo.

Contexto

Aquí es donde describes la situación que provocó la decisión. ¿Qué problema estamos resolviendo? ¿Qué restricciones tenemos? ¿Quién se ve afectado?

## Contexto

El servicio de órdenes necesita almacenamiento persistente para datos de
órdenes. Esperamos procesar 50,000 órdenes por día inicialmente, creciendo
a 500,000 en dos años. Las órdenes tienen una estructura bien definida pero
pueden necesitar campos de metadatos adicionales con el tiempo. El equipo
tiene experiencia con bases de datos relacionales y documentales.

Sé específico sobre las restricciones. "Necesitamos cumplimiento ACID" es mucho más útil que "necesitamos confiabilidad." Los futuros lectores necesitan entender las fuerzas que dieron forma a la decisión.

Decisión

Enuncia la decisión claramente. No "podríamos considerar" o "deberíamos explorar" — lo que realmente decidimos.

## Decisión

Usaremos PostgreSQL 15 como base de datos principal para el servicio de órdenes.

Elegimos PostgreSQL porque:

- El cumplimiento ACID es requerido para datos financieros de órdenes
- Las columnas JSON proporcionan flexibilidad de esquema para metadatos
- Nuestro equipo de infra tiene experiencia operacional con PostgreSQL
- Los patrones de consulta están bien adaptados al modelado relacional

Nota que esto no solo enuncia la decisión sino que explica brevemente el razonamiento. La siguiente sección entra en más detalle, pero incluso la sección de decisión debería ser auto-explicativa.

Alternativas consideradas

Esta es la sección más subestimada. Documentar lo que no elegiste es frecuentemente tan valioso como documentar lo que elegiste.

## Alternativas consideradas

### MongoDB

Pros:

- Almacenamiento JSON nativo
- Escalado horizontal más simple
- Evolución de esquema flexible

Contras:

- Garantías de consistencia más débiles
- Equipo menos familiar con operaciones
- Requeriría herramientas adicionales para transacciones

### DynamoDB

Pros:

- Totalmente gestionado, operaciones mínimas
- Excelentes características de escalabilidad

Contras:

- Lock-in de proveedor con AWS
- Patrones de consulta limitados a acceso partition/sort key
- Costo impredecible a gran escala

Cuando alguien nuevo se une al equipo y pregunta "¿por qué no usamos MongoDB?", tienes la respuesta. No necesitas programar una reunión o encontrar a la persona que tomó la decisión original.

Consecuencias

Cada decisión tiene trade-offs. Sé honesto sobre ellos.

## Consecuencias

### Positivas

- Fuertes garantías de integridad de datos
- El equipo puede aprovechar la experiencia existente en PostgreSQL
- Características operacionales bien entendidas

### Negativas

- Las migraciones de esquema requieren más planificación que document stores
- Escalado horizontal más complejo si excedemos capacidad single-node
- Necesidad de implementar sharding a nivel de aplicación si llegamos a límites

### Riesgos

- Puede necesitar revisión si el volumen de órdenes excede 1M/día
- Consultas de columnas JSON menos eficientes que document stores nativos

Esta sección es sobre honestidad intelectual. Ninguna decisión es perfecta. Reconocer las desventajas construye confianza y ayuda a futuros equipos a entender cuándo podrían necesitar revisar la decisión.

Cuándo escribir un ADR

No cada elección técnica necesita un ADR. Usa tu juicio, pero aquí hay algunas guías:

Escribe un ADR cuando...

  • La decisión afecta múltiples equipos o servicios
  • La decisión sería costosa de revertir
  • Estás eligiendo entre múltiples opciones viables
  • Futuros miembros del equipo podrían cuestionar la elección
  • La decisión resuelve un debate técnico significativo

No escribas un ADR cuando...

  • La elección es obvia y no está en disputa
  • La decisión solo afecta a una persona o un archivo
  • Es fácilmente reversible sin costo significativo
  • Es un patrón estándar que tu equipo siempre sigue

Por ejemplo: "¿Qué biblioteca JSON usar?" probablemente no necesita un ADR. "¿Usar GraphQL o REST para nuestra API pública?" definitivamente sí.

ADRs reales de nuestros proyectos

Aquí hay algunos ADRs reales que hemos escrito (simplificados para este post):

ADR-0007: Comunicación Event-Driven entre Servicios

Contexto: Nuestros microservicios actualmente se comunican sincrónicamente vía HTTP. Esto crea acoplamiento fuerte y fallas en cascada cuando los servicios no están disponibles.

Decisión: Adoptaremos una arquitectura event-driven usando Apache Kafka para comunicación asincrónica entre servicios.

Consecuencias:

  • Los servicios se vuelven más resilientes a fallas
  • Consistencia eventual en lugar de consistencia fuerte
  • Mayor complejidad operacional (gestión del cluster Kafka)
  • El equipo necesita capacitación en patrones de event sourcing

ADR-0015: Monorepo para Aplicaciones Frontend

Contexto: Tenemos 5 aplicaciones frontend en repositorios separados. Compartir código requiere publicar paquetes. La experiencia de desarrollador sufre por incompatibilidades de versiones.

Decisión: Consolidar todas las aplicaciones frontend en un solo monorepo usando Nx.

Alternativas rechazadas:

  • Mantener repos separados con mejor gestión de paquetes: Rechazado porque el overhead de coordinación permanece
  • Repo único sin Nx: Rechazado porque los tiempos de build serían prohibitivos

Consecuencias:

  • Compartir código y consistencia simplificados
  • Un solo PR puede actualizar código compartido y todos los consumidores
  • Repositorio más grande requiere mejores herramientas para cache de build
  • Potencial de acoplamiento no intencional entre aplicaciones

Errores comunes que he cometido

Error 1: Escribir ADRs después del hecho

El mejor momento para escribir un ADR es durante el proceso de decisión, no semanas después. Cuando escribes después, olvidas los matices, las alternativas que consideraste, y las restricciones específicas.

Ahora escribimos borradores de ADRs como parte del proceso de decisión. La discusión ocurre en el documento ADR, no en hilos de Slack que desaparecen.

Error 2: Hacerlos demasiado largos

Si tu ADR es más de una página, probablemente estás:

  • Documentando múltiples decisiones (sepáralos en múltiples ADRs)
  • Incluyendo detalles de implementación (guarda eso para docs de diseño)
  • Sobre-explicando contexto obvio

La disciplina de la brevedad fuerza claridad.

Error 3: No vincular ADRs relacionados

Las decisiones rara vez existen en aislamiento. Cuando elegimos Kafka para comunicación event-driven (ADR-0007), eso influyó nuestra elección de base de datos (ADR-0042) porque podíamos aceptar consistencia eventual.

Haz referencias cruzadas de ADRs relacionados:

## Decisiones relacionadas

- Ver ADR-0007 para por qué aceptamos consistencia eventual
- Reemplaza ADR-0003 que recomendaba MongoDB

Error 4: Abandonar la práctica

Los ADRs proporcionan valor con el tiempo. Uno o dos ADRs no ayudan mucho. Un corpus de 50+ ADRs, acumulados a lo largo de años, se vuelve increíblemente valioso. Es una historia buscable de tu evolución arquitectural.

La tentación es dejar de escribirlos cuando las cosas se ponen ocupadas. Resiste. Los diez minutos gastados escribiendo un ADR ahorrarán horas de reuniones después.

Haciendo ADRs parte de tu workflow

La parte más difícil no es escribir ADRs — es hacerlos un hábito. Esto es lo que funciona:

Almacénalos con el código

Pon los ADRs en tu repositorio, típicamente en docs/adr/ o docs/decisions/. De esta manera:

  • Se versionan con el código que describen
  • Aparecen en revisiones de código
  • No pueden quedar huérfanos en un wiki en algún lado

Usa un template

Crea un template markdown que todos usen. Esto reduce fricción y asegura consistencia:

# ADR-NNNN: Título

## Estado

Propuesto | Aceptado | Deprecado | Rechazado

## Contexto

[¿Cuál es el problema que estamos viendo que motiva esta decisión?]

## Decisión

[¿Cuál es el cambio que estamos proponiendo y/o haciendo?]

## Alternativas consideradas

[¿Qué otras opciones consideramos?]

## Consecuencias

[¿Qué se vuelve más fácil o más difícil por este cambio?]

Revisa ADRs trimestralmente

Pon un recordatorio de calendario para revisar tus ADRs cada trimestre:

  • ¿Hay decisiones que ya no son relevantes?
  • ¿Han cambiado las circunstancias que invalidan nuestras suposiciones?
  • ¿Hay decisiones no documentadas que deberíamos capturar?

Vincula ADRs a diagramas de arquitectura

Aquí es donde herramientas como Archyl brillan. Cuando vinculas un ADR a un componente específico en tu diagrama C4, cualquiera que mire ese componente puede instantáneamente ver las decisiones que lo moldearon.

"¿Por qué este servicio habla con Kafka en lugar de directamente a la base de datos?" Haz clic en el ADR vinculado y descúbrelo.

Conclusión

Los Architecture Decision Records son una de esas prácticas que parecen overhead hasta que los necesitas. Entonces son invaluables.

¿Esa reunión de dos horas sobre PostgreSQL vs MongoDB? La terminamos en diez minutos una vez que alguien encontró el ADR original. Todo el contexto estaba ahí — las restricciones, las alternativas, el razonamiento. Rápidamente confirmamos que la decisión original aún aplicaba y seguimos adelante.

Empieza pequeño. La próxima vez que tomes una decisión arquitectural, toma quince minutos para escribir un ADR. Ponlo en tu repositorio. En seis meses, cuando alguien pregunte "¿por qué lo hicimos de esa manera?", tendrás la respuesta.


Aprende más sobre documentación de arquitectura: Introducción al modelo C4 | Por qué la documentación importa | Documentando flujos de usuario