LogAggregation Interview Questions | JiQuest

add

#

LogAggregation

System design deep dive · HLD

Design a log aggregation system (ELK-style): full high-level design.

Requirements, back-of-envelope capacity estimation, a high-level design diagram, a deeper deployment architecture diagram, sequence diagrams for log shipping/indexing and full-text search, and an entity-relationship diagram for the metadata model - with the reasoning an interviewer expects behind every box and arrow.

2.5M/sPeak log lines (incident)
50KHosts shipping logs
21TB/dayRaw ingest volume
Host + agenttails log file Collectorbuffers, batches Parse + enrichstructure fields Search indexqueryable in seconds Kafka bufferabsorbs spikes rollover + retention applied

1. Clarify requirements before drawing any box

A log aggregation system is most stressed exactly when it's most needed: during an incident, when log volume spikes 5-10x and engineers are simultaneously running expensive ad hoc searches - so ingestion must never be the thing that falls over.

Functional requirements

Ship logs from every hostCollect stdout/log files from tens of thousands of hosts and containers continuously.
Parse and structureExtract fields (level, service, trace_id, timestamp) from semi-structured or free-text lines.
Full-text and field searchEngineers query by free text, exact field match, and time range, typically during an incident.
Retention and rolloverOlder logs age from fast/expensive storage to cheap/slow storage, then are deleted per policy.

Non-functional requirements

Ingestion must never block the appA slow or down logging pipeline must not cause backpressure into production services.
Search latency under loadCommon incident queries return in a few seconds even during a volume spike.
Write-heavy at massive scaleIngest throughput dwarfs query throughput by orders of magnitude.
Cost-aware retentionHot storage is expensive; most logs are read within hours of being written and rarely after.
Explicitly out of scope Real-time alerting/anomaly detection rules engine, log-based metrics dashboards, and distributed tracing correlation UI are called out as adjacent products rather than core requirements, so the core design stays focused on ship, index, and search.

2. Back-of-the-envelope capacity estimation

These numbers decide the size of the Kafka buffer needed to survive an incident-driven spike, how many index shards are needed, and how the hot/warm/cold tiering saves cost.

MetricAssumptionResulting estimate
Fleet size50,000 hosts/containers, ~10 log lines/sec/host average~500,000 log lines/sec average
Incident spikeError-heavy code paths log 5x more during an outage~2.5 million log lines/sec peak - this is the number the pipeline must absorb without dropping data
Raw ingest volume~500 bytes/line average (message + structured fields)500K/s × 500B ≈ 250 MB/sec ≈ ~21.6 TB/day raw
Indexed sizeInverted index + stored fields typically ~1.1x raw after compression trade-offs~24 TB/day added to the hot tier
Hot tier retention7 days of fast, frequently-queried storage (SSD-backed)~170 TB hot tier, sized for sub-second recent-log queries
Warm/cold tiers30 days warm (spinning disk/cheaper nodes), 1 year cold (object storage, rarely queried)~720 TB warm, several PB/year cold - driving the case for tiered storage instead of one uniform cluster
Why this matters The 5x gap between average and incident-time peak is the number that justifies putting a durable buffer (Kafka) between shipping and indexing - indexing can fall behind by minutes during a spike and catch up afterward, as long as nothing upstream of the buffer is ever lost.

3. High-level design (HLD)

The HLD names the major components and the one-directional data flow from a log line on disk to a searchable, retained document, without yet committing to shard counts, tiering policy, or cluster topology.

Hosts + agentsFilebeat / Fluent Bit Collector tierreceive, batch, ack Kafkadurable buffer Parser/enricherLogstash-style pipeline Hot index shardslast 7 days Warm / cold tiersrollover + archive Query APIfull-text + field search
Stateless pipeline servicesFast-path infraDurable index storageAsync / edge

What each box owns

Host agent and collector tier

A lightweight agent (Filebeat/Fluent Bit-style) tails log files or reads container stdout, tracks its own read offset so it can resume after a restart without re-reading or losing lines, and ships batches to a collector over a lossy-tolerant protocol with local disk buffering if the collector is unreachable - this local buffer is what protects the application from ever blocking on logging.

Kafka buffer

Decouples "receiving a log line" from "indexing a log line." During a 5x incident spike, the collector keeps accepting and producing to Kafka at full rate even if the indexing pipeline temporarily falls behind - the buffer's retention window (a few hours) is the slack that lets indexing catch up after the spike passes instead of dropping data.

Parser/enricher pipeline

