Redyx
An anonymous, community-driven discussion platform inspired by Reddit, built from scratch as a distributed system. 12 Go microservices communicating over gRPC, fronted by Envoy, with Kafka for async workflows, consistent-hashing-based database sharding, and full Kubernetes deployment with observability.

Redyx -- Anonymous Discussion Platform
Redyx is an anonymous, community-driven discussion platform inspired by Reddit, built from scratch as a distributed microservice system. Users create communities, post content (text, links, media), comment in nested threads, and vote on everything -- all under pseudonymous usernames. No real names, no exposed emails, no stored IP addresses.
The backend consists of 12 Go microservices communicating over gRPC, fronted by an Envoy API gateway that translates REST/JSON from the Astro + Svelte frontend. Asynchronous workflows flow through Apache Kafka. Fully containerized and deployable on Kubernetes with a complete observability stack.
Architecture
1+------------------+2 | Cloudflare CDN |3 +--------+---------+4 |5 +--------v---------+6 | Astro Frontend | (SSR + Svelte Islands)7 +--------+---------+8 | REST/JSON9 +--------v---------+10 | Envoy Gateway |11 | - REST -> gRPC |12 | - Rate limiting |13 | - JWT validation|14 +--------+---------+15 | gRPC (internal)16 +------------------+------------------+17 | | | | |18 +----v---+ +---v----+ +v------+ +v------+ +v--------+19 | Auth | | User | | Post | | Vote | | Comment |20 | Service| | Service| | Svc | | Svc | | Service |21 +----+---+ +---+----+ +---+---+ +---+---+ +----+----+22 | | | | |23 +----v---+ +---v----+ +--v----+ +-v------+ +---v-----+24 |Postgres| |Postgres| |Postgres| | Redis | | ScyllaDB|25 | (auth) | | (user) | |(shard) | | +Kafka | | |26 +--------+ +--------+ +-------+ +--------+ +---------+2728 +------------------+------------------+------------------+29 | | | | | |30+----v-----+ +v------+ +v--------+ +------v-------+ +--------v-------+31| Community| | Search| | Media | | Notification | | Moderation/Spam|32| Service | | Svc | | Service | | Service | | Services |33+----+-----+ +---+---+ +----+----+ +------+-------+ +--------+-------+34 | | | | |35+----v---+ +----v-----+ +--v-----+ +----v----+ +-----v----+36|Postgres| |Meilisearch| | MinIO | | Redis | | Postgres |37|(commty)| +----------+ | (S3) | | +Kafka | | +Redis |38+--------+ +--------+ | +PG | | +Kafka |39 +---------+ +----------+
Tech Stack
| Layer | Technology | Purpose |
|---|---|---|
| Frontend | Astro (SSR) + Svelte (Islands) | Content-driven pages with minimal JS; interactive components hydrate as Svelte islands |
| API Gateway | Envoy Proxy | REST-to-gRPC transcoding, rate limiting, CORS, load balancing, WebSocket upgrades |
| Backend | Go (Golang) | All 12 microservices; high concurrency, strong gRPC ecosystem |
| Service Comm | gRPC + Protocol Buffers | Type-safe, binary protocol for inter-service calls; 15 .proto definitions |
| Message Queue | Apache Kafka | Event-driven workflows: vote processing, search indexing, notifications, spam analysis |
| Cache | Redis | Session store, vote counts, rate limiting, hot feeds, OTP codes, WebSocket registry |
| Primary DB | PostgreSQL 16 | ACID-compliant relational storage across 5 instances (one sharded) |
| Comment Store | ScyllaDB 6.2 | High-throughput wide-column store for nested comment trees |
| Search | Meilisearch v1.12 | Full-text search with typo tolerance, ranked by relevance + recency + score |
| Object Storage | MinIO (S3-compatible) | Image/video uploads, thumbnails; production uses AWS S3 + CloudFront |
| Orchestration | Kubernetes (kind for local) | Helm charts, HPA, namespace isolation, NGINX Ingress |
| Monitoring | Prometheus + Grafana | Metrics collection via /metrics endpoints; per-service dashboards |
| Logging | Loki + Promtail | Centralized structured JSON log aggregation, queryable through Grafana |
| Tracing | OpenTelemetry + Jaeger | Distributed request tracing across all microservices |
| Auth Tokens | JWT (access 15m + refresh 7d) | Stateless authentication with short-lived access and long-lived refresh tokens |
| Password Hashing | Argon2id | Memory-hard, GPU-resistant hashing (RFC 9106 parameters) |
Services Overview
The most architecturally significant service -- handles post CRUD, feed generation, and ranking with database sharding via consistent hashing.
- Post types: text (markdown), link, media
- Anonymous posting (visible only to moderators)
- Feed generation: community feed (single-shard), home feed (cross-shard fan-out), saved posts
- Ranking algorithms: Hot (Lemmy algorithm), New, Top (time-filtered), Rising (velocity-based)
- Consistent hashing:
community_idmaps to shard via hash ring with 40 virtual nodes per shard - Pre-publish spam and moderation checks (synchronous gRPC)
- Kafka events:
PostCreated,PostUpdated,PostDeletedconsumed by Search, Notification, Spam
Database Architecture
The system uses 9 data stores across 5 technologies:
PostgreSQL (5 instances): pg-auth (credentials), pg-user (profiles/karma), pg-community (communities/memberships), pg-post (sharded by community_id), pg-platform (moderation/notifications/media metadata).
ScyllaDB (1 cluster): All comments, partitioned by post_id, clustered by materialized path.
Redis (1 instance, 12 logical databases): Each service gets a dedicated db (db0-db11) -- OTP codes, vote state, karma cache, feed cache, WebSocket registry, dedup hashes, and more.
Meilisearch (1 instance): Full-text search index for posts and communities.
MinIO / S3 (1 bucket): Object storage for uploads, thumbnails, and community banners.
Post Sharding with Consistent Hashing
The Post Service implements application-level database sharding using consistent hashing:
- Each
community_idis hashed onto a ring usingserialx/hashring - The ring has 40 virtual nodes per physical shard for even distribution
- All posts for a community land on the same shard
- Community feed queries hit a single shard (no cross-shard joins)
- Home feed queries fan out to all shards in parallel
Adding a new shard: consistent hashing ensures only ~1/N of data migrates. Identify affected community_id values, background-migrate, flip routing, clean up.
Current deployment: 2 shards (posts_shard_0, posts_shard_1), each in its own PostgreSQL database.
Async Event Flows (Kafka)
1VoteCreated ->2 Post Service: update post score3 Comment Service: update comment score4 User Service: update karma5 Spam Service: vote manipulation detection67PostCreated ->8 Search Service: index in Meilisearch9 Notification Service: notify community followers10 Spam Service: analyze for spam patterns1112PostRemoved ->13 Post Service: mark as removed14 Notification Service: notify the author15 Search Service: remove from index
Security and Privacy
- Anonymity by design: Users identified only by username; no real name, phone, or location
- Argon2id: RFC 9106 parameters (64 MiB memory, GPU-resistant)
- JWT: Short-lived access tokens (15 min) with long-lived refresh tokens (7 days)
- No IP storage: IPs hashed with SHA-256 + salt for abuse detection (24h TTL in Redis)
- TLS everywhere: Envoy terminates external TLS; internal mTLS via Istio (optional)
- Parameterized queries: No string concatenation in SQL
- Account deletion: True PII purge; posts become
[deleted], vote records anonymized - Constant-time comparison:
subtle.ConstantTimeComparefor password verification
Observability
- Prometheus: Scrapes
/metricsfrom each service viago-grpc-prometheusinterceptors - Grafana: Per-service dashboards with Prometheus, Loki, and Jaeger data sources
- Loki + Promtail: Centralized structured JSON log aggregation
- Jaeger: Distributed tracing via OpenTelemetry SDK, trace context propagated across gRPC calls
- Alerting: Error rate spikes, P99 latency thresholds, pod restarts, Kafka consumer lag
Deployment
Docker Compose (Local Development)
make docker-up # Start all services make docker-logs # Tail logs make docker-down # Stop everything
Kubernetes (kind)
make k8s-up # Full deployment: cluster + ingress + storage + data + monitoring + app make k8s-status # Show cluster status make k8s-down # Tear down everything
Namespaces: redyx-app (12 microservices + Envoy), redyx-data (PostgreSQL, Redis, ScyllaDB, Kafka, Meilisearch, MinIO), redyx-monitoring (Prometheus, Grafana, Loki, Jaeger).
Features: Helm chart, HPA per service, gRPC health probes, ConfigMaps/Secrets, NGINX Ingress Controller.
Screenshots
Project Structure
1redyx/2|-- cmd/ # Service entry points (main.go per service)3| |-- auth/, comment/, community/, media/, moderation/4| |-- notification/, post/, search/, spam/, user/, vote/5|6|-- internal/ # Service implementations7| |-- auth/ # Hasher, JWT, OAuth, OTP, email8| |-- comment/ # ScyllaDB, materialized path, Wilson score9| |-- community/ # CRUD, cache10| |-- media/ # S3, thumbnails11| |-- moderation/ # Mod actions, store12| |-- notification/ # WebSocket hub, Kafka consumer13| |-- post/ # Shard router, ranking, cache, Kafka14| |-- search/ # Meilisearch client, Kafka indexer15| |-- spam/ # Blocklist, dedup, Kafka consumer16| |-- user/ # Profiles, karma17| |-- vote/ # Redis Lua scripts, Kafka producer/consumer18| |-- platform/ # Shared libraries (JWT, config, DB, errors,19| # middleware, observability, pagination,20| # rate limiting, Redis)21|22|-- proto/redyx/ # 15 Protocol Buffer definitions23|-- gen/ # Generated Go code from protobuf24|-- migrations/ # SQL migrations per database25|-- deploy/26| |-- docker/ # Multi-stage Dockerfile, init-databases.sql27| |-- envoy/ # Envoy config (REST->gRPC transcoding)28| |-- k8s/ # kind config, storage, data, monitoring,29| # ingress, Helm chart30|-- web/ # Astro + Svelte frontend31|-- docker-compose.yml32|-- Makefile