El Data Lake de $0 para Startups: DataSpoc + S3 en 30 Minutos
Eres el ingeniero fundador de una startup en etapa seed. Tu CEO pregunta “¿cuántos usuarios se registraron la semana pasada?” y tú haces SSH al servidor de producción, abres psql, escribes una consulta, pegas el resultado en Slack. La próxima semana la pregunta es “¿cuál es nuestro MRR de Stripe?” y ahora estás haciendo malabares con dos fuentes de datos.
Este artículo construye una plataforma de datos completa en 30 minutos por menos de $5/mes. Ingestarás desde Postgres y Stripe, consultarás con SQL e IA, y conectarás a Claude cómo agente. Al final, cualquier persona de tu equipo puede hacer preguntas sobre tus datos sin molestarte.
Lo Que Construirás
Postgres ──→ [Pipe] ──→ S3 Bucket ──→ [Lens] ──→ SQL ShellStripe ──→ [Pipe] ──┘ │ ├──→ AI Ask │ ├──→ Jupyter │ └──→ MCP → Claude- Pipe extrae de Postgres y Stripe, escribe Parquet en S3
- Lens consulta los archivos Parquet con DuckDB
- MCP conecta Claude (o Cursor, Windsurf) a tu data lake
Costo total: almacenamiento S3 (~$2/mes para datos a escala de startup) + DataSpoc ($0, código abierto).
Minuto 0-5: Instalar Todo
# Install both toolspip install dataspoc-pipe dataspoc-lens
# Install the Singer taps you needdataspoc-pipe add tap-postgresdataspoc-pipe add tap-stripe
# Verifydataspoc-pipe --versiondataspoc-lens --versionCrea un bucket S3 para tu data lake:
aws s3 mb s3://mycompany-data-lake --region us-east-1Minuto 5-12: Ingestar desde Postgres
Crea la configuración del pipeline:
source: tap: tap-postgres config: host: "${DATABASE_HOST}" port: 5432 database: "${DATABASE_NAME}" user: "${DATABASE_READONLY_USER}" password: "${DATABASE_READONLY_PASSWORD}"
tables: - name: users replication_method: incremental replication_key: updated_at
- name: orders replication_method: incremental replication_key: updated_at
- name: subscriptions replication_method: incremental replication_key: updated_at
target: bucket: "s3://mycompany-data-lake" prefix: "raw/postgres" format: parquetCrea un usuario de base de datos de solo lectura (nunca uses las credenciales de tu app para ETL):
-- Run once on your Postgres databaseCREATE USER dataspoc_readonly WITH PASSWORD 'secure-random-password';GRANT CONNECT ON DATABASE myapp TO dataspoc_readonly;GRANT USAGE ON SCHEMA public TO dataspoc_readonly;GRANT SELECT ON ALL TABLES IN SCHEMA public TO dataspoc_readonly;ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO dataspoc_readonly;Configura las variables de entorno y ejecuta:
export DATABASE_HOST="your-rds-endpoint.amazonaws.com"export DATABASE_NAME="myapp"export DATABASE_READONLY_USER="dataspoc_readonly"export DATABASE_READONLY_PASSWORD="secure-random-password"
dataspoc-pipe run postgres-app[09:05:01] Starting pipeline: postgres-app[09:05:02] Extracting: users (2,340 rows)[09:05:03] → raw/postgres/users/users_20260428.parquet (180 KB)[09:05:03] Extracting: orders (8,920 rows)[09:05:05] → raw/postgres/orders/orders_20260428.parquet (720 KB)[09:05:05] Extracting: subscriptions (1,890 rows)[09:05:06] → raw/postgres/subscriptions/subscriptions_20260428.parquet (95 KB)[09:05:06] Pipeline complete: 3 tables, 13,150 rowsMinuto 12-20: Ingestar desde Stripe
source: tap: tap-stripe config: api_key: "${STRIPE_API_KEY}" # Use a restricted key with read-only access start_date: "2025-01-01"
streams: - charges - customers - invoices - subscriptions - balance_transactions
target: bucket: "s3://mycompany-data-lake" prefix: "raw/stripe" format: parquetObtén una clave de API restringida desde el Dashboard de Stripe (Settings > API Keys > Create Restricted Key con acceso de solo lectura):
export STRIPE_API_KEY="rk_live_..."
dataspoc-pipe run stripe[09:12:01] Starting pipeline: stripe[09:12:03] Extracting: charges (4,560 records)[09:12:08] Extracting: customers (2,120 records)[09:12:11] Extracting: invoices (3,890 records)[09:12:15] Extracting: subscriptions (1,450 records)[09:12:18] Extracting: balance_transactions (12,340 records)[09:12:22] Pipeline complete: 5 streams, 24,360 recordsMinuto 20-25: Conectar Lens y Consultar
Registra el bucket con Lens:
dataspoc-lens add-bucket s3://mycompany-data-lake --name datalakedataspoc-lens tablesraw.postgres.usersraw.postgres.ordersraw.postgres.subscriptionsraw.stripe.chargesraw.stripe.customersraw.stripe.invoicesraw.stripe.subscriptionsraw.stripe.balance_transactionsOcho tablas de dos fuentes. Ahora consulta:
# How many users signed up last week?dataspoc-lens query " SELECT COUNT(*) AS signups FROM raw.postgres.users WHERE created_at >= CURRENT_DATE - INTERVAL 7 DAY"
# What is our MRR?dataspoc-lens query " SELECT SUM(plan_amount / 100.0) AS mrr_dollars FROM raw.stripe.subscriptions WHERE status = 'active'"
# Revenue by day this monthdataspoc-lens query " SELECT DATE_TRUNC('day', created::TIMESTAMP) AS day, SUM(amount / 100.0) AS revenue FROM raw.stripe.charges WHERE status = 'succeeded' AND created::TIMESTAMP >= DATE_TRUNC('month', CURRENT_DATE) GROUP BY 1 ORDER BY 1"O usa IA (configura un proveedor o usa Ollama gratis):
dataspoc-lens setup-ai # installs Ollama + local model
dataspoc-lens ask "what is our MRR?"dataspoc-lens ask "how many users signed up each day this week?"dataspoc-lens ask "what is the average revenue per user?"Minuto 25-30: Conectar Claude vía MCP
Agrega la configuración del servidor MCP para Claude Desktop o cualquier herramienta compatible con MCP:
{ "mcpServers": { "dataspoc-lens": { "command": "dataspoc-lens", "args": ["mcp"], "env": { "AWS_PROFILE": "default" } } }}Ahora en Claude Desktop, escribe:
What tables do we have in the data lake?Claude llama al servidor MCP, descubre tus tablas y responde. Continúa con:
What is our MRR and how has it changed month over month?Claude escribe SQL, lo ejecuta contra tus archivos Parquet y te da una respuesta formateada con análisis. Tu CEO ahora puede preguntarle a Claude directamente en lugar de mandarte un mensaje por Slack.
Programarlo
Agrega un cron job para mantener los datos frescos:
crontab -e# Extract from Postgres every hour0 * * * * cd /opt/dataspoc && dataspoc-pipe run postgres-app >> /var/log/dataspoc/postgres.log 2>&1
# Extract from Stripe every 6 hours (API rate limits)0 */6 * * * cd /opt/dataspoc && dataspoc-pipe run stripe >> /var/log/dataspoc/stripe.log 2>&1
# Refresh Lens cache after extractions5 * * * * dataspoc-lens cache refresh-stale >> /var/log/dataspoc/cache.log 2>&1Desglose de Costos
| Componente | Costo Mensual | Notas |
|---|---|---|
| DataSpoc Pipe | $0 | Código abierto |
| DataSpoc Lens | $0 | Código abierto |
| Almacenamiento S3 (1 GB) | $0.023 | Parquet está altamente comprimido |
| Solicitudes S3 | ~$1-2 | PUT/GET para extracción y consultas |
| Ollama (IA local) | $0 | Se ejecuta en tu máquina |
| Total | < $3/mes |
Compara con las alternativas:
| Alternativa | Costo Mensual |
|---|---|
| Snowflake | $400+ (warehouse mínimo) |
| BigQuery | $0 (tier gratis) luego $5/TB consultado |
| Fivetran + Snowflake | $500+ |
| Airbyte Cloud + Redshift | $400+ |
| DataSpoc + S3 | < $5 |
Lo Que Obtienes
Por menos de $5/mes, tu startup ahora tiene:
- Ingesta de datos automatizada desde Postgres y Stripe (cada hora)
- Analítica SQL sobre Parquet en la nube (sin warehouse que gestionar)
- Consultas potenciadas por IA (gratis con Ollama, o usa Claude/OpenAI)
- Integración MCP para Claude Desktop, Cursor, Windsurf
- Extracción incremental (solo se obtienen datos nuevos)
- Sin infraestructura que gestionar (S3 + herramientas CLI)
Camino de Crecimiento: Cuándo Escalar
Esta configuración maneja una startup desde seed hasta Serie A cómodamente. Aquí está cuándo considerar mejoras:
| Hito | Acción |
|---|---|
| Datos > 10 GB | Agregar más almacenamiento S3 ($0.23/mes por 10 GB) |
| Necesitas transformaciones | Agregar archivos SQL de transformación (ver nuestro post de alternativa a dbt) |
| 5+ fuentes de datos | Agregar más pipelines de Pipe (mismo patrón) |
| Necesitas dashboards | Conectar Metabase/Superset a DuckDB vía Lens |
| Equipo > 5 analistas | Considerar cache de Lens en servidor compartido |
| Datos > 1 TB | Considerar estrategia de particionamiento, sigue funciónando con DuckDB |
| Necesitas tiempo real | Ahí es cuando miras Kafka + streaming — aún no |
El insight clave: siempre puedes migrar a un stack más pesado después. Parquet en S3 es el formato de datos universal. Si superas DataSpoc, tus datos funciónan con Spark, Trino, Athena o tablas externas de Snowflake.
Agregar Más Fuentes Después
DataSpoc Pipe soporta más de 400 taps de Singer. Agrega cualquier fuente en minutos:
# HubSpot CRMdataspoc-pipe add tap-hubspot
# Google Analyticsdataspoc-pipe add tap-google-analytics
# Salesforcedataspoc-pipe add tap-salesforce
# MySQL (if you have a second database)dataspoc-pipe add tap-mysql
# Google Sheets (for manual data)dataspoc-pipe add tap-google-sheetsCada fuente obtiene su propio YAML de pipeline y se ejecuta en su propio horario. Todos los datos llegan al mismo bucket S3, consultables a través de la misma interfaz de Lens.
El Script de Configuración Completo
Guarda esto y ejecútalo para configurar todo de una vez:
#!/bin/bash# setup-data-lake.sh -- Complete startup data lake setupset -e
echo "=== DataSpoc Data Lake Setup ==="
# Install toolsecho "[1/6] Installing DataSpoc..."pip install dataspoc-pipe dataspoc-lens
# Install tapsecho "[2/6] Installing source connectors..."dataspoc-pipe add tap-postgresdataspoc-pipe add tap-stripe
# Create S3 bucketecho "[3/6] Creating S3 bucket..."aws s3 mb s3://mycompany-data-lake --region us-east-1
# Run initial extractionecho "[4/6] Running initial extraction..."dataspoc-pipe run postgres-appdataspoc-pipe run stripe
# Configure Lensecho "[5/6] Configuring query engine..."dataspoc-lens add-bucket s3://mycompany-data-lake --name datalake
# Setup local AIecho "[6/6] Setting up AI queries..."dataspoc-lens setup-ai
echo ""echo "=== Setup Complete ==="echo "Tables available:"dataspoc-lens tablesecho ""echo "Try: dataspoc-lens ask 'how many users signed up this week?'"Treinta minutos. Menos de $5/mes. Una plataforma de datos completa que crece contigo. Deja de hacer SSH a producción para responder preguntas de negocio.