ADRs para proyectos pequeños: cómo documentar decisiones técnicas sin burocracia
Guía práctica para usar Architecture Decision Records en proyectos personales o equipos pequeños sin caer en documentación pesada.

Hace unos meses abrí un proyecto personal que llevaba un año sin tocar. Kotlin con Spring Boot, una API para gestión de feeds RSS. Me encontré con una decisión que no entendía: por qué usaba Redis como caché de feeds en vez de la caché en memoria de Spring. El código funcionaba, los tests pasaban, pero no tenía ni idea de por qué había elegido Redis para un proyecto que corre en una sola instancia.
Tardé una hora en reconstruir el razonamiento. Revisé commits, mensajes de commit, incluso un hilo viejo de Slack conmigo mismo. Al final encontré el motivo: necesitaba persistir la caché entre reinicios para no re-fetchear todos los feeds al arrancar. Tenía sentido. Pero una hora de arqueología para una decisión que habría ocupado 10 líneas de documentación.
Desde entonces uso ADRs. No la versión enterprise de 3 páginas con comité de aprobación. Una versión ligera que funciona para proyectos personales y equipos pequeños. Escribirlo tarda 5 minutos. No escribirlo cuesta horas de confusión futura.
Qué es un ADR (sin complicarlo)
Un Architecture Decision Record es exactamente lo que dice el nombre: un registro de una decisión de arquitectura. Ni más ni menos.
No es un documento de diseño. No es una spec. No es una justificación corporativa. Es una nota breve que responde a cuatro preguntas:
- Qué decisión se tomó.
- En qué contexto se tomó.
- Qué alternativas se consideraron.
- Qué consecuencias tiene.
Si las specs definen qué se va a construir, los ADRs explican por qué se decidió construirlo de una manera concreta y no de otra.
La relación con SDD es complementaria. La spec dice “el sistema de notificaciones envía emails de forma asíncrona”. El ADR explica “elegimos un sistema de eventos con Spring Events en vez de una cola de mensajes externa porque el volumen previsto no justifica la complejidad operacional de mantener un RabbitMQ”.
Plantilla ADR sencilla
Esta es la plantilla que uso. Intencionalmente mínima:
# ADR-001: [Título de la decisión]
**Estado**: Aceptado | Superseded by ADR-XXX | Deprecated
**Fecha**: YYYY-MM-DD
**Autor**: [nombre]
## Contexto
[Qué problema o situación motivó esta decisión. 2-4 frases.]
## Decisión
[Qué se decidió hacer. Claro y concreto. 1-3 frases.]
## Alternativas consideradas
### [Alternativa A]
- Ventajas: ...
- Desventajas: ...
### [Alternativa B]
- Ventajas: ...
- Desventajas: ...
## Consecuencias
[Qué implica esta decisión. Positivo y negativo. Qué ganas, qué pierdes,
qué deuda técnica asumes.]Son cinco secciones. Ninguna debería superar un párrafo excepto las alternativas. Si necesitas más de una página para explicar un ADR, probablemente estás documentando un diseño, no una decisión.
Ejemplo real: por qué Kotlin en vez de Java para un microservicio
Voy a rellenar la plantilla con un ejemplo real de una decisión que tomamos en un proyecto:
# ADR-003: Usar Kotlin en vez de Java para el servicio de notificaciones
**Estado**: Aceptado
**Fecha**: 2026-03-15
**Autor**: Roger
## Contexto
Estamos creando un nuevo microservicio de notificaciones que se integrará con
el sistema de pedidos existente (Java/Spring Boot). El equipo tiene experiencia
en ambos lenguajes. El servicio será relativamente pequeño (~15 endpoints,
lógica de eventos y plantillas de email) y lo mantendrán 2-3 personas.
## Decisión
Escribir el servicio de notificaciones en Kotlin con Spring Boot 3.x.
El servicio de pedidos existente se mantiene en Java.
## Alternativas consideradas
### Java 21 con Spring Boot 3.x
- Ventajas: consistencia con el servicio de pedidos, menos curva de aprendizaje
para el equipo, más candidatos si contratamos.
- Desventajas: más boilerplate para DTOs y data classes, null safety manual
(Optional o anotaciones), corrutinas no nativas.
### Kotlin con Spring Boot 3.x
- Ventajas: data classes reducen boilerplate en DTOs y eventos, null safety
nativo (importante porque manejamos datos de usuario que pueden venir
incompletos), corrutinas para llamadas asíncronas al proveedor de email,
extension functions para mappers limpios.
- Desventajas: un miembro del equipo tiene menos experiencia con Kotlin,
alguna incompatibilidad menor con librerías Java puras.
### Kotlin con Ktor
- Ventajas: stack 100% Kotlin, más ligero que Spring.
- Desventajas: ecosistema más pequeño, menos tooling, el equipo no tiene
experiencia con Ktor, integración con el resto de infra (Spring Cloud
Config, Actuator) requeriría trabajo extra.
## Consecuencias
- El equipo necesita mantener dos lenguajes (Java en pedidos, Kotlin en
notificaciones). Aceptamos esa complejidad porque el beneficio en
productividad de Kotlin para este servicio específico lo compensa.
- El miembro del equipo con menos experiencia en Kotlin tendrá pair
programming durante las primeras 2 semanas.
- Los módulos compartidos (eventos, DTOs comunes) se escriben en Kotlin
pero son interoperables con Java.
- Si en el futuro migramos el servicio de pedidos a Kotlin, la experiencia
ganada aquí será útil.Esto se escribió en 10 minutos. Seis meses después, cuando alguien nuevo pregunte “por qué este servicio está en Kotlin y el otro en Java”, la respuesta está documentada. No hay que reconstruir el razonamiento desde cero.
Cuándo escribir un ADR (y cuándo no hace falta)
No toda decisión técnica necesita un ADR. Si documentaras cada if arquitectónico, pasarías más tiempo escribiendo ADRs que código. La clave está en identificar las decisiones que cumplen al menos una de estas condiciones:
Sí necesita ADR
- Es difícil de revertir. Elegir la base de datos, el lenguaje, el framework, la estructura de módulos. Cambiar esto después cuesta semanas o meses.
- Tuvo alternativas razonables. Si había varias opciones válidas y elegiste una por motivos específicos, esos motivos deberían quedar documentados.
- Alguien te va a preguntar por qué. Si puedes anticipar que un futuro miembro del equipo (o tu yo de dentro de un año) va a mirar ese código y pensar “por qué se hizo así”, eso es señal de que necesita un ADR.
- Tiene implicaciones a largo plazo. Decisiones que afectan a rendimiento, escalabilidad, costes operacionales, seguridad o mantenibilidad futura.
No necesita ADR
- Es una convención estándar. “Usamos REST para la API” no necesita ADR si todo tu stack es REST. Es el default.
- Es trivialmente reversible. Elegir entre dos librerías de logging que hacen lo mismo y se cambian en 5 minutos no merece un ADR.
- No tuvo alternativas. Si un requisito técnico te obliga a usar una tecnología concreta, no hay decisión que documentar. Puedes mencionarlo en la spec.
- Ya está explicado en la spec. Si la spec dice explícitamente “usaremos eventos para comunicación asíncrona” y explica por qué, no necesitas un ADR que repita lo mismo.
En la duda, pregúntate: si yo me fuera del proyecto mañana y alguien nuevo tomara el relevo, le resultaría confusa esta decisión. Si la respuesta es sí, escribe el ADR.
Dónde guardar los ADRs
En el repositorio. Punto. Igual que las skills, los ADRs viven junto al código que describen.
proyecto/
├── docs/
│ └── adr/
│ ├── 001-usar-postgresql-en-vez-de-mongodb.md
│ ├── 002-estructura-por-features-no-por-capas.md
│ ├── 003-kotlin-en-vez-de-java-servicio-notificaciones.md
│ ├── 004-redis-para-cache-de-feeds.md
│ └── template.md
├── src/
└── ...La convención de nombrado NNN-titulo-descriptivo.md es simple y funciona. El número da orden cronológico. El título es descriptivo para que puedas encontrar el ADR relevante sin abrir cada archivo.
Ventajas de tenerlos en el repo:
- Se versionan con git. Puedes ver la evolución de las decisiones.
- Pasan por PR. Un ADR nuevo se revisa como cualquier otro cambio.
- Son buscables con grep/search. No necesitas una herramienta especial.
- Cualquier persona que clone el repo tiene acceso inmediato.
- Están junto al código que afectan, no en un wiki que nadie visita.
Para proyectos con múltiples repos, cada repo tiene sus ADRs específicos. Si hay decisiones que afectan a toda la plataforma, pueden vivir en un repo de documentación central, pero eso ya es para equipos más grandes.
ADRs y agentes de IA: más útiles de lo que parece
Aquí es donde los ADRs encajan con el flujo de trabajo con IA que vengo describiendo en artículos anteriores.
Un agente de IA que trabaja con tu código necesita contexto. Las skills le dicen cómo escribir código. Las specs le dicen qué construir. Y los ADRs le dicen por qué las cosas son como son.
Esto es particularmente útil cuando el agente necesita tomar una decisión o cuando un desarrollador le pide una recomendación. Sin ADRs, el agente propone lo que considere mejor según su entrenamiento general. Con ADRs, puede considerar el contexto específico de tu proyecto.
Ejemplo de prompt que aprovecha ADRs:
Contexto del proyecto:
- Skills: backend-conventions.md
- ADRs relevantes:
- ADR-003: Usamos Kotlin en vez de Java para servicios nuevos
- ADR-004: Redis como caché para datos que necesitan persistir entre reinicios
- ADR-007: Spring Events para comunicación entre módulos del mismo servicio
Tarea: Necesito añadir un sistema de caché para las respuestas del LLM en el
servicio de resúmenes. Las respuestas no cambian frecuentemente y son costosas
de generar. Propón una implementación que sea consistente con las decisiones
arquitectónicas existentes.Con los ADRs como contexto, el agente va a proponer Redis (consistente con ADR-004) en vez de inventar su propia solución. Va a usar Kotlin (consistente con ADR-003). Y si la comunicación es interna al servicio, va a usar Spring Events (consistente con ADR-007).
Los ADRs convierten al agente de un programador genérico a un programador que conoce el contexto y las decisiones de tu proyecto.
ADR para decisiones que ya tomaste
Un error común es pensar que los ADRs solo sirven para decisiones futuras. En realidad, el mayor valor inmediato está en documentar las decisiones que ya tomaste y que hoy no tienen explicación.
Si abres tu proyecto y hay cinco cosas que “funcionan así pero nadie sabe bien por qué”, esos son tus primeros cinco ADRs. No hace falta que sean perfectos. Es mejor tener un ADR aproximado que no tener nada.
Mi proceso para documentar decisiones retroactivas:
- Identifica la decisión. Algo en el código que no es obvio. “Por qué usamos Redis aquí”, “por qué este módulo está separado”, “por qué hay un cron en vez de un trigger”.
- Reconstruye el contexto. Revisa commits, PRs, mensajes de Slack, tu memoria. No hace falta que sea perfecto.
- Escribe el ADR con lo que sepas. Si no recuerdas las alternativas que consideraste, escribe las que habrías considerado. Si no recuerdas exactamente por qué, escribe tu mejor hipótesis y marca con un nota tipo “[reconstruido, puede no ser exacto]”.
- Marca el estado. Si la decisión sigue vigente, “Aceptado”. Si ya no tiene sentido pero se mantiene por inercia, “Deprecated” o “En revisión”.
# ADR-004: Redis como caché de feeds RSS
**Estado**: Aceptado
**Fecha**: 2025-04-XX (aproximada, reconstruido retrospectivamente)
**Autor**: Roger
## Contexto
[Reconstruido] El servicio de feeds RSS re-fetches todos los feeds al
reiniciarse. Con ~200 feeds y un rate limit de los proveedores, un reinicio
completo tardaba 15-20 minutos. Necesitaba una caché que persistiera entre
reinicios.
## Decisión
Usar Redis como caché de feeds parsados. TTL de 1 hora por feed.
## Alternativas consideradas
### Caché en memoria (Spring Cache + ConcurrentHashMap)
- Ventajas: cero infraestructura adicional.
- Desventajas: se pierde al reiniciar. Reinicio = re-fetch masivo.
### SQLite/H2 como caché en disco
- Ventajas: persiste sin servicio externo.
- Desventajas: más complejo de implementar, no pensado para TTL nativo.
### Redis
- Ventajas: TTL nativo, persiste entre reinicios, operaciones atómicas, bajo
overhead.
- Desventajas: un servicio más que mantener (Redis).
## Consecuencias
- Redis añade un componente de infraestructura al deploy (docker-compose).
- El servicio arranca en segundos en vez de minutos.
- Si Redis no está disponible, el servicio funciona pero sin caché
(degrada a re-fetch).Cinco minutos de escritura que ahorran una hora de arqueología.
Flujo completo: specs, ADRs y skills juntos
El ecosistema de documentación de un proyecto con SDD se compone de tres piezas que se complementan:
| Documento | Responde a | Ejemplo |
|---|---|---|
| Spec | Qué construir y con qué criterios | ”Sistema de notificaciones por email con reintentos y preferencias de usuario” |
| ADR | Por qué se construye de esta forma | ”Elegimos Kotlin por null safety y corrutinas para este servicio” |
| Skill | Cómo se construye en este equipo | ”Usamos inyección por constructor, tests con MockK, estructura por feature” |
Ninguno sustituye a los otros. Los tres juntos dan a un desarrollador (o a un agente de IA) todo el contexto que necesita para contribuir al proyecto de forma alineada con las decisiones y convenciones del equipo.
Errores comunes con ADRs
ADRs que son documentos de diseño
Si tu ADR tiene diagramas de secuencia, pseudocódigo detallado y secciones de 500 palabras, no es un ADR. Es un documento de diseño disfrazado. El ADR solo captura la decisión y su razonamiento. El diseño detallado va en la spec o en documentación técnica aparte.
ADRs que no mencionan alternativas
Si solo escribes lo que decidiste pero no qué alternativas había, pierdes la parte más valiosa. El contexto de “por qué no X” es a menudo más útil que “por qué sí Y”. Cuando alguien nuevo propone cambiar a X, puede ver directamente por qué se descartó.
ADRs que nunca se actualizan
Si una decisión ya no aplica porque el contexto cambió, el ADR debería reflejarlo. No lo borres: marca el estado como “Superseded by ADR-XXX” y enlaza al nuevo. Así mantienes el historial de decisiones.
No escribir ADRs porque “es un proyecto pequeño”
Los proyectos pequeños son precisamente donde más necesitas ADRs. En un equipo de 20 personas con procesos formales, las decisiones se discuten en reuniones y quedan en actas. En un proyecto personal o de 2-3 personas, las decisiones se toman en la cabeza de alguien y se olvidan en dos meses.
Empieza hoy
Si llevas leyendo este artículo y estás pensando “tiene sentido pero no sé por dónde empezar”, aquí va la versión mínima:
- Crea una carpeta
docs/adr/en tu proyecto. - Copia la plantilla que mostré arriba en
docs/adr/template.md. - Piensa en una decisión de tu proyecto que no sea obvia. La primera que te venga a la mente.
- Escribe el ADR. No busques la perfección. 10 minutos como máximo.
- Haz commit.
Ya está. Ya tienes tu primer ADR. El siguiente lo escribirás cuando tomes la próxima decisión arquitectónica o cuando alguien te pregunte “por qué se hizo así” y te des cuenta de que la respuesta debería estar escrita.
No es burocracia. Es memoria del proyecto. Y la memoria, al contrario que las opiniones, no cambia con el tiempo.


