This is a simple batch ingestion system for large JSON payloads. It keeps the API fast by sending work to Redis/BullMQ and letting a background worker process the records while PostgreSQL tracks the job state.
flowchart LR
A[Client] --> B[API]
B --> C[(PostgreSQL)]
B --> D[Redis Queue]
D --> E[Worker]
E --> C
- Client sends raw JSON array text.
- API creates a
BatchJob. - API adds the job to BullMQ.
- Worker reads the job and processes records in chunks.
- Valid rows go into
IngestedRecord. - Bad rows go into
JobError.
- Node.js
- TypeScript
- Express
- PostgreSQL
- Prisma
- Redis
- BullMQ
- Docker
- API accepts raw JSON array text and returns quickly with a queued job id.
- Worker processes records in small chunks of 100 so memory use stays lower.
- PostgreSQL stores job state, valid rows, and row-level errors.
- Redis + BullMQ handles background processing.
- Docker runs API, worker, Postgres, and Redis together.
npm run benchmarkcompares one-shot processing with chunked async processing.
npm install
npx prisma generate
npm run prisma:deploy
npm run devdocker compose up --buildPORT=3001
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/distributed_loader
REDIS_URL=redis://127.0.0.1:6379Send a raw JSON array:
[{"name":"A"},{"name":"B"}]{
"success": true,
"message": "Batch accepted and queued",
"jobId": "uuid"
}Get one batch job by id:
GET /api/batch/:jobIdResponse includes the job status, row counts, and record/error totals.