Applies grok-style pattern matching or structured (JSON) parsing to extract fields like level, service, trace_id, and host, tags the document with the source's known metadata (region, environment), and normalizes timestamps to UTC. Lines that fail to parse are still indexed with the raw message intact and a parse_failed flag, rather than being dropped.

Tiered index storage and query API

New documents land in hot-tier shards on fast storage for the first several days when they're most likely to be queried during active incident response. An index lifecycle policy rolls indices to warm and then cold tiers (cheaper storage, fewer replicas) as they age, and eventually deletes them per retention policy. The query API fans a search out only to the indices whose time range overlaps the query, which is what keeps a "last 15 minutes" search fast even with petabytes retained overall.

4. Detailed architecture diagram

The architecture diagram answers how backpressure is actually handled at the agent, how the search cluster is sharded and tiered, and how rollover/retention runs without downtime - the details an interviewer checks once the HLD shape is accepted.

Agent fleet (on every host) Fluent Bit sidecartracks file offset checkpoint Local disk spoolbuffers on collector outage Backpressure-aware batchingdrop-oldest at spool cap TLS-authenticated shipping Ingestion tier Collectors ×60 nodes Kafka, 256 partitions Partition key: service+host6h retention window= indexing catch-up slack Indexing pipeline (auto-scaling consumers) Parse/enrich workers Bulk indexer workers Scales 10-150 consumerson consumer-lag metric,not on ingest rate directly Hot tier SSD nodes, daily indices 7 days, 2 replicas, sharded by day Warm tier HDD nodes, merged indices 30 days, 1 replica, force-merged segments Cold / archive tier Object storage (S3), compressed 1 year, rarely queried, ILM auto-deletes past that
DecisionChoiceReasoning
Local disk spool on the agentBuffer-then-drop-oldest, not block-the-applicationA logging pipeline outage must never propagate backpressure into production request handling; losing the oldest buffered logs is an acceptable trade-off, silently blocking writes is not.
Kafka retention window~6 hours, sized to the largest expected indexing outageGives the indexing pipeline enough slack to fall behind during a spike and catch up afterward without permanently losing data.
Index shardingTime-based daily indices, not one giant indexLets old data be dropped by simply deleting whole indices (cheap) instead of running expensive delete-by-query across a monolithic index.
Hot/warm/cold tieringSSD (7d) → HDD (30d) → object storage (1yr)Most queries target the last few days; paying for SSD-speed storage on data nobody queries anymore would multiply cost for no benefit.

5. Sequence diagrams for the two critical flows

A sequence diagram is where an interviewer checks whether shipping is decoupled from indexing, and whether a search actually narrows its scope by time before touching data.

5.1 Log shipping and indexing

Agent Collector Kafka Parser worker Hot index 1. batch of tailed log lines 2. produce(topic=service_x, batch) 3. ack offset 4. advance local checkpoint 5. consume batch 6. parse fields, enrich, normalize ts 7. bulk index request 8. indexed, refresh interval elapses

Step 4 - advancing the agent's local checkpoint only after Kafka acks the batch in step 3 - is what makes the pipeline crash-safe: if the collector or the agent restarts before the ack, the same lines are re-read and re-shipped rather than silently lost, and downstream idempotent handling (or accepted rare duplicates) is preferred over any risk of a gap. Step 8's "refresh interval" is a deliberate small delay (typically ~1s) before a newly indexed document becomes visible to search - a knob traded against indexing throughput.

5.2 Full-text search query across a time range

Engineer Query API Hot shards (today) Warm shards (excluded) 1. search: "error trace_id:X" last 15m 2. resolve indices overlapping time range 3. fan out only to today's hot shards 4. warm/cold indices skipped entirely (out of range) 5. per-shard matches + relevance score 6. merge, sort by score/time, dedupe 7. top N results

Step 2 is the single biggest performance lever in the whole query path: because indices are partitioned by day, the query planner can discard every index outside the requested time range before issuing a single shard query, rather than relying on a query-time filter to skip irrelevant data after reading it. Step 4 makes that skip explicit - the warm/cold tiers are never touched for a "last 15 minutes" search, which is exactly why petabytes of retained cold data don't slow down the incident-response query engineers actually run.

6. Entity-relationship (ER) diagram and schema

Unlike the previous systems, the bulk of the data (log_entries) lives in a search engine's inverted index, not a relational table - but the metadata that controls sourcing, indexing, and retention is genuinely relational and worth modeling explicitly.

