This document presents a robust backend architecture for implementing a publish-subscribe system that supports high-throughput message distribution, fault tolerance, and real-time event processing across distributed services.
1. Executive Summary
Clarifying questions
-
What is the expected read/write ratio for the publish-subscribe system?
- Is this primarily a pub/sub system with high write volume and moderate reads, or is it more balanced?
-
What are the consistency requirements for messages?
- Are there strict ordering guarantees needed (e.g., exactly-once delivery, per-partition ordering)?
-
Is this a global system or regional?
- Will the system span multiple regions or be deployed in a single region?
-
How sensitive is the system to latency?
- Are there strict SLA requirements for message delivery (e.g., sub-second p99)?
-
What is the expected growth in terms of publishers, subscribers, and message volume?
- Is this a system for millions of users or more?
-
Are there any external integrations or third-party services that will publish or subscribe to this system?
- Will the system support external clients (e.g., webhooks, IoT devices)?
-
What is the expected message size and payload type?
- Are messages small JSON payloads or large binary data?
Problem being solved
The publish-subscribe (pub/sub) system enables decoupled communication between publishers and subscribers, allowing for scalable, asynchronous event-driven architectures. The system must support real-time message delivery, handle high throughput, and ensure reliability in a distributed environment.
Back-of-envelope calculations
Assuming:
- 10 million daily active users (DAU)
- Peak-to-average ratio of 10:1
- Average message size = 1KB
- 5 messages per user per day
Peak QPS:
- DAU = 10M
- Messages per day = 10M * 5 = 50M messages
- Peak QPS = (50M * 10) / 86400 ≈ 5,787 QPS
Storage per user/event:
- 1KB per message
- 5 messages/user/day
- Storage per user = 5KB/day
Total storage growth per year:
- 10M users * 5KB * 365 = 18.25 TB/year
Bandwidth (read + write throughput in MB/s):
- Write bandwidth = 5,787 QPS * 1KB ≈ 5.79 MB/s
- Read bandwidth = 5,787 QPS * 1KB ≈ 5.79 MB/s
- Total = 11.58 MB/s
Cache hit rate assumption: 90%
- Cache hits = 5,787 QPS * 0.9 ≈ 5,208 QPS
- DB QPS = 5,787 - 5,208 ≈ 579 QPS
Number of servers needed at peak:
- Assuming 10,000 QPS per server (typical for a high-throughput pub/sub backend)
- Servers needed = 5,787 / 10,000 ≈ 1 server (assuming horizontal scaling with sharding)
SLA targets
- P50 latency: < 10ms (critical path)
- P95 latency: < 50ms
- P99 latency: < 200ms
- Availability: 99.9% (3.6 minutes of downtime/month)
- Durability: At least 2x replication with 100% message persistence
- Consistency: At-least-once delivery guarantee
Key architectural decisions summary
- Use of Apache Kafka or Amazon MSK for message streaming and persistence
- Horizontal sharding of topics across multiple brokers to scale throughput
- Event-driven microservices for publishers and subscribers with asynchronous processing
- Multi-region deployment for global availability and low latency
- Stateless services with distributed caching (Redis) for fast message retrieval and metadata access
- Event schema registry to enforce versioning and compatibility
- Circuit breaker and retry patterns for resilience
- Monitoring and alerting stack using Prometheus, Grafana, and Datadog for observability
- Zero-downtime deployment using canary rollouts and feature flags
2. System Goals & Non-Functional Requirements
Latency Targets
- p50: 50ms for message publishing and delivery
- p95: 200ms for message publishing and delivery
- p99: 1s for message publishing and delivery
- End-to-end latency: 5s maximum for guaranteed delivery with retries
Throughput Requirements
- Average QPS: 100,000 messages/sec (assuming 1KB average message size)
- Peak QPS: 1,000,000 messages/sec (10x average)
- Peak burst capacity: 5M messages/sec for 5-second window
- Storage throughput: 100MB/s write, 500MB/s read for event store
Availability Target
- 99.9% (3 nines) availability for core publish-subscribe functionality
- 99.99% (4 nines) availability for mission-critical topics and services
- RTO: 5 minutes for service recovery
- RPO: < 1 minute for message durability
Durability and Consistency Requirements
- Consistency model: Eventual consistency for message delivery (eventual consistency is acceptable for most use cases, but critical topics may require stronger guarantees)
- Durability: Messages persisted to at least 3 availability zones with replication
- CAP trade-off: Prioritize availability and partition tolerance over consistency (CP trade-off is acceptable for most use cases)
- Message ordering: Per-partition ordering guarantee (not global)
Data Retention and Compliance Requirements
- Message retention: 30 days for standard topics, 90 days for compliance topics
- Compliance: GDPR/CCPA compliance with data subject rights and deletion capabilities
- Audit logging: Full audit trail for all message operations (publish, subscribe, delete)
- Data classification: Support for sensitive data classification and handling
Security and Regulatory Requirements
- Authentication: OAuth2/OIDC with JWT tokens for service-to-service authentication
- Authorization: RBAC model with topic-level permissions and role-based access control
- Encryption: TLS 1.3 for all network communication, at-rest encryption with AES-256
- Compliance: SOC2 Type II, HIPAA compliance for healthcare data, GDPR compliance for EU users
- Audit: Real-time audit logging with external compliance reporting capabilities
3. High-Level Architecture Diagram
C4Context
title Publish-Subscribe System - Context Diagram
Person(user, "End User")
Person(publisher, "Event Publisher")
Person(consumer, "Event Consumer")
System_Boundary(b1, "Publish-Subscribe System") {
System(pubsub, "Event Broker", "Kafka / Pulsar / SQS")
System(api, "API Gateway", "AWS API Gateway / Kong")
System(auth, "Auth Service", "OAuth2 / OIDC")
System(producer, "Producer Service", "Event Producer")
System(consumer_service, "Consumer Service", "Event Consumer")
System(cache, "Cache Layer", "Redis / Memcached")
System(db, "Database", "PostgreSQL / MySQL")
System(logging, "Logging Stack", "ELK / Loki")
System(tracing, "Tracing", "Jaeger / Zipkin")
System(metrics, "Metrics", "Prometheus + Grafana")
}
Rel(user, api, "Submits events via API")
Rel(publisher, pubsub, "Publishes events to")
Rel(consumer, pubsub, "Consumes events from")
Rel(api, producer, "Routes to Producer")
Rel(api, consumer_service, "Routes to Consumer")
Rel(producer, pubsub, "Publishes to Broker")
Rel(consumer_service, pubsub, "Consumes from Broker")
Rel(pubsub, cache, "Caches metadata")
Rel(pubsub, db, "Stores state")
Rel(pubsub, logging, "Logs events")
Rel(pubsub, tracing, "Traces events")
Rel(pubsub, metrics, "Exports metrics")
UpdateLayoutConfig($c4ShapeInRow = 3, $c4BoundaryInRow = 1)
C4Container
title Publish-Subscribe System - Container Diagram
Container_Boundary(c1, "Event Broker Layer") {
Container(kafka, "Kafka Cluster", "Apache Kafka", "Handles event streaming and persistence")
Container(schema_registry, "Schema Registry", "Confluent Schema Registry", "Manages event schemas")
Container(kafka_ui, "Kafka UI", "Kafka Manager / kafkactl", "Admin interface for Kafka")
}
Container_Boundary(c2, "Service Layer") {
Container(producer_service, "Producer Service", "gRPC/REST API", "Handles event publishing")
Container(consumer_service, "Consumer Service", "gRPC/REST API", "Handles event consumption")
Container(auth_service, "Auth Service", "OAuth2/OIDC", "Handles authentication and authorization")
Container(api_gateway, "API Gateway", "AWS API Gateway", "Routes requests to services")
}
Container_Boundary(c3, "Data Layer") {
Container(cache, "Cache", "Redis", "Caches metadata and recent events")
Container(db, "Database", "PostgreSQL", "Stores event metadata and consumer state")
Container(object_store, "Object Store", "S3 / GCS", "Stores event payloads")
}
Container_Boundary(c4, "Monitoring & Observability") {
Container(logging, "Logging", "ELK Stack", "Collects and analyzes logs")
Container(tracing, "Tracing", "Jaeger", "Distributed tracing")
Container(metrics, "Metrics", "Prometheus + Grafana", "Monitoring and alerting")
}
Rel(kafka, schema_registry, "Validates schemas")
Rel(producer_service, kafka, "Publishes events to")
Rel(consumer_service, kafka, "Consumes events from")
Rel(api_gateway, producer_service, "Routes to Producer")
Rel(api_gateway, consumer_service, "Routes to Consumer")
Rel(kafka, cache, "Caches metadata")
Rel(kafka, db, "Stores state and consumer offsets")
Rel(kafka, object_store, "Stores payloads")
Rel(kafka, logging, "Logs events")
Rel(kafka, tracing, "Traces events")
Rel(kafka, metrics, "Exports metrics")
Rel(auth_service, api_gateway, "Authenticates requests")
UpdateLayoutConfig($c4ShapeInRow = 3, $c4BoundaryInRow = 1)
Major Components and Data Flow
System Components:
- Event Broker: Apache Kafka or Amazon SQS/SNS for message queuing and streaming
- API Gateway: Routes requests to appropriate services (AWS API Gateway or Kong)
- Producer Service: Service that publishes events to the broker
- Consumer Service: Service that consumes events from the broker
- Auth Service: Handles authentication and authorization (OAuth2/OIDC)
- Cache Layer: Redis for caching metadata and recent events
- Database: PostgreSQL for storing event metadata, consumer state, and schemas
- Object Store: S3/GCS for storing large event payloads
- Monitoring Stack: ELK stack, Jaeger, Prometheus/Grafana
Data Flow:
- End users or external systems publish events via API Gateway to Producer Service
- Producer Service publishes events to Event Broker (Kafka/SQS)
- Events are persisted in the broker with schema validation
- Consumer Service subscribes to events from the broker
- Events are processed and stored in database or object store as needed
- Monitoring systems collect logs, traces, and metrics for observability
External Integrations:
- Authentication providers (Auth0, Okta, Cognito)
- Cloud storage services (S3, GCS, Azure Blob Storage)
- Monitoring and logging platforms (Datadog, CloudWatch, ELK stack)
Traffic Flow:
- Publish traffic flows from API Gateway → Producer Service → Event Broker
- Subscribe traffic flows from API Gateway → Consumer Service → Event Broker
- Metadata and state traffic flows between Event Broker, Cache, and Database
- Observability traffic flows from Event Broker to Logging, Tracing, and Metrics systems
4. Service Architecture
Microservices vs. Monolith vs. Modular Monolith Decision
For a publish-subscribe system, we'll adopt a modular monolith approach as the initial architecture pattern. This decision balances the need for clear service boundaries with operational simplicity during early development phases. The modular monolith allows us to:
- Rapidly iterate on features without complex inter-service communication overhead
- Maintain strong consistency for core publish-subscribe operations
- Simplify debugging and local development experience
- Gradually extract services as traffic patterns become clearer
As the system scales, we'll transition to a microservices architecture with clear service boundaries for specific domains.
Service Decomposition Strategy
We'll decompose the system into the following core services:
- Event Publisher Service - Handles event publishing, validation, and routing
- Event Subscriber Service - Manages subscription lifecycle, delivery, and retry logic
- Event Store Service - Provides durable storage for events with metadata
- Topic Management Service - Handles topic creation, configuration, and lifecycle
- Subscription Management Service - Manages subscription policies, filters, and routing rules
- Metrics & Monitoring Service - Aggregates system metrics and generates alerts
Service boundaries will be defined by domain cohesion:
- Publisher/Subscriber logic (cohesive business logic)
- Event storage and retrieval (data persistence)
- Topic and subscription lifecycle management (configuration)
- Observability and monitoring (cross-cutting concerns)
Service Boundaries and Contracts
Each service will expose a gRPC interface for internal communication with clear protobuf definitions:
// EventPublisherService
rpc PublishEvent(PublishRequest) returns (PublishResponse);
rpc ValidateEvent(ValidateRequest) returns (ValidateResponse);
// EventSubscriberService
rpc Subscribe(SubscribeRequest) returns (SubscribeResponse);
rpc Acknowledge(AcknowledgeRequest) returns (AcknowledgeResponse);
// TopicManagementService
rpc CreateTopic(CreateTopicRequest) returns (CreateTopicResponse);
rpc ListTopics(ListTopicsRequest) returns (ListTopicsResponse);
Services will communicate via:
- gRPC for synchronous, high-throughput operations
- Message queues for asynchronous, fire-and-forget operations
- Events for cross-service notifications and state propagation
Inter-Service Communication Pattern
Synchronous Communication:
- Publisher → Topic Manager (for topic validation)
- Subscriber → Event Store (for event retrieval)
- Publisher → Subscriber (for direct delivery in high-priority cases)
Asynchronous Communication:
- All service-to-service notifications via message queues
- Event store → Metrics service (for system telemetry)
- Topic manager → Subscription manager (for topic deletion notifications)
Service Mesh Consideration
We'll implement Istio as our service mesh for:
- Traffic management (canary deployments, A/B testing)
- Security (mTLS, access control policies)
- Observability (distributed tracing, metrics collection)
- Resilience (circuit breakers, retry policies)
Service mesh will be enabled for all services but configured with minimal overhead for core publish-subscribe operations.
Service Registry and Discovery Strategy
We'll use Consul for service discovery with the following approach:
- Service Registration: Each service registers itself with Consul on startup
- Health Checks: Services report health every 5 seconds to Consul
- Service Mesh Integration: Istio will leverage Consul for service discovery
- Dynamic Configuration: Service configurations will be managed via Consul KV store
Service discovery will support:
- Round-robin load balancing for service instances
- Failover handling with automatic redirection to healthy instances
- Service versioning to support gradual rollouts
The registry will maintain service metadata including:
- Service name and version
- Health status and availability zones
- Load balancing weights for traffic distribution
- Security policies and access control information
This service architecture provides a solid foundation for building a scalable, maintainable publish-subscribe system that can evolve from modular monolith to microservices as requirements grow.
5. Data Architecture
Database Selection per Service
Event Store Service (Primary Publisher/Subscriber Store)
- Selection: Apache Kafka with Schema Registry
- Justification:
- High throughput for event publishing/subscribing (100K+ events/sec)
- Strong durability guarantees with replication
- Built-in partitioning and horizontal scaling capability
- Rich ecosystem for stream processing (Kafka Streams, Flink)
- Schema evolution support with Confluent Schema Registry
Metadata Service (Event and Subscription Metadata)
- Selection: PostgreSQL 15
- Justification:
- Strong consistency requirements for subscription metadata, topic configurations
- Complex queries for subscription management and filtering
- ACID compliance needed for transactional operations (e.g., topic creation with ACLs)
- Mature ecosystem and tooling for RDBMS operations
Cache Service (In-memory event caching)
- Selection: Redis 7.x
- Justification:
- Low latency (sub-millisecond) for hot event data access
- Pub/Sub capabilities for real-time message distribution to subscribers
- Rich data structures (lists, sets, hashes) for caching strategies
- Built-in persistence and replication options
Metrics Service (Event processing metrics)
- Selection: TimescaleDB (PostgreSQL extension)
- Justification:
- Time-series data modeling for event processing metrics (latency, throughput)
- Efficient querying of temporal data patterns
- Horizontal scaling through hypertables and partitioning
- Integration with Prometheus for monitoring stack
Data Partitioning Strategy
Kafka Topics (Event Store)
- Partitioning Method: Hash-based sharding on key field (e.g., topic ID, user ID)
- Justification:
- Ensures consistent distribution of events across partitions
- Enables parallel processing and scaling of consumers
- Allows for topic-level ordering guarantees within partitions
- Supports horizontal sharding with predictable scaling
PostgreSQL Metadata Tables
- Partitioning Method: Range-based on topic ID or subscription ID
- Justification:
- Allows for efficient querying of topics/subscriptions by ID ranges
- Enables horizontal partitioning across multiple database instances
- Supports read-heavy workloads with proper indexing strategy
Data Replication Strategy
Kafka Cluster
- Replication: 3x replication factor per partition
- Strategy: Multi-zone replication with cross-region sync
- Justification:
- Ensures high availability and fault tolerance (2 node failures tolerable)
- Supports active-active multi-region deployment for disaster recovery
- Maintains data consistency with quorum-based writes
PostgreSQL Metadata
- Replication: Primary-replica (1:1) with automatic failover
- Strategy: Read replicas for read-heavy metadata queries, write to primary only
- Justification:
- Maintains consistency for transactional operations
- Enables horizontal scaling of read queries
- Supports point-in-time recovery and backup strategies
Cross-Service Data Ownership
No Shared Databases Rule
- Enforcement Strategy:
- Each service owns its data stores (Kafka, PostgreSQL, Redis)
- Service boundaries enforced through API contracts and database permissions
- Data replication handled via Kafka streams or service-to-service consumers
- Audit logs for data access and modification (via database triggers)
CQRS Pattern Application
Event Store Service
- Usage: Read-side optimized for event consumption
- Justification: Separate read and write models to handle high-concurrency publishing vs. low-latency consumption
Metadata Service
- Usage: Write-side for managing topic and subscription state
- Justification: Complex write operations (e.g., creating subscriptions, updating ACLs) require strong consistency
Event Sourcing Consideration
Not Applied
- Reasoning:
- Events are immutable and durable in Kafka (natural event store)
- Complex state reconstruction not required for typical use cases
- Simpler architecture without event sourcing complexity
- Kafka's built-in retention and replay capabilities meet requirements
Object Storage Design
Not Applicable
- Rationale: The system focuses on event streaming and messaging, not file/media storage
Storage Tiering Strategy
Hot Tier (Kafka Events)
- Storage: SSD-backed Kafka clusters with 3x replication
- Access Pattern: High-frequency reads/writes for active topics
- Justification: Low latency requirement for real-time event processing
Warm Tier (Metadata)
- Storage: Standard SSDs with read replicas
- Access Pattern: Moderate frequency for metadata queries and updates
- Justification: Balance between cost and performance for non-critical data
Cold Tier (Archived Events)
- Storage: S3-compatible object storage with lifecycle policies
- Access Pattern: Low frequency, long-term archival (e.g., 30+ days retention)
- Justification: Cost-effective storage for compliance and historical analysis
Backup and Restore Strategy
Kafka Backups
- RTO: < 5 minutes (with replication)
- RPO: < 1 hour (with retention policies)
- Strategy: Regular snapshots and log compaction backups
PostgreSQL Metadata
- RTO: < 15 minutes (with point-in-time recovery)
- RPO: < 5 minutes (with WAL-based replication)
- Strategy: Scheduled logical backups with automated restore testing
Redis Cache
- RTO: < 1 minute (with Redis persistence)
- RPO: < 5 minutes (with Redis replication)
- Strategy: Periodic RDB snapshots and AOF persistence
Cross-Region Disaster Recovery
- Strategy: Multi-region Kafka clusters with cross-region replication
- RTO/RPO: < 1 hour for full system recovery
- Testing: Monthly DR drills with automated failover simulation
6. Caching Architecture
Caching Layers Overview
The caching strategy follows a multi-tier architecture to optimize performance and reduce database load:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Client Cache │ │ CDN / Edge │ │ API Gateway │ │ Application │
│ (L1) │ │ (L2) │ │ (L3) │ │ (L4) │
└─────────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │ │
└───────────────────────┼───────────────────────┼───────────────────────┘
│ │
┌─────────────────┐ ┌─────────────────┐
│ Redis Cluster │ │ Database │
│ (L5) │ │ (L6) │
└─────────────────┘ └─────────────────┘
Cache Layers Design
L1 - Client-side Caching (Browser/SDK Level)
- Implementation: HTTP cache headers (ETag, Cache-Control)
- Size: 10MB per user session
- Strategy: Time-based expiration with cache validation
- Use case: Reduces redundant requests for static content and frequently accessed data
L2 - CDN Edge Caching
- Implementation: CloudFront/S3 Origin Shield with Redis fallback
- Size: 100GB per region (shared across all users)
- Strategy: Content-based TTL with cache warming
- Use case: Reduces latency for globally distributed users and handles burst traffic
L3 - API Gateway Caching
- Implementation: Redis-backed cache at API gateway level
- Size: 50GB per instance (3 instances = 150GB)
- Strategy: TTL-based with cache invalidation on publish
- Use case: Reduces API gateway processing and database hits for repeated subscriptions
L4 - Application Layer Caching
- Implementation: In-memory cache (Caffeine) with Redis fallback
- Size: 2GB per application instance (5 instances = 10GB)
- Strategy: LRU eviction with cache warming for hot topics
- Use case: Reduces application-level database queries and improves response times
L5 - Distributed Cache (Redis Cluster)
- Implementation: Redis Cluster with 3 masters, 3 replicas per shard
- Size: 50GB per shard (3 shards = 150GB total)
- Strategy: Cache-Aside pattern with optimistic locking for consistency
- Use case: Shared cache across services and persistence of publish-subscribe state
L6 - Database Layer
- Implementation: PostgreSQL with query result caching
- Size: 100GB per database instance (2 instances = 200GB)
- Strategy: Query result caching with invalidation on write operations
- Use case: Secondary cache for complex query results and data consistency
Cache Sizing Strategy
Based on back-of-envelope calculations:
- Peak QPS: 10,000 (assuming 10x peak-to-average ratio)
- Average response size: 5KB
- Cache hit rate target: 80% (reducing DB QPS from 10,000 to 2,000)
- Cache size requirement: 50GB (estimated based on 80% hit rate and 10ms target latency)
Cache Invalidation Strategy
- Publish-based invalidation: When a message is published, invalidate cache entries for related topics
- TTL-based invalidation: Automatic expiration of cached entries after configurable time (5-15 minutes)
- Cache warming: Pre-populate cache with hot topics during system startup and traffic spikes
- Consistency model: Eventual consistency with cache invalidation on write operations
Cache Warmup Strategy
- Startup warmup: Load hot topics from database into cache on service startup
- Traffic-based warming: Monitor traffic patterns and warm cache for trending topics
- Pre-warming: Use historical data to pre-populate cache for expected traffic patterns
Cache Performance Targets
- L1/L2: 95% hit rate with <5ms latency
- L3/L4: 85% hit rate with <10ms latency
- L5: 80% hit rate with <20ms latency
- Overall system: 90% cache hit rate with <15ms average response time
Cache Consistency Considerations
- Cache consistency model: Eventual consistency with cache invalidation on publish
- Read consistency: Strong consistency for subscription state, eventual consistency for message content
- Cache coherency: Use cache invalidation patterns to ensure consistency across services
- Cross-service cache: Implement cache sharing for common topics between services
Cache Monitoring and Metrics
- Cache hit ratio per layer
- Cache miss ratio per layer
- Cache latency distribution
- Cache size utilization
- Cache invalidation frequency
- Cache warming success rate
Cache Failure Handling
- Cache miss: Fall back to database with circuit breaker pattern
- Cache unavailability: Fail gracefully with stale data or timeout
- Cache warming failure: Retry warmup on next traffic spike or scheduled maintenance window
- Consistency violations: Implement cache validation and re-sync mechanisms
7. Messaging & Event Streaming Architecture
Message Broker Selection
For a publish-subscribe system, we'll select Apache Kafka as our primary message broker due to:
- High throughput: Kafka can handle millions of messages per second with low latency
- Durability guarantees: Messages are persisted to disk and replicated across brokers
- Scalable architecture: Horizontal scaling through partitioning and consumer groups
- Rich ecosystem: Strong tooling for monitoring, management, and integration
- Stream processing capabilities: Native support for KSQL and Kafka Streams for real-time processing
Alternative considered: Amazon MSK (managed Kafka) - but we're designing a self-contained system with minimal external dependencies.
Event Schema Registry and Versioning
We'll implement a Confluent Schema Registry to manage event schemas with:
- Backward compatibility checks: Ensures new schema versions don't break existing consumers
- Versioning strategy: Semantic versioning (v1.0.0, v1.1.0) with automatic migration paths
- Schema evolution: Support for adding optional fields, changing field types (with constraints)
- Validation at publish time: Messages must pass schema validation before being published
Topic Partitioning and Consumer Group Design
Partitioning Strategy:
- Hash-based partitioning: Messages are routed to partitions based on a hash of the key field (e.g., user_id, event_type)
- Partition count: Start with 128 partitions per topic (scalable to 1024+ as needed)
- Replication factor: 3 (ensuring fault tolerance across 3 brokers)
Consumer Group Design:
- Partition assignment: Kafka's built-in range and round-robin assignment strategies
- Consumer lag monitoring: Real-time tracking of consumer lag with alerting thresholds (5min+)
- Graceful rebalancing: Configured with appropriate session timeouts and heartbeat intervals
Event Ordering Guarantees
Per-partition ordering:
- Messages within the same partition maintain strict ordering
- Different partitions can be processed in parallel, enabling horizontal scaling
Global ordering guarantees:
- Not required for most use cases; if needed, implement a single partition or use Kafka's global ordering features
Exactly-once vs. At-least-once Processing Trade-offs
Decision: At-least-once processing with idempotent consumers for most use cases, with exactly-once where critical:
- At-least-once: Default processing model - consumers process messages multiple times but ensure no data loss
- Exactly-once: Implemented for critical financial or inventory events using Kafka's idempotent producer features and transactional APIs
- Idempotent consumer pattern: Consumers maintain state to handle duplicate messages gracefully
Event Replay and Reprocessing Strategy
- Event retention policy: 7 days of message retention (configurable per topic)
- Replay capability: API endpoints to replay events from specific timestamps or offsets
- Event versioning: Versioned event schemas enable safe reprocessing of older message formats
- Reprocessing dashboard: UI to trigger and monitor event replay operations
Dead Letter Queue and Poison Pill Handling
Dead Letter Queue (DLQ) Strategy:
- Automatic DLQ routing: Failed messages after max retries are automatically sent to a dedicated DLQ topic
- Poison pill handling: Messages that consistently fail processing are moved to DLQ with metadata about failure reasons
- DLQ monitoring: Alerting on DLQ message volume and error types to identify systemic issues
- DLQ reprocessing: Manual or automated retry capability for DLQ messages after root cause fixes
Failure Handling:
- Retry configuration: 3 attempts with exponential backoff (1s, 2s, 4s)
- Dead letter topic:
myapp.events.failedfor failed messages - Error logging: Detailed error context stored in message headers for debugging
Message Format and Serialization
- JSON format: Human-readable, schema-compatible for most use cases
- Protocol Buffers: For high-performance services requiring binary serialization
- Content-type headers: Metadata to indicate message format and version
- Compression: GZIP compression for large payloads (configurable per topic)
Cross-Service Event Delivery
Event-driven architecture pattern:
- Synchronous vs. asynchronous: Most events are published asynchronously to enable loose coupling
- Event-driven microservices: Services consume events rather than direct API calls
- Event sourcing: Critical business events are stored as immutable records for audit and replay capability
Cross-service communication:
- Event bus: Centralized event routing through Kafka topics
- Service-to-service events: Events are published to specific topics for targeted consumers
- Event filtering: Consumers can filter messages by event type, user_id, or other criteria
Monitoring and Management
- Kafka monitoring: Prometheus metrics integration with Grafana dashboards
- Consumer lag alerts: Threshold-based alerts for consumer lag exceeding 5 minutes
- Broker health checks: Real-time monitoring of broker availability and performance metrics
- Topic management: Automated topic creation with default configurations and retention policies
Performance Optimization
- Batching: Producer batching to reduce network overhead
- Compression: Configurable compression levels for different message types
- Partitioning strategy optimization: Key-based partitioning to ensure even distribution
- Consumer parallelism: Configurable consumer thread counts per topic
Data Retention and Lifecycle Management
- Retention policies: Configurable retention (7 days default, configurable per topic)
- Archival strategy: For compliance or long-term storage, events can be archived to object storage (S3/GCS)
- Topic lifecycle: Automated topic creation, maintenance, and cleanup based on usage patterns
- Storage efficiency: Compaction for key-based topics to maintain latest values per key
8. Reliability Engineering
Failure Mode Analysis
Single Points of Failure:
- Message Broker (Kafka): Centralized event streaming system with no built-in redundancy for metadata
- API Gateway: Single point for all incoming requests and rate limiting
- Service Registry (Consul/Eureka): If unavailable, services can't discover each other
- Authentication Service: Blocks all service-to-service communication if unavailable
- Primary Database: Single source of truth for critical data with no automatic failover
Service-Level Failures:
- Producer Service: Can cause message loss or duplicate messages if not properly idempotent
- Consumer Services: Can experience data loss or processing delays due to network issues or timeouts
- Event Store: Can become a bottleneck during peak load or fail during maintenance
Fault Tolerance Patterns
Circuit Breaker Pattern:
- Applied to all inter-service communication (e.g., consumer service calling producer)
- Implemented using Hystrix or Resilience4j for automatic failure detection and recovery
- Configured with timeout thresholds (500ms), failure rate thresholds (50%), and reset timeouts (30s)
Bulkhead Pattern:
- Isolated consumer pools per topic to prevent cascading failures
- Configured with thread pool limits (max 100 concurrent consumers per topic)
- Prevents one slow consumer from blocking all others
Timeout & Retry Strategy:
- Producer: 300ms timeout for publishing to Kafka, 3 retries with exponential backoff (1s, 2s, 4s)
- Consumer: 500ms timeout for processing messages, 2 retries with jittered exponential backoff
- Service Discovery: 100ms timeout for registry lookups, 2 retries with linear backoff
Multi-Region / Multi-AZ Strategy
Active-Active Architecture:
- Deployed across 3 AWS regions (us-east-1, us-west-2, eu-west-1) for high availability
- Each region has independent Kafka clusters with cross-region replication
- Services are deployed in all regions with automatic failover to healthy region
Cross-Region Event Replication:
- Use Kafka MirrorMaker 2.0 for cross-region replication of events
- Maintain event ordering within each region using partitioning strategy
- Implement region-aware consumer groups to avoid duplicate processing
Chaos Engineering Strategy
GameDays:
- Weekly 2-hour GameDay sessions to test system resilience
- Simulate network partitions, service outages, and database failures
- Validate circuit breaker behavior and consumer recovery patterns
Chaos Monkey:
- Random service termination (5% of services daily)
- Network latency injection (200-500ms random delays)
- Database connection pool exhaustion simulation
Steady-State Hypothesis:
- System remains available under normal conditions (99.9% uptime)
- Event processing continues with no data loss during failures
- All services maintain consistent state after failure recovery
Disaster Recovery Plan
RTO/RPO Targets:
- RTO: 15 minutes for service recovery (including failover to secondary region)
- RPO: 5 seconds for event data loss (using Kafka's durability settings)
Recovery Procedures:
- Service Outage: Auto-failover to secondary region with manual intervention for service restart
- Kafka Cluster Failure: Failover to cross-region replica with consumer reconfiguration
- Data Loss: Restore from point-in-time backups with event replay from last known good state
Runbook Design
Top-5 Failure Scenarios:
| Failure | Impact | Recovery Steps |
|---|---|---|
| Kafka Cluster Outage | Event processing halts, consumers blocked | Failover to secondary region, reconfigure consumer groups |
| Service Discovery Failure | Services cannot communicate | Restart registry service, validate DNS resolution |
| Authentication Service Down | All service-to-service calls blocked | Use cached JWT tokens, enable fallback authentication |
| Consumer Processing Timeout | Message processing delays | Increase consumer thread pool, optimize processing logic |
| Network Partition | Services isolated in different regions | Re-establish cross-region connectivity, validate replication |
Runbook Automation:
- Predefined scripts for common recovery actions (e.g., Kafka failover, service restart)
- Integration with PagerDuty for alert escalation and runbook triggering
- Automated health checks to validate recovery success before alert resolution
9. Observability Architecture
Logging Stack
The system will implement a structured logging approach using JSON format for all service logs to enable programmatic parsing and analysis. Logs will be collected through a centralized logging solution like Loki (for open-source) or CloudWatch (for AWS) with multi-tenant support for different services. Each log entry will include trace context, service name, timestamp, log level, and relevant contextual metadata. Log retention policies will be set to 90 days for operational logs with audit logs retained for 7 years.
Distributed Tracing
Distributed tracing will be implemented using OpenTelemetry (OTel) with Jaeger as the backend for trace visualization. All services will instrument their code to emit trace spans, with automatic instrumentation for HTTP and database calls. The tracing system will capture end-to-end request flows across service boundaries, enabling root cause analysis of performance bottlenecks and error propagation. Trace sampling will be set to 10% for production to balance observability with performance overhead.
Metrics Stack
Prometheus will serve as the primary metrics backend, with Grafana for dashboard visualization. Key metrics will include:
- Service-level latency (p50, p95, p99)
- Error rates and error budgets
- Throughput (QPS) by service and topic
- Queue depths and processing rates
- Cache hit/miss ratios
- Database query latencies
Metrics will be collected at 15-second intervals with a 30-day retention window for operational dashboards and 1-year for historical trend analysis.
Alerting Strategy
The alerting system will implement a multi-tier severity model:
- Critical (P0): Service outages, SLA violations, security breaches - routed to on-call via PagerDuty with immediate escalation
- High (P1): High error rates, latency spikes >500ms - routed to engineering team with 15-minute escalation
- Medium (P2): Performance degradation, cache miss rates >30% - routed to team with 1-hour escalation
Alerts will be configured using Prometheus Alertmanager with proper grouping and inhibition rules to avoid alert fatigue. Each alert will include contextual information, impact assessment, and suggested remediation steps.
SLI/SLO Definition and Error Budget Tracking
SLIs will be defined for core system capabilities:
- Availability: (Total time - Downtime) / Total time
- Latency: p95 response time < 200ms for API endpoints, <500ms for background processing
- Throughput: 1000 QPS average with 2x peak capacity
SLOs will target 99.9% availability and 95th percentile latency under 200ms. Error budget will be calculated as (1 - SLO) * 100% and monitored in real-time. Dashboard will display remaining error budget with burn rate visualization to enable proactive risk management.
Capacity Planning and Load Forecasting
Capacity planning will utilize historical metrics and load patterns to predict resource requirements. The system will implement predictive analytics using machine learning models to forecast traffic spikes and automatically adjust resource allocation. Load forecasting will be performed at hourly intervals with 95% confidence bands to ensure adequate capacity for peak traffic scenarios. Auto-scaling triggers will be based on metrics-driven thresholds with 5-minute lookback windows to prevent over-scaling due to temporary spikes.
The observability stack will be deployed in a separate monitoring namespace with dedicated resources to ensure it doesn't impact the primary system performance. All observability components will be monitored with their own health checks and alerting to maintain system reliability.
10. API Gateway & Edge Layer
API Gateway Selection and Justification
For a publish-subscribe system, I recommend AWS API Gateway as the primary API gateway solution with the following rationale:
- Managed service benefits: Reduces operational overhead and provides built-in features like rate limiting, authentication, and request/response transformation
- Native integration with AWS services: Seamless integration with Lambda, SNS, SQS, and other AWS messaging services
- Advanced features: Supports request/response transformation, custom authentication, and comprehensive monitoring capabilities
- Scalability: Automatically scales to handle millions of requests per second with no configuration required
Alternative consideration: Kong for organizations preferring open-source solutions with more customization control, though it requires additional operational overhead.
Request Routing Strategy
The API gateway will implement a multi-tier routing strategy:
- Service-level routing: Route requests to appropriate microservices based on topic/subscription patterns
- Content-based routing: Use message headers to route to specific consumers or processing services
- Load balancing: Distribute requests across multiple service instances for high availability
Authentication and Authorization at Gateway Layer
Authentication:
- JWT-based authentication for client applications
- OAuth2/OIDC integration with AWS Cognito for federated identity
- mTLS support for service-to-service communication
Authorization:
- RBAC model with role-based access control
- Attribute-based access control for fine-grained permissions
- API key management with per-client rate limiting
Rate Limiting and Throttling Design
Global Rate Limiting:
- 10,000 requests/second per client for standard tier
- 50,000 requests/second for premium tier
Per-Client Limits:
- Configurable limits per client application
- Dynamic adjustment based on usage patterns and business rules
Throttling Mechanism:
- Token bucket algorithm for burst handling
- Immediate rejection of requests exceeding limits with 429 status codes
Request Transformation and Protocol Translation
Protocol Translation:
- HTTP to WebSocket for real-time pub/sub communications
- REST to gRPC for internal service communication
Request/Response Transformation:
- Schema validation and transformation using JSON Schema
- Field projection and filtering for performance optimization
- Content negotiation for different response formats (JSON, XML, Protobuf)
BFF (Backend for Frontend) Design
For client-facing applications, we'll implement a BFF pattern:
Mobile Clients:
- Transform complex event streams into optimized JSON payloads
- Handle client-specific data transformations and filtering
Web Applications:
- Implement WebSocket connections for real-time event delivery
- Cache frequently accessed subscription metadata
- Provide unified API endpoints that aggregate data from multiple services
BFF Responsibilities:
- Client-specific event filtering and transformation
- Session management and caching for improved performance
- Protocol adaptation between client and backend services
Security Considerations at Edge Layer
TLS Termination:
- End-to-end encryption with TLS 1.3 support
- Certificate management through AWS ACM or custom certificate stores
Security Headers:
- Implement security headers (Content-Security-Policy, X-Frame-Options)
- Rate limiting and DDoS protection integration
Request Validation:
- Input sanitization and validation
- Request size limiting to prevent resource exhaustion
- Payload compression for bandwidth optimization
Performance Optimization Strategies
Caching at Edge Layer:
- Response caching for frequently accessed subscription metadata
- CDN integration for static content distribution
Connection Management:
- WebSocket connection pooling for real-time event delivery
- HTTP/2 support for multiplexed request handling
Traffic Management:
- Traffic splitting for canary deployments
- Circuit breaker patterns to prevent cascading failures
Integration with Messaging System
The API gateway will integrate directly with the event streaming layer:
- Publish endpoint: Accepts messages and forwards to SNS/SQS
- Subscribe endpoint: Manages WebSocket connections for real-time delivery
- Subscription management: Handles subscription creation, updates, and deletion
- Event routing: Maps topics to appropriate consumer services based on subscription filters
Monitoring and Observability Integration
Built-in Metrics:
- Request/response latency, error rates, and throughput
- Authentication/authorization success/failure rates
- Rate limiting and throttling statistics
Integration with Observability Stack:
- Forward logs to CloudWatch/ELK for centralized logging
- Export metrics to Prometheus/Grafana for dashboarding
- Distributed tracing integration with AWS X-Ray
Scalability Considerations
Horizontal Scaling:
- Auto-scaling based on request volume and latency metrics
- Multi-AZ deployment for high availability
Capacity Planning:
- Predictive scaling based on historical usage patterns
- Alerting thresholds for capacity planning and proactive scaling
This edge layer design provides a robust, scalable foundation that handles authentication, authorization, rate limiting, and protocol translation while maintaining the flexibility to evolve with changing requirements.
11. Authentication & Authorization Architecture
Identity Provider Integration
The system will integrate with AWS Cognito as the primary identity provider due to its seamless integration with AWS services, built-in support for federated identities, and robust user pool management capabilities. Cognito provides comprehensive authentication flows including username/password, SAML, OAuth2, and social login providers. For enterprise customers requiring custom authentication logic, a custom IdP integration will be supported via SAML 2.0 federation.
OAuth2 / OIDC Flow Design
sequenceDiagram
participant Client
participant AuthN
participant Cognito
participant Service
Client->>AuthN: Request authentication
AuthN->>Cognito: Redirect to Cognito login
Cognito-->>Client: Login page
Client->>Cognito: User authenticates
Cognito->>AuthN: Return JWT token
AuthN->>Service: Forward request with JWT
Service->>Service: Validate JWT signature and claims
Service-->>AuthN: Response
AuthN-->>Client: Response with auth context
The system implements the Authorization Code flow with PKCE for public clients and Client Credentials flow for service-to-service authentication. JWT tokens will be signed using RS256 algorithm with 1-hour expiration times, with refresh tokens enabled for long-lived sessions.
Service-to-Service Authentication
For service-to-service communication, the system will implement mTLS with SPIFFE/SPIRE for secure identity management. Each service will have a unique SPIFFE ID that is validated at the transport layer. Additionally, service accounts with scoped permissions will be used for cross-service operations, with token rotation every 24 hours.
RBAC / ABAC Model Design
The system will implement a hybrid RBAC/ABAC model:
- Role-Based Access Control (RBAC) for standard user permissions with predefined roles (admin, publisher, subscriber, reader)
- Attribute-Based Access Control (ABAC) for fine-grained permissions based on user attributes, resource properties, and environmental conditions
The RBAC model will support hierarchical role inheritance where admin roles inherit publisher permissions, which in turn inherit subscriber permissions. ABAC will be used for dynamic policies like "publishers can only publish to topics they own" or "subscribers can only consume from topics in their organization."
Token Revocation Strategy
The system will implement a hybrid token revocation strategy:
- Short-lived JWT tokens (1 hour) with refresh token rotation to minimize impact of compromised tokens
- Blacklist-based revocation for immediate token invalidation in case of security incidents or user logout
- Refresh token rotation where each refresh request generates a new refresh token, invalidating the previous one
- Token validation service that checks revocation status for all incoming tokens before processing
The token validation will be implemented as a middleware layer that checks the revocation status against a distributed cache (Redis) before allowing service requests to proceed. This ensures that even if a token is compromised, it becomes invalid within 5 minutes of revocation.
12. Search Architecture
Search Use Cases and Requirements
The publish-subscribe system includes a search capability for event content, metadata, and topic discovery. This feature enables users to find relevant events by content, tags, or topics without needing to subscribe to all channels.
Search Indexing Pipeline
The search indexing pipeline follows a multi-stage process:
- Event Ingestion: Events are published to the message broker and consumed by search indexer service
- Content Extraction: Text content, metadata fields, and tags are extracted from event payloads
- Index Transformation: Content is normalized, tokenized, and enriched with additional fields (e.g., timestamps, user IDs)
- Indexing: Transformed content is indexed into the search engine with appropriate field mappings
Search Engine Selection
Elasticsearch is selected as the primary search engine due to:
- Excellent full-text search capabilities with relevance scoring
- Rich query DSL for complex search patterns (fuzzy matching, range queries)
- Strong ecosystem integration with Kibana for visualization
- Horizontal scalability and distributed architecture
- Mature support for real-time indexing and search
Index Schema Design
Search indexes are designed with the following key fields:
- event_id: Unique identifier for deduplication
- topic: Topic name for category filtering
- content: Full-text searchable content field
- timestamp: Event timestamp for time-range queries
- tags: Array of tags for multi-value filtering
- user_id: User identifier for personalization
- metadata: JSON field for arbitrary key-value search attributes
Query Patterns and Performance
Primary query patterns include:
- Full-text search: Content-based searching with fuzzy matching
- Tag filtering: Multi-value tag-based filtering
- Time-range queries: Temporal filtering for recent events
- User-specific search: Events related to specific users
Search performance is optimized through:
- Index field mapping with appropriate data types (text, keyword, date)
- Query caching for frequently accessed search terms
- Sharding strategy across multiple index replicas
Real-time vs. Near-real-time Indexing
Near-real-time indexing is implemented with:
- Index refresh interval set to 1 second for acceptable latency
- Document-level indexing with batch processing for efficiency
- Background indexing workers that process events asynchronously from publish flow
Relevance Tuning Strategy
Relevance is tuned through:
- Field boosting: Prioritizing content over metadata fields
- Custom scoring functions: Weighting timestamp and tag relevance
- Query-time boosting: Dynamic adjustment based on user behavior
- A/B testing framework: For measuring impact of relevance changes
Search Scaling Design
Horizontal scaling is achieved through:
- Shard distribution: 3 shards per index with 2 replicas for redundancy
- Index lifecycle management: Automatic index rollover based on size/time thresholds
- Cross-cluster search: For multi-region search capability
- Search coordination: Load balancing across search nodes
Search Integration with Pub/Sub
Search service integrates with the pub/sub system through:
- Event-driven indexing: Search index updates triggered by event publication
- Search API endpoints: RESTful interfaces for search queries
- Real-time search results: Streaming search results to connected clients
- Search analytics: Tracking search queries and user engagement patterns
Search Result Presentation
Search results are presented with:
- Structured response format: Consistent JSON output including hits, total count, and facets
- Pagination support: For large result sets with cursor-based pagination
- Faceted search: Category and tag filtering capabilities
- Highlighting: Relevance-based content highlighting in search results
Search Performance Monitoring
Search performance is monitored through:
- Query latency metrics: p50, p95, p99 response times
- Indexing throughput: Events per second indexed
- Search hit ratio: Percentage of queries served from cache vs. disk
- Resource utilization: CPU, memory, and disk I/O metrics for search nodes
Search Data Retention
Search indexes follow the same retention policies as underlying event data:
- Index lifecycle management: Automatic index deletion after configured retention period
- Archival strategy: Historical search data moved to cold storage for compliance
- Search query logging: Audit trail of search activities for compliance requirements
13. Scalability Deep Dive
Bottleneck Identification Per Component
Message Broker (Kafka)
- Bottleneck: Producer throughput and consumer lag
- Calculation: With 100K QPS peak, assuming 1KB average message size → 100MB/s write throughput
- Scaling Path:
- Vertical: Increase broker instance size (from m5.large to m5.xlarge)
- Horizontal: Add more brokers to distribute partitions
- Optimization: Use compression (LZ4/zip) to reduce network overhead by ~30%
Database (PostgreSQL)
- Bottleneck: Write amplification from frequent metadata updates
- Calculation: 50K QPS → 50K writes/sec to metadata tables (topic, subscription, consumer offsets)
- Scaling Path:
- Read replicas: 3x read capacity for metadata queries
- Connection pooling: Reduce DB connection overhead by 60%
- Sharding: Horizontal partitioning of consumer offset tables
Service Layer (Event Publisher/Subscriber)
- Bottleneck: Memory pressure from concurrent subscription processing
- Calculation: 10K concurrent subscribers → 5GB memory usage (assuming 500KB per subscription)
- Scaling Path:
- Horizontal scaling: Auto-scaling groups with HPA based on queue depth
- Memory optimization: Use object pooling for event objects
Horizontal vs. Vertical Scaling Decisions
Message Broker (Kafka)
- Decision: Hybrid approach - vertical scaling for single-topic performance, horizontal for throughput
- Justification:
- Vertical: Higher memory/disk IOPS for single-topic high-throughput scenarios
- Horizontal: Distributes load across multiple brokers for multi-topic scaling
Database (PostgreSQL)
- Decision: Vertical scaling with read replicas for metadata, horizontal sharding for user data
- Justification:
- Vertical: Single DB instance handles metadata with high consistency needs
- Horizontal: User data partitioned by tenant ID for better distribution
Service Layer
- Decision: Pure horizontal scaling with stateless services
- Justification:
- Stateless services can scale independently based on QPS load
- No session affinity required, enabling efficient load balancing
Database Scaling Path
Phase 1: Single PostgreSQL instance with read replicas (3x) for metadata operations Phase 2: Connection pooling and query optimization (reduce 50% of DB QPS) Phase 3: Horizontal sharding of user data by tenant ID (partitioned tables or separate databases) Phase 4: Migration to distributed database (CockroachDB) for cross-tenant operations
Stateless vs. Stateful Service Design Implications
Stateless Services (Event Publishers, Subscribers)
- Advantages:
- Easy horizontal scaling
- Fault tolerance through replication
- No session affinity required
- Challenges:
- Need for external state management (Redis for caching, Kafka for ordering)
- Increased complexity in maintaining consumer offsets
Stateful Services (Message Broker, Metadata Store)
- Advantages:
- Built-in ordering guarantees and persistence
- Reduced external dependencies for core functionality
- Challenges:
- Complex scaling (need for leader election, replication)
- Higher operational overhead
Session Affinity and Its Implications
No session affinity required due to stateless design:
- All services maintain no local state
- Consumer offset tracking handled by Kafka and external cache
- Load balancer can distribute traffic evenly across service instances
Implications:
- Positive:
- Simplified scaling and deployment
- Better fault tolerance with automatic failover
- Negative:
- Need for external coordination mechanisms (Redis, Kafka)
- Slight increase in latency due to distributed state management
Performance Characteristics at Scale
Peak QPS Scaling:
- 100K QPS → 10x increase in message broker throughput
- 50K QPS → 2x increase in database read capacity (with replicas)
- 10K concurrent subscribers → 5x increase in service instances
Latency Impact:
- Message processing latency increases by 20% at peak load due to queuing and coordination overhead
- Database query latency increases by 15% due to read replica synchronization lag
Resource Utilization:
- CPU utilization: 70% peak (with proper HPA configuration)
- Memory usage: 2GB per service instance (optimized for stateless design)
- Network bandwidth: 100MB/s peak write, 200MB/s read (with compression)
14. Infrastructure & Deployment Architecture
Cloud Provider and Region Selection
For a global publish-subscribe system, we'll target AWS as the primary cloud provider due to its mature messaging services (SQS, SNS), robust global infrastructure, and extensive ecosystem integration. The system will be deployed across multiple regions (us-east-1, eu-west-1, ap-southeast-1) to ensure low-latency global distribution and fault tolerance.
Kubernetes Cluster Design
We'll implement a multi-tenant Kubernetes cluster model with:
- Namespace Strategy:
pubsub-systemfor core infrastructure servicespubsub-servicesfor application services (publisher, subscriber, broker)pubsub-monitoringfor observability stack
- Resource Quota Model:
- CPU and memory limits per namespace to prevent resource contention
- Pod disruption budgets (PDBs) set at 100% for critical services
- Cluster Topology:
- Multi-AZ deployment (3 zones per region) for high availability
- Dedicated node pools for different service types (control plane, data plane, monitoring)
- Cluster-autoscaler enabled with min/max node scaling policies
Container Image Strategy
Container images will follow a multi-stage build approach:
- Base Images: Alpine Linux or Ubuntu 22.04 LTS for minimal attack surface
- Build Process:
- Multi-stage Docker builds to minimize final image size
- Build-time security scanning using Trivy or Snyk
- Image signing and verification using Cosign for supply chain security
- Registry Strategy:
- Private ECR repositories per region with image lifecycle policies
- Image pull secrets configured at namespace level
Deployment Strategy
The system will use a hybrid deployment approach:
- Primary Strategy: Blue-green deployments with 100% traffic shift
- Canary Strategy: For new features or major version upgrades, using 10% traffic split to validate in production
- Traffic Management:
- Kubernetes Ingress controller with custom routing rules
- Service mesh integration (Istio) for advanced traffic management and observability
- Rollback Triggers:
- Automated rollback on 5xx errors exceeding 5% of traffic
- Manual approval gate for production rollbacks
Auto-Scaling Design
Auto-scaling will be implemented at multiple levels:
- Horizontal Pod Autoscaler (HPA):
- CPU utilization target: 70% for most services
- Memory-based scaling for stateful services (broker, subscriber)
- Vertical Pod Autoscaler (VPA):
- Memory and CPU recommendations based on historical usage patterns
- KEDA (Kubernetes Event-Driven Autoscaling):
- Auto-scale based on message queue depth (SQS/SNS)
- Custom metrics for event processing rate and latency
Infrastructure as Code Approach
Infrastructure will be provisioned using Terraform with the following design principles:
- Module Organization:
pubsub-corefor VPC, security groups, and networkingpubsub-k8sfor EKS cluster configuration and IAM rolespubsub-servicesfor service-specific deployments (publisher, subscriber)
- State Management:
- Remote state using S3 backend with DynamoDB locking
- Version control for all infrastructure changes via GitOps (ArgoCD)
- Compliance and Security:
- Terraform modules validated with tfsec for security checks
- Policy-as-code using OPA/Gatekeeper for Kubernetes admission control
Multi-Region Deployment Strategy
For global availability:
- Active-Active Architecture:
- Each region maintains independent broker clusters
- Cross-region replication using Kafka or SNS cross-region topics
- Traffic Splitting:
- Global load balancer (AWS CloudFront or API Gateway) routes to nearest region
- Service discovery using Consul or Kubernetes DNS for inter-region communication
- Data Synchronization:
- Event replication using Kafka Connect or custom sync services
- Conflict resolution and deduplication strategies for cross-region events
Resource Management and Cost Optimization
- Resource Allocation:
- CPU and memory requests/limits set to 50% of actual usage for better scheduling
- Node taints and tolerations to ensure critical services run on dedicated nodes
- Spot Instance Strategy:
- Non-critical services (worker pods) will use spot instances with preemption handling
- Critical services (broker, API) run on on-demand instances for reliability
- Cluster Efficiency:
- Node pool sizing based on peak QPS capacity requirements (back-of-envelope calculations)
- Resource quotas per namespace to prevent overconsumption
15. Security Architecture
VPC Design and Network Segmentation
The system operates within a multi-AZ VPC architecture with public and private subnets to enforce network isolation. Public subnets host load balancers and API gateways, while private subnets contain application services and databases. All inter-service communication occurs within the private network using internal load balancers. Network ACLs and security groups are configured to restrict traffic at the subnet and instance levels, implementing a zero-trust model where every request must be authenticated and authorized.
Zero-Trust Network Model
All services operate under a zero-trust security model where no service is trusted by default. Every request must pass through authentication and authorization layers before accessing any resource. Service-to-service communication uses mutual TLS (mTLS) with certificate-based authentication to ensure end-to-end encryption and prevent man-in-the-middle attacks. Network policies enforce strict access control between services, preventing lateral movement in case of compromise.
TLS Termination Strategy
TLS termination occurs at the API gateway layer for external traffic, while internal service communication uses mTLS with certificate rotation every 90 days. All external endpoints are served over HTTPS with HSTS headers enabled to prevent protocol downgrade attacks. Certificate management is handled through AWS ACM or HashiCorp Vault, with automatic renewal and failover mechanisms.
DDoS Protection Strategy
DDoS protection is implemented through AWS Shield Advanced or equivalent cloud provider DDoS mitigation services. Traffic filtering rules are configured to drop malicious traffic at the network edge before it reaches application layers. Rate limiting is enforced at the API gateway level to prevent abuse and ensure fair resource allocation across legitimate users.
Secrets Management Architecture
Secrets management is handled through a centralized secrets store (e.g., AWS Secrets Manager, HashiCorp Vault) with automatic rotation for sensitive credentials. Services retrieve secrets at runtime using IAM roles or service accounts with minimal required permissions. Secrets are encrypted at rest and in transit, with audit trails maintained for compliance purposes.
Vulnerability Scanning in CI/CD
Vulnerability scanning is integrated into the CI/CD pipeline using tools like Trivy, Snyk, or SonarQube to scan container images and dependencies for known vulnerabilities. Security scans are run as part of the build process, with automated blocking of images containing critical or high-severity vulnerabilities. Container image scanning is performed at build time, and dependency updates are monitored for security patches.
WAF Rules for Critical Endpoints
Web Application Firewall (WAF) rules are configured to protect critical endpoints from common attack patterns including SQL injection, cross-site scripting (XSS), and command injection. Rules are customized based on threat intelligence feeds and application-specific attack vectors. WAF policies are applied at the API gateway level to filter malicious traffic before it reaches backend services.
Access Control and Authentication
All services implement role-based access control (RBAC) with fine-grained permissions. Service-to-service authentication uses JWT tokens with short TTLs and automatic refresh mechanisms. External API access is protected through OAuth2/OIDC flows with proper scope validation and token introspection. Token revocation is handled through a centralized token management system that invalidates tokens immediately upon user logout or session expiration.
Data Encryption and Compliance
All data at rest is encrypted using AES-256 encryption with keys managed through AWS KMS or equivalent key management services. Data in transit is encrypted using TLS 1.3 with strong cipher suites and forward secrecy. Compliance requirements such as GDPR, HIPAA, or SOC2 are addressed through audit logging, data retention policies, and encryption controls that meet regulatory standards.
16. Deployment & Release Strategy
Deployment Strategy
The system will utilize a canary deployment strategy with progressive traffic shifting to minimize risk during releases. The deployment pipeline will follow a blue-green deployment model for major version changes, with the ability to quickly roll back to the previous stable version.
Traffic management will be handled through Istio-based traffic splitting or service mesh routing rules, allowing for fine-grained control over traffic distribution across different service versions. The strategy will support:
- Gradual traffic shift: 10% → 25% → 50% → 75% → 100% traffic to new version
- Health check-based routing: Only route traffic to versions that pass pre-defined health checks
- Automated rollback: If error rates exceed thresholds (e.g., 5% error rate over 5 minutes), automatically shift traffic back to stable version
Artifact Promotion Model
The deployment pipeline will follow a multi-stage promotion model:
- Dev Environment: Continuous integration with unit and integration tests
- Staging Environment: Full end-to-end testing including performance and load testing
- Production Gate: Manual approval process with automated compliance checks
- Production Deployment: Canary deployment to production with monitoring and alerting
Each stage will include:
- Automated security scanning (Snyk, Trivy)
- Compliance validation checks
- Performance regression testing
- Manual approval gates for critical services
Zero-Downtime Database Migration Strategy
Database migrations will be handled using schema migration tools (e.g., Flyway, Liquibase) with the following approach:
- Backward-compatible schema changes: New columns and indexes added without breaking existing functionality
- Feature flags for new database features: Enable/disable new database features through feature flags rather than requiring full deployment
- Rolling schema updates: Apply changes to database in phases across different database instances or shards
- Migration rollback capability: Maintain backup of previous schema versions and migration scripts for quick rollback
Feature Flag Integration and Progressive Rollout Design
Feature flags will be implemented using LaunchDarkly or Flagship for centralized feature management:
- Gradual rollouts: Enable features for 10% of users, then increase to 50%, 90%, and finally 100%
- Segment-based targeting: Target specific user segments (e.g., beta testers, enterprise customers)
- A/B testing capability: Support for A/B testing with statistical significance measurement
- Real-time flag updates: Ability to toggle flags without requiring service restarts
Canary Analysis Automation and Auto-Rollback Triggers
Automated canary analysis will include:
- Error rate monitoring: Track error rates and latency for new versions
- Performance regression detection: Monitor response times and throughput degradation
- Business metric tracking: Monitor key business metrics (conversion rates, user engagement)
- Auto-rollback thresholds:
- Error rate > 5% over 5 minutes → rollback
- Latency increase > 30% over 10 minutes → rollback
- Business metric degradation > 10% over 15 minutes → rollback
Release Cadence and Branching Strategy
The system will follow a trunk-based development model with the following release cadence:
- Minor releases: Every 2 weeks for new features and improvements
- Patch releases: As needed for critical bug fixes and security patches
- Major releases: Every 3 months for significant architectural changes
Branching strategy:
- Main branch: Production-ready code with feature flags for upcoming features
- Feature branches: Short-lived branches for experimental features (max 2 weeks)
- Release branches: Created for release preparation and bug fixes only
The trunk-based approach minimizes merge conflicts, enables continuous integration, and ensures that all code is tested in production-like environments before release. Release branches will be used only for hotfixes and security patches, with proper merge strategies to maintain consistency across branches.
The deployment strategy ensures that the system can handle rapid iteration while maintaining stability and reliability through automated testing, progressive rollouts, and robust rollback mechanisms. This approach balances the need for fast delivery with operational reliability and risk mitigation.
17. Cost Architecture
Major Cost Drivers Analysis
Compute Costs:
- Message brokers (Kafka/Pulsar): Primarily driven by CPU and memory usage, with cost scaling linearly with message volume and partition count
- Event processing services: Variable based on concurrent consumers, CPU-intensive transformations, and service instance count
- API gateway and edge services: Ingestion rate dependent, with cost scaling with QPS and request size
- Caching layer (Redis): Memory usage directly impacts cost, with multi-AZ redundancy adding 2x cost
Storage Costs:
- Message persistence: Event retention policies directly impact storage costs, with hot/warm/cold tiering providing cost optimization
- Metadata stores: Relational DBs for topic/subscription metadata, with read-heavy workloads
- Object storage (S3/GCS): For large payloads or event archives, with cost varying by access frequency and region
Network & Data Transfer Costs:
- Inter-service communication: Internal network traffic, with cross-region costs being 5x higher than same-region
- External integrations: Egress to third-party services, with per-message cost in high-volume scenarios
- Data egress from cloud: Per-GB cost for data leaving cloud regions, particularly impactful for global systems
Cost Optimization Strategy
Storage Tiering:
- Hot Tier: Recent 7 days of events stored in high-IOPS SSDs (e.g., Kafka on AWS EBS gp3)
- Warm Tier: 30-day retention in standard storage (e.g., S3 Standard-IA)
- Cold Tier: Archive storage (e.g., S3 Glacier Deep Archive) for long-term compliance retention
Compute Optimization:
- Instance Type Selection: Use burstable instances (t3/t4) for low-volume periods, switch to compute-optimized (c5/c6) during peak
- Spot Instances: For non-critical processing services, with 90% cost savings and 10% risk of interruption
- Auto-scaling: HPA with CPU/memory thresholds to avoid over-provisioning during low-load periods
Data Transfer Optimization:
- Cross-region replication: Minimize inter-region traffic by colocating services in same region
- Compression: Enable compression (gzip) for messages to reduce bandwidth by 30-50%
- Batching: Process events in batches (100-1000 events) to reduce per-message overhead
Reserved vs. Spot Instance Strategy
Reserved Instances:
- Primary brokers: 3-year reserved instances for Kafka/Pulsar clusters to save up to 75% on compute costs
- Metadata services: Reserved instances for relational DBs and Redis clusters to ensure availability during peak
Spot Instances:
- Event processing workers: Use spot instances for non-critical consumer services with retry logic and idempotent processing
- Batch job processors: For nightly batch jobs, with 90% cost reduction and acceptable SLA trade-off
Data Egress Cost Minimization
Internal Traffic Optimization:
- VPC peering: Use VPC peering for inter-service communication to minimize cross-region egress costs
- Local caching: Reduce external API calls by caching metadata and configuration in local services
Regional Data Handling:
- Edge services: Deploy edge services in same region as consumers to minimize data egress from message brokers
- Content delivery: Use CDN for event payloads that are frequently accessed by end users
FinOps Dashboards and Budget Alerts
Cost Monitoring:
- Real-time cost dashboards: Build Grafana dashboards with Prometheus metrics to track per-service and per-topic costs
- Budget alerts: Configure AWS Budgets or GCP Billing Alerts to notify when spending exceeds 80% of monthly budget
- Cost allocation tags: Use service, team, and environment tags to enable cost attribution for billing
Optimization Automation:
- Cost anomaly detection: Use ML-based anomaly detection to identify unexpected cost spikes
- Right-sizing recommendations: Integrate with cloud provider's auto-scaling and right-sizing tools to optimize instance types
- Storage lifecycle policies: Automate transition between storage tiers based on event age and access frequency
This cost architecture provides a balanced approach to cost optimization while maintaining system performance, reliability, and scalability. The strategy focuses on reducing compute and storage costs through intelligent tiering and instance selection, while minimizing network egress costs through strategic placement and data handling.
18. Open Questions, Risks & Trade-offs
Decisions requiring product / engineering alignment
- Event schema evolution strategy: How do we handle breaking changes to event schemas? Do we version events at the topic level or use a centralized schema registry?
- Exactly-once processing guarantee: Should we prioritize exactly-once semantics across all services or accept at-least-once for better performance and simpler implementation?
- Cross-service data ownership: How do we enforce the no-shared-database rule when services may need to read from each other's event streams for operational purposes?
- Service mesh adoption: Should we invest in service mesh for mTLS, observability, and traffic management, or build these capabilities natively into services?
Key architectural risks
| Risk | Impact | Likelihood | Mitigation |
|---|---|---|---|
| Message loss during broker failures | High | Medium | Implement dead letter queues, message deduplication, and robust consumer error handling |
| Event ordering violations in sharded systems | Medium | High | Use partition keys that ensure consistent ordering and implement sequence numbers |
| Cache stampedes during warmup | Medium | Medium | Implement cache warming with exponential backoff and circuit breaker patterns |
| Data consistency across services in CQRS | High | Medium | Use event sourcing and eventual consistency patterns with compensating transactions |
| Multi-region sync latency | High | Low | Implement conflict resolution strategies and use last-write-wins with versioning |
Trade-offs made with justification
- Consistency vs. availability: Chose eventual consistency over strong consistency to ensure high availability and horizontal scaling capability, with compensating actions for data integrity
- Performance vs. observability: Prioritized performance and throughput over comprehensive tracing in high-volume paths, using sampling strategies for telemetry
- Simplicity vs. flexibility: Chose a simpler topic-based pub/sub model over a complex routing system to reduce operational complexity and improve maintainability
- Monolithic vs. distributed: Used a distributed message broker approach over monolithic event handling to enable independent scaling and reduce coupling between services
Alternatives considered and rejected
- RabbitMQ vs. Kafka: Rejected RabbitMQ due to its limited horizontal scaling capabilities and higher operational complexity for large-scale event streaming
- Custom message broker vs. open-source: Rejected building a custom broker due to high development and maintenance costs, preferring proven open-source solutions like Apache Kafka
- Event-driven vs. request-response: Rejected monolithic request-response architecture for better decoupling and scalability in a microservices environment
- Database-per-service vs. shared event store: Rejected shared event stores to maintain service autonomy and prevent single points of failure
Technical debt acknowledged
- Schema evolution complexity: The current approach to event schema versioning adds operational overhead and requires careful management of backward compatibility
- Consumer lag monitoring: Lack of built-in consumer lag alerting may lead to delayed detection of processing bottlenecks
- Cross-service event dependencies: Services that depend on events from other services create implicit coupling that's hard to track and manage
- Event replay complexity: The event replay mechanism requires additional infrastructure for maintaining historical event state and handling replay scenarios
19. Phased Implementation Roadmap
Phase 1: MVP (Minimum Viable Architecture)
Timeline: Weeks 1-4 Critical Path: Core messaging infrastructure, basic pub/sub functionality, minimal service boundaries
Deliverables:
- Single-region message broker (Apache Kafka or AWS MSK) with basic topic creation and message publishing
- Core pub/sub service with minimal API surface (publish, subscribe, basic filtering)
- Simple consumer group management
- Basic authentication and authorization for publishers/subscribers
- Single database instance (PostgreSQL) for metadata storage
- Basic observability stack with Prometheus and Grafana
- Simple Kubernetes deployment with basic HPA configuration
Dependencies:
- Cloud infrastructure provisioning (VPC, security groups)
- CI/CD pipeline setup with basic testing
- Basic monitoring and alerting infrastructure
Phase 2: Scale (Hardening & Optimization)
Timeline: Weeks 5-10 Critical Path: Multi-region support, horizontal scaling, reliability improvements
Deliverables:
- Multi-region deployment with active-active configuration
- Horizontal sharding of message brokers across regions
- Enhanced consumer group management with dynamic scaling
- Database sharding strategy (hash-based partitioning)
- Advanced caching layer with L1/L2 cache hierarchy
- Improved reliability patterns (circuit breaker, bulkhead)
- Enhanced observability with distributed tracing and structured logging
- Feature flag integration for progressive rollouts
Dependencies:
- Multi-region VPC configuration and cross-region connectivity
- Enhanced security infrastructure (mTLS, secrets management)
- Advanced monitoring and alerting system with SLO tracking
Phase 3: Excellence (Reliability, Observability, Cost Optimization)
Timeline: Weeks 11-16 Critical Path: Production-grade reliability, comprehensive observability, cost optimization
Deliverables:
- Full multi-region disaster recovery capability with automatic failover
- Advanced event replay and reprocessing system
- Comprehensive audit logging and compliance tracking
- Cost optimization with reserved instances and data egress reduction
- Advanced search and filtering capabilities for event subscriptions
- Service mesh integration with Istio for enhanced observability and security
- Automated chaos engineering experiments (GameDays)
- Advanced capacity planning with predictive load forecasting
Dependencies:
- Production-grade security infrastructure (zero-trust model)
- Advanced CI/CD with automated canary deployments
- Comprehensive testing and validation infrastructure
Critical Path Dependencies:
- Infrastructure Setup - VPC, security groups, multi-region connectivity (Week 1)
- Core Messaging Layer - Message broker setup and basic pub/sub (Week 3)
- Authentication & Authorization - Identity provider integration and RBAC (Week 4)
- Observability Stack - Logging, tracing, metrics infrastructure (Week 5)
- Multi-Region Support - Cross-region replication and failover (Week 8)
Milestones:
- Week 4: MVP functional end-to-end system with basic reliability
- Week 10: Scale-ready architecture with multi-region support and horizontal scaling
- Week 16: Production-grade system with comprehensive observability and cost optimization
Risk Mitigation:
- High-Risk: Multi-region failover - Addressed by implementing automated disaster recovery and regular failover testing
- High-Risk: Data consistency across regions - Addressed by implementing strict ordering guarantees and cross-region synchronization
- High-Risk: Performance degradation under load - Addressed by implementing comprehensive caching and database optimization strategies
Success Criteria:
- 99.9% availability target met across all regions
- Sub-100ms p50 latency for core publish/subscribe operations
- Support for 1M concurrent subscribers with 100K QPS peak throughput
- Comprehensive observability with SLO tracking and alerting
- Production-ready security and compliance capabilities