Cómo construir un sistema de gestión del conocimiento personal
Cómo construir un sistema de gestión del conocimiento sostenible: marcos de notas, estrategias de enlace y recuperación que se potencian.

Todo desarrollador lee documentación, depura errores oscuros y descubre patrones mejores. Casi todo ese conocimiento se evapora en cuestión de semanas. Un sistema de gestión del conocimiento personal (PKM) captura, organiza y hace resurgir lo que aprendes, para que se acumule en vez de desvanecerse.
Esto no se trata de elegir la aplicación correcta. Las herramientas importan menos que el sistema que construyes sobre ellas. Una simple estructura de archivos de texto plano con buenos hábitos supera a una herramienta sofisticada sin ningún proceso.
El hábito de capturar
La parte más importante de la gestión del conocimiento es capturar la información en el momento en que la encuentras. Si esperas siquiera 30 minutos, la mayor parte del contexto ya se ha perdido.
## Capture Template (daily-notes/2021-06-25.md)
### Debug: PostgreSQL connection pool exhaustion
- **Context**: Production alert at 2pm, API response times spiked to 8s
- **Root cause**: Long-running analytics query was holding connections
for 45+ seconds, exhausting the 20-connection pool
- **Fix**: Separate read replica connection pool for analytics queries
with statement_timeout of 30s
- **Ref**: https://wiki.postgresql.org/wiki/Number_Of_Database_Connections
- **Tags**: #postgresql #connection-pool #production-incident
### TIL: CSS `aspect-ratio` works on replaced elements
- Using `aspect-ratio: 16/9` on an img tag prevents layout shift
without needing the padding-bottom hack
- Still need width OR height set — aspect-ratio calculates the other
- **Tags**: #css #layout-shift #performanceLa plantilla de captura tiene cinco campos: contexto (por qué lo buscaste), contenido (qué aprendiste), fuente (dónde lo encontraste), conexiones (con qué se relaciona) y etiquetas.
Organizar con Maps of Content
Los sistemas de etiquetas planas dejan de funcionar a gran escala. Los Maps of Content (MOC) son notas índice que organizan notas relacionadas en una estructura navegable.
## Database Performance MOC (mocs/database-performance.md)
### Connection Management
- [[connection-pooling-essentials]] — pool sizing, pgBouncer config
- [[database-connection-exhaustion-debug]] — production incident, read replica fix
- [[connection-timeout-strategies]] — statement_timeout, idle_in_transaction
### Query Optimization
- [[sql-query-optimization-guide]] — EXPLAIN ANALYZE, index selection
- [[slow-query-log-analysis]] — pg_stat_statements, identifying hot paths
- [[n-plus-one-query-patterns]] — ORM pitfalls, dataloader pattern
### Indexing
- [[database-indexing-deep-dive]] — B-tree, GIN, partial indexes
- [[composite-index-ordering]] — column order matters, left-prefix rule
- [[index-bloat-management]] — REINDEX, pg_repack, monitoring
### Scaling Patterns
- [[read-replica-architecture]] — connection routing, replication lag
- [[database-sharding-strategies]] — hash, range, directory-based
- [[connection-pool-per-service]] — microservices isolation patternLos MOC funcionan porque reflejan la forma en que tu cerebro organiza el conocimiento, no en jerarquías rígidas sino en agrupaciones contextuales. Una nota sobre el pooling de conexiones puede aparecer en el MOC de Rendimiento de Base de Datos y también en un MOC de Incidentes de Producción.
La estrategia de enlaces Zettelkasten
Las notas individuales se vuelven poderosas cuando están enlazadas. El método Zettelkasten crea una red en la que cada nota se conecta con ideas relacionadas.
## Note: Statement Timeout Strategy (notes/statement-timeout-strategy.md)
**ID**: 2021-06-25-1403
**Tags**: #postgresql #timeout #resilience
Setting `statement_timeout` at the connection pool level prevents
any single query from holding resources indefinitely.
```sql
-- Per-connection pool timeout (set in pgBouncer or application config)
ALTER ROLE analytics_reader SET statement_timeout = '30s';
ALTER ROLE api_reader SET statement_timeout = '5s';
-- Per-query override when needed
SET LOCAL statement_timeout = '60s';
SELECT * FROM expensive_analytics_view;
Different roles get different timeouts based on their expected query patterns. The API pool gets a strict 5s timeout because any query taking longer than that should be moved to a background job.
Links:
- Relates to: [[connection-pooling-essentials]] — pool configuration
- Triggered by: [[database-connection-exhaustion-debug]] — discovery context
- Supports: [[circuit-breaker-pattern]] — timeout is a form of circuit breaking
- See also: [[timeout-retry-backoff-pattern]] — what happens after timeout
Cada nota enlaza hacia adelante (qué habilita) y hacia atrás (qué la originó). Con el tiempo, las notas más enlazadas revelan los conceptos centrales de tu base de conocimiento.
## Flujos de recuperación
El conocimiento que no puedes encontrar es conocimiento que no tienes. Integra la recuperación en tu flujo de trabajo diario.
```typescript
// Simple local search script for markdown knowledge base
import { readdir, readFile } from 'fs/promises';
import { join } from 'path';
interface SearchResult {
file: string;
line: number;
context: string;
score: number;
}
async function searchNotes(
query: string,
notesDir: string
): Promise<SearchResult[]> {
const results: SearchResult[] = [];
const queryTerms = query.toLowerCase().split(/\s+/);
const files = await readdir(notesDir, { recursive: true });
for (const file of files) {
if (!file.endsWith('.md')) continue;
const filePath = join(notesDir, file);
const content = await readFile(filePath, 'utf-8');
const lines = content.split('\n');
for (let i = 0; i < lines.length; i++) {
const lower = lines[i].toLowerCase();
const matchCount = queryTerms.filter(t => lower.includes(t)).length;
if (matchCount > 0) {
const start = Math.max(0, i - 1);
const end = Math.min(lines.length, i + 2);
results.push({
file,
line: i + 1,
context: lines.slice(start, end).join('\n'),
score: matchCount / queryTerms.length,
});
}
}
}
return results
.sort((a, b) => b.score - a.score)
.slice(0, 20);
}
// Usage: search("connection pool timeout postgres")
// ❌ Searching only by filename
const result = notes.filter(n => n.filename.includes(query));
// Misses notes where the content matches but the filename doesn't
// ✅ Multi-signal search: filename + content + tags + links
function searchScore(note: Note, query: string): number {
const terms = query.toLowerCase().split(/\s+/);
let score = 0;
for (const term of terms) {
if (note.filename.toLowerCase().includes(term)) score += 3;
if (note.tags.some(t => t.includes(term))) score += 2;
if (note.content.toLowerCase().includes(term)) score += 1;
if (note.links.some(l => l.toLowerCase().includes(term))) score += 1;
}
return score;
}La mejor base de conocimiento es la que realmente utilizas para buscar. Si te encuentras buscando en Google el mismo problema que ya resolviste hace seis meses, tu sistema de recuperación está fallando.
Repaso espaciado
Las notas nuevas necesitan refuerzo. Un hábito de repaso semanal evita que el conocimiento se atrofie.
## Weekly Review Template (templates/weekly-review.md)
### Date: 2021-06-25
#### New Notes This Week (review for accuracy and links)
- [ ] Statement timeout strategy — linked to connection pooling?
- [ ] CSS aspect-ratio discovery — linked to performance MOC?
- [ ] Production incident postmortem — root cause documented?
#### Random Resurfacing (revisit 3 random older notes)
- [ ] [[distributed-tracing-fundamentals]] — still accurate?
- [ ] [[feature-flags-at-scale]] — any new patterns learned since?
- [ ] [[oauth2-flows-demystified]] — relevant to current project?
#### MOC Updates
- [ ] Database Performance MOC — add new connection pool notes
- [ ] Production Incidents MOC — add this week's incident
#### Gaps Identified
- Need deeper notes on pgBouncer configuration
- Missing: comparison of connection pooling libraries for Node.jsEl repaso semanal cumple tres funciones: refuerza el conocimiento nuevo, hace resurgir el conocimiento antiguo e identifica vacíos. La sección de "resurgimiento aleatorio" evita que las notas recientes desplacen a las más antiguas.
Estructura del sistema de archivos
Mantén la estructura de archivos simple. La complejidad en la organización genera fricción que termina matando el hábito.
knowledge-base/
├── daily/ # Quick captures, inbox
│ ├── 2021-06-23.md
│ ├── 2021-06-24.md
│ └── 2021-06-25.md
├── notes/ # Processed, permanent notes
│ ├── connection-pooling-essentials.md
│ ├── statement-timeout-strategy.md
│ └── css-aspect-ratio-layout-shift.md
├── mocs/ # Maps of Content (index notes)
│ ├── database-performance.md
│ ├── frontend-performance.md
│ └── production-incidents.md
├── projects/ # Project-specific knowledge
│ ├── migration-to-k8s/
│ └── auth-service-redesign/
├── templates/ # Capture and review templates
│ ├── daily-note.md
│ ├── weekly-review.md
│ └── incident-postmortem.md
└── README.md # How this system works
Tres carpetas cubren el 90% del flujo de trabajo: daily para capturas en bruto, notes para conocimiento procesado y mocs para la navegación. Todo lo demás es opcional.
Puntos clave
- Captura de inmediato — anótalo en cuanto lo aprendas, no después, cuando ya se haya perdido el contexto
- Usa Maps of Content para organizar las notas en agrupaciones navegables en lugar de jerarquías de carpetas rígidas
- Enlaza sin miedo — cada nota debería conectarse con al menos 2-3 notas relacionadas
- Integra la recuperación en tu flujo de trabajo — si no puedes encontrar algo en 30 segundos, mejora tu búsqueda
- Repasa semanalmente — refuerza las notas nuevas, haz resurgir las antiguas e identifica vacíos de conocimiento
- Mantén la estructura mínima — tres carpetas (daily, notes, MOCs) cubren la mayoría de los flujos de trabajo