log_sources PK id BIGINT hostname VARCHAR service,env VARCHAR last_shipped_at TIMESTAMP agent_version VARCHAR indices PK name VARCHAR date_range DATERANGE shard_count INT tier ENUM(hot,warm,cold) doc_count BIGINT size_bytes BIGINT delete_after TIMESTAMP log_entries (doc) PK doc_id UUID FK source_id BIGINT FK index_name VARCHAR level,message TEXT NN 1N a source's entries land across many daily indices; one index holds entries from many sources for one day

Key modeling decisions

log_entries is a search-engine document, not a relational rowIts inverted index over `message` is what makes free-text search fast; a relational table would need a much slower LIKE-style scan.
indices is metadata, tracked outside the search engineRetention/rollover jobs decide what to delete or tier by querying this small metadata table instead of introspecting every shard directly.
log_sources.last_shipped_at powers a "silent host" alertA host that stops shipping logs (crashed agent, network partition) is itself an operational signal, not just an ingestion gap.
Indices are named by date + optionally by serviceNaming convention (e.g. logs-service_x-2026.09.05) is what lets both time-range pruning and per-service isolation happen without extra metadata lookups.
Storage choiceUse whenWatch out for
Inverted-index search engine (Elasticsearch/OpenSearch) for log_entriesFree-text search and relevance ranking across huge volumes is the primary access pattern.Expensive per-document overhead compared to columnar stores; mapping explosion from unbounded dynamic fields must be controlled.
Relational (Postgres) for log_sources and indices metadataSmall tables (thousands to low millions of rows) needing simple queries for lifecycle management and alerting.Not meant to scale to log volume itself - keep raw log content out of this tier entirely.

7. Deep dives interviewers actually probe

How do you handle a 5-10x log volume spike during an incident without dropping data?

Two layers absorb it: the agent's local disk spool tolerates a slow or unreachable collector for minutes without blocking the application, and Kafka's multi-hour retention window absorbs the gap between spike-time ingest rate and the indexing pipeline's steady-state throughput. Indexing consumers auto-scale on consumer lag (not on raw ingest rate, which is noisy) so the pipeline catches up within minutes after the spike passes, rather than needing to be provisioned for peak load year-round.

Why time-based daily indices instead of one continuously-growing index?

Deleting expired data becomes dropping a whole index (near-instant metadata operation) instead of a delete-by-query that has to find and mark documents individually across a monolithic index - the latter is slow and fragments the index, requiring expensive background merges. Daily indices also let the query planner skip entire indices outside a query's time range before touching any shard, which is the main reason time-bounded searches stay fast at any retained volume.

What happens to a log line that fails to parse?

It's still indexed - with the raw message stored verbatim and a parse_failed:true field - rather than dropped, because losing visibility into exactly the malformed, often error-adjacent lines during an incident is worse than having an imperfectly structured document. A separate low-volume metric tracks the parse failure rate per source so a service that starts emitting a new, unrecognized log format gets noticed and its parser pattern updated.

How does hot/warm/cold tiering actually save cost without breaking search?

Warm-tier nodes use cheaper spinning disks and drop replica count from 2 to 1 (some durability risk accepted for cost, since this is operational log data, not the system of record). Indices are force-merged into fewer, larger segments once they roll to warm - segment merging is expensive so it only happens once, after writes to that index have stopped. Cold tier moves to object storage entirely, sacrificing query latency for near-zero storage cost, which is acceptable since cold-tier queries are rare, deliberate lookups (compliance/forensics), not the incident-response fast path.

How do you prevent one noisy service from overwhelming the shared cluster?

Per-source ingest quotas at the collector tier (a service producing far above its historical baseline gets rate-limited, with a metric alerting the owning team rather than silently truncating), plus separate Kafka topics per major service so one service's backlog doesn't head-of-line-block another's. On the query side, a per-query timeout and a maximum-indices-touched cap prevent one engineer's overly broad "search everything, all time" query from starving cluster resources needed for active incident response.

8. Summary: what a strong answer covers

Clarified scope before designingJustified every number with a calculationDecoupled shipping from indexing with a buffer Named the sharding/tiering scheme and whyNever dropped logs, even malformed onesMade time-range pruning the core search optimization
Interview tip When asked to design a log aggregation system, the strongest signal is explicitly designing for the incident scenario - the moment log volume spikes and query load spikes simultaneously - rather than only sizing the system for calm, average-day traffic; that's precisely when the system is needed most and most likely to be under strain.
No comments
Leave a Comment