← All work
Systems/Workers · Kafka/2024 — 2025/Built

Distributed Job Platform

Fault-tolerant workers with visibility leases, exponential backoff, idempotency keys, dead-letter routing, heartbeat reclaim for crashed workers and queue-depth metrics.

JavaSpring BootKafkaRedisPostgreSQL
Personal systems work
01

The problem

Background job systems tend to fail in the same handful of ways: a worker dies mid-job and the job is lost, a retry runs the side effect twice, one poison message blocks a partition, and nobody notices the backlog until a user does. I built the platform to handle each of those explicitly rather than hope.

02

Who uses it

2 groups

Producing services

Hand off work and know it will run exactly once, or land somewhere visible if it cannot.

Operators

See queue depth, retry rate and dead letters, and replay a fixed batch without a deploy.

03

Workflow

6 stages
01Submit job
02Claim with lease
03Execute idempotently
04Heartbeat while running
05Retry with backoff
06Dead-letter & replay
01 · SubmitTriggerProducer publishes a job with an idempotency keySystemSpring Boot API, Kafka topicOutputJob accepted; a duplicate key returns the original job instead of a second one
02 · ClaimTriggerWorker polls for available workSystemVisibility lease held in Redis with a TTLOutputJob claimed and invisible to other workers for the lease window
03 · ExecuteTriggerLease acquiredSystemHandler with an idempotency check before the side effectOutputEffect applied once; a replayed job is recognised and skipped
04 · HeartbeatTriggerEvery interval while the job runsSystemWorker heartbeat extending the leaseOutputLong jobs keep their claim; a crashed worker's lease expires and the job is reclaimed
05 · RetryTriggerHandler throws a retryable errorSystemExponential backoff with jitter, bounded attemptsOutputJob rescheduled; transient failures clear without operator involvement
06 · Dead-letterTriggerAttempts exhausted, or the payload is unprocessableSystemDead-letter topic, metrics, replay toolOutputPoison messages parked out of the hot path and replayable after a fix
04

How it was built

6 parts

Leases instead of locks

A worker claims a job by taking a lease with a TTL rather than holding a lock. If the worker dies the lease simply expires and another worker picks the job up — no lock to release, no manual cleanup, and the failure mode is a delay rather than a lost job.

Idempotency keys

Every job carries a key. The handler checks it before performing the side effect and records it after, so an at-least-once delivery becomes an effectively-once outcome. Retries and duplicate submissions are both safe by construction.

Backoff with jitter

Retries back off exponentially with jitter, so a downstream outage does not turn into a synchronised retry storm the moment it recovers. Attempts are bounded; what exhausts them is dead-lettered rather than retried forever.

Heartbeat reclaim

Running jobs heartbeat to extend their lease. This separates 'slow' from 'dead': a long job keeps its claim, and a crashed worker's jobs return to the queue within one lease window instead of hanging until someone notices.

Dead-letter routing and replay

Unprocessable messages go to a dead-letter topic with their failure reason attached, keeping one bad payload from blocking a partition. A replay path pushes a corrected batch back through the normal flow after the fix.

Metrics

Queue depth, lease expiry rate, retry rate, dead-letter rate and handler latency are exported. Depth trending up while throughput is flat is the signal that matters, and it is visible before users feel it.

05

What it is built with

Runtime

  • Java
  • Spring Boot
  • Concurrency

Messaging

  • Kafka
  • Partitioning
  • Dead-letter topics

State

  • Redis leases
  • PostgreSQL
  • Idempotency store

Operations

  • Metrics
  • Replay tooling
  • JUnit
06

Outcome