A production-style backend system built in Go that demonstrates how a distributed backup platform can be architected using modern backend patterns.
This project implements:
- Clean Architecture
- gRPC client/server communication
- Worker pool concurrency
- Streaming database backups β MinIO (S3-compatible object storage)
- Pluggable storage adapters (local / S3 / GCS)
- Slack notifications
- Scheduler (cron-based, triggers real gRPC backup jobs)
- Dockerized development environment
- Prometheus metrics
- Graceful shutdown
- Context propagation
- Retry + backoff strategy
- Timestamp-based backup naming
The goal of this project is to simulate how real infrastructure backup tools are designed and implemented.
backup-cli
β
βΌ
gRPC Client
β
βΌ
backup-daemon (gRPC Server)
β
βββ Scheduler (cron jobs β triggers real gRPC RunBackup calls)
βββ Worker Pool
βββ Retry + Backoff
βββ Metrics
β
βΌ
Backup Pipeline
(pg_dump β gzip β S3/MinIO)
β
βΌ
Notifications (Slack)
+--------------------+
| backup-cli |
| gRPC Client |
+----------+---------+
|
v
+--------------------+
| backup-daemon |
| gRPC Server |
| :50051 |
| Metrics :9090 |
+----------+---------+
|
+-----------------+------------------+
| |
v v
+---------------+ +--------------------+
| PostgreSQL | | MinIO |
| :5432 | | S3-Compatible Store|
+---------------+ | API :9000 |
| Console :9001 |
+--------------------+
All services run locally through Docker Compose to simulate a production-like environment.
| Layer | Technology |
|---|---|
| Language | Go |
| RPC Transport | gRPC |
| Concurrency | Goroutines + Channels |
| Scheduler | robfig/cron |
| Compression | gzip |
| Storage | MinIO (S3-compatible) / Local / GCS Adapter |
| Notifications | Slack Webhook |
| Metrics | Prometheus |
| Logging | Zap |
| Containerization | Docker + Docker Compose |
BackUpData/
β
βββ cmd/
β βββ backup-cli/ # CLI client
β β βββ cmd/
β β β βββ backup.go
β β β βββ root.go
β β β βββ schedule.go
β β βββ main.go
β β
β βββ backup-daemon/ # gRPC backup server
β βββ main.go
β
βββ internal/
β βββ compression/
β β βββ gzip.go
β β
β βββ core/
β β βββ worker/
β β βββ backup_service.go
β β βββ full_backup.go
β β βββ interfaces.go
β β βββ job.go
β β βββ job_handler.go
β β βββ strategy.go
β β
β βββ db/
β β βββ postgres/
β β βββ backup.go
β β βββ executor.go
β β βββ postgres.go
β β
β βββ storage/
β β βββ local/
β β βββ s3/ # Active: used by MinIO adapter
β β βββ gcs/
β β
β βββ notification/
β β βββ slack/
β β βββ slack.go
β β
β βββ scheduler/
β β βββ scheduler.go
β β
β βββ metrics/
β βββ metrics.go
β
βββ pkg/
β βββ config/
β βββ logger/
β
βββ proto/
β βββ backup.proto
β βββ backup.pb.go
β βββ backup_grpc.pb.go
β
βββ docker-compose.yml
βββ Dockerfile
βββ go.mod
βββ go.sum
Note: The
backups/local directory is no longer the primary destination. All backups are streamed directly to MinIO using the S3 adapter. Local storage remains available as a fallback adapter.
Business logic is isolated from external systems.
CLI / gRPC Layer
β
βΌ
Application Layer
β
βΌ
Core Business Logic
β
βΌ
Adapters (DB / Storage / Notifications)
This makes the system:
- extensible
- testable
- loosely coupled
Multiple backups can run concurrently.
+-------------+
| Job Channel |
+-------------+
β β β
βΌ βΌ βΌ
W1 W2 W3
Each worker processes backup jobs asynchronously.
Large databases are backed up using streaming I/O β no intermediate files, no full in-memory loads.
PostgreSQL
β
βΌ
pg_dump (streaming stdout)
β
βΌ
gzip compression (streaming)
β
βΌ
MinIO / S3 storage adapter (multipart upload)
Backup objects are named using a timestamp-based convention to avoid collisions and enable chronological sorting:
postgres-db_2024-01-15T02-00-00Z.sql.gz
The CLI communicates with the daemon using gRPC.
backup-cli
β
βΌ
RunBackup RPC
β
βΌ
backup-daemon
The daemon executes the backup pipeline and returns a response.
Backups are automated using cron expressions. The scheduler directly invokes the gRPC RunBackup RPC internally β it does not use shell commands or indirect triggers.
Example cron expression:
0 2 * * *
Runs a real backup job every day at 2 AM by calling RunBackup through the gRPC layer. During development, the interval is set to every 10 seconds for rapid iteration.
MinIO runs as a containerized S3-compatible object store. It is started automatically via Docker Compose alongside PostgreSQL.
http://localhost:9001
Default credentials (development only):
Username: minio
Password: minio123
Using the MinIO console:
- Open
http://localhost:9001in your browser - Navigate to Buckets β Create Bucket
- Name the bucket:
backups - Click Create Bucket
Using the MinIO CLI (mc):
# Configure the local MinIO alias
mc alias set local http://localhost:9000 minioadmin minioadmin
# Create the bucket
mc mb local/backups
# Verify
mc ls local/The daemon uses the following environment variables to connect to MinIO:
S3_ENDPOINT=http://localhost:9000
S3_BUCKET=backup-bucket
S3_ACCESS_KEY=minio123
S3_SECRET_KEY=minio
S3_USE_PATH_STYLE=true
S3_USE_PATH_STYLE=trueis required for MinIO β it uses path-style URLs instead of virtual-hosted style.
Slack notifications are sent after backup completion.
Example message:
Backup completed
Database: postgres-db
File: postgres-db_2024-01-15T02-00-00Z.sql.gz
Storage: MinIO (s3://backups/)
Duration: 3s
Size: 12000 bytes
The daemon exposes metrics at:
http://localhost:9090/metrics
Available metrics:
backup_success_total
backup_failure_total
backup_duration_seconds
These metrics allow integration with Grafana dashboards and alerts.
The system can be run in two ways:
- Local development
- Docker deployment
- Go 1.22+
- Docker
- Docker Compose
- protoc
- protoc-gen-go
- protoc-gen-go-grpc
Start all services (PostgreSQL + MinIO):
docker compose up -dVerify containers:
docker psExpected services:
backup-postgres
backup-mysql
backup-minio
Connect to the database container:
docker exec -it backup-postgres psql -U backup -d testdbCreate sample table:
CREATE TABLE users(
id SERIAL PRIMARY KEY,
name TEXT
);Insert sample data:
INSERT INTO users(name) VALUES ('alice'), ('bob');Verify:
SELECT * FROM users;Before running the daemon, ensure the backups bucket exists in MinIO:
mc alias set local http://localhost:9000 minioadmin minioadmin
mc mb local/backupsOr use the console at http://localhost:9001.
go run ./cmd/backup-daemonDaemon runs on:
- gRPC:
:50051 - Metrics:
:9090
In another terminal:
go run ./cmd/backup-cli backupExpected output:
Daemon Response: backup completed
List backup objects in the MinIO bucket:
mc ls local/backupsExample output:
[2024-01-15 02:00:03] 12345 postgres-db_2024-01-15T02-00-00Z.sql.gz
Inspect backup content:
mc cat local/backups/postgres-db_2024-01-15T02-00-00Z.sql.gz | gunzip | headOr via the MinIO console at http://localhost:9001 β Object Browser β backups.
Open browser:
http://localhost:9090/metrics
Example output:
backup_success_total 1
backup_failure_total 0
Run the full system with:
docker compose up --buildStop the system:
docker compose down+----------------+
| backup-cli |
+----------------+
|
v
+----------------+
| backup-daemon |
| gRPC Server |
+----------------+
| |
v v
+---------+ +--------------+
| Worker | | PostgreSQL |
+---------+ +--------------+
|
v
+------------------------+
| Storage Layer |
| (S3 Adapter β MinIO) |
+------------------------+
|
v
+--------------+
| Notifications|
+--------------+
+---------------------+
| BackupService |
|---------------------|
| RunBackup() |
| StreamProgress() |
+---------------------+
|
v
+----------------------+
| BackupExecutor |
|----------------------|
| Run() |
+----------------------+
|
v
+----------------------+
| PostgresExecutor |
+----------------------+
|
v
+----------------------+
| S3StorageAdapter |
| (MinIO-compatible) |
+----------------------+
Job Queue
β
ββββββββββββΌβββββββββββ
βΌ βΌ βΌ
Worker1 Worker2 Worker3
β β β
ββββββββββββ΄βββββββββββ
β
Streaming β MinIO
All backup objects follow a timestamp-based naming scheme:
{database-name}_{ISO8601-timestamp}.sql.gz
Example:
postgres-db_2024-01-15T02-00-00Z.sql.gz
This ensures:
- No filename collisions across scheduled runs
- Chronological sorting in object storage
- Easy retention policy management by date prefix
Krishna Thakur
Backend engineering learning project focused on building production-style infrastructure systems in Go.
- X (Twitter): https://x.com/i_krsna4
- LinkedIn: https://www.linkedin.com/in/krishnathakur1/
β Star this repository if you find it helpful!