Question Background
The interviewer threw out a fairly open-ended system-design / data-engineering question:
You have 200TB of media data (images/videos) that needs to be transferred to compute hosts / a compute cluster for processing (preprocessing, inference, training). How would you design this?
There's no standard answer to this one. What it's actually testing is: can you pin down the scope of the requirements first, can you do a quantitative bandwidth/cost estimate, and can you identify the key point that "don't connect directly to a single machine — use intermediate storage to decouple." Below is the order I actually walked through it in the interview.
Step 1: Clarify first, don't rush to answer
I didn't jump straight into drawing an architecture. I first asked a few questions that would determine which direction the design should go:
- One-time or recurring? A one-time cold migration and a daily data feed call for completely different designs.
- Where is the data source? On-prem / another data center / already sitting in cloud object storage? Are the source and destination in the same region, or cross-region / cross-ocean?
- What's the network between the two ends? Public internet, a dedicated line (something like Direct Connect / Interconnect), or is there no network at all and it has to be physically shipped? Is the available bandwidth 1Gbps, 10Gbps, or 100Gbps?
- What's the time requirement? Can it take a few days, or does it need to be ready within hours?
- Is the "processing host" a single machine or a cluster? Does the data need to land on one machine's local disk, or does it need to be read repeatedly by an entire GPU cluster?
- What shape is the data in? Is the 200TB a huge number of small files (millions of images), or a small number of large files (long videos)? Lots of small files bring metadata/IO overhead problems.
Interviewer's feedback: asking clarifying questions was itself a point in my favor. He confirmed this was a one-time large-batch cold migration, the source was on-prem, the destination was a GPU training cluster in the cloud, and a few days were allowed.
Step 2: Bandwidth math — first figure out whether the network is even viable
This is, I think, the point in this question where candidates get separated the most. First get the unit conversion straight:
200TB = 200 × 10¹² bytes = 1.6 × 10¹⁵ bit = 1,600,000 Gbit
Estimated transfer time at ideal full speed on different links:
| Link bandwidth | Ideal transfer time | Realistic ~70% effective throughput |
|---|---|---|
| 1 Gbps | ≈ 18.5 days | ≈ 26 days |
| 10 Gbps | ≈ 1.85 days | ≈ 2.6 days |
| 100 Gbps | ≈ 4.4 hours | ≈ 6.3 hours |
Conclusion: if you only have an ordinary ~1Gbps-class link, going over the network takes close to a month, which is basically unacceptable → you should physically ship the data (more on this below). If you have a 10Gbps dedicated line, two or three days is acceptable, so the network approach works. If you have a 100Gbps-class dedicated line, it's done in a few hours, and network is the best option.
A practical rule of thumb: when "network transfer time" is greater than "the time to box up the drives and ship them," you should physically ship the data. At the 200TB scale, with only ordinary bandwidth, physical migration is often faster.
Step 3: Two main approaches
Option A: Physical shipping (the first choice when bandwidth is insufficient / it's one-time)
Use a cloud vendor's data migration appliance (things like AWS Snowball, Azure Data Box, GCP Transfer Appliance):
- Each device holds on the order of tens of TB, so 200TB needs several loaded in parallel.
- Copy the data onto the device locally (limited by local disk IO, takes hours to a day), ship it back to the cloud vendor, and they import it into object storage.
- Door-to-door is usually done within a week, and it doesn't eat into production network bandwidth.
- Key point: you need a checksum throughout to guarantee data integrity, and the devices are usually self-encrypting.
Option B: Network transfer (when you have a dedicated line / need recurring migration)
Core principle: don't dump the 200TB directly onto a single "processing host's" local disk.
The right approach is to introduce object storage as an intermediate landing zone, e.g. S3 / GCS:
On-prem data source ──(dedicated line, multiple parallel streams)──▶ Object storage (S3/GCS) ──▶ Compute cluster pulls as needed
Reasoning:
- Decoupling: transfer and consumption are decoupled. A failed transfer can resume from where it left off, and the consuming side can pull on demand at any time — neither side blocks the other.
- A single machine can't hold it and shouldn't have to: 200TB is far more than one machine's local disk can hold; object storage scales out naturally and can be read by the whole cluster.
- Fault tolerance: object storage has high durability, so it's naturally the "source of truth" for the data.
Engineering points for the network transfer itself:
- Chunking + multiple parallel streams: split large files into chunks and upload with multiple parallel connections to fully saturate the bandwidth (a single TCP stream is often limited by RTT and can't fill a dedicated line).
- Resumable transfer / idempotency: each chunk carries a checksum; on failure, only that chunk needs to be retransmitted.
- Network tuning: dedicated-line interconnect, jumbo frames (larger MTU to reduce packet overhead), multiple streams; for cross-cloud/cross-region transfers, use private links rather than public internet egress.
- Security boundary: encryption in transit (TLS), encryption at rest (KMS), and network-layer access control policies, to avoid exposing the data plane to the public internet.
Step 4: Use a queue to decouple the consumer side (a step further, worth extra points)
If it's a recurring data feed, I added further: put a message queue / event notification layer (like S3 Event → SQS / Pub/Sub) between object storage and the compute cluster.
- Every time new data lands in object storage, a message goes into the queue.
- Workers on the processing cluster consume from the queue and pull the corresponding object on demand.
Benefits: the producer (transfer) and the consumer (processing) are fully decoupled, processing nodes can scale elastically based on queue length, and if a worker dies the message can be redelivered — no data is lost.
This is the key step that takes you from "a one-time data move" up to "a sustainable data pipeline."
Step 5: The interviewer's follow-up — connecting it to the ML training pipeline
The interviewer then pushed further in the AI/ML direction: once the data is in object storage, how do you feed it efficiently to GPU training?
The core tension here is GPU starvation — GPUs are expensive, and you can't let them sit idle. If data loading can't keep up, GPU utilization drops and that's money burning. My answer:
- Offline preprocessing + sharded packing: don't wait until training time to read millions of small files (random small-file reads are a disaster for IO). Preprocess the data ahead of time and pack it into ML-oriented shard formats (WebDataset tar shards, TFRecord, etc.), aggregating a huge number of small files into a small number of large shards, turning random reads into sequential reads.
- Streaming datasets: stream the shards directly from object storage during training, instead of pulling the full 200TB to local disk first (which wouldn't fit anyway). Train while downloading, with a prefetch buffer.
- Input pipeline optimization: multiple workers loading and decoding data in parallel, overlapping data prep with GPU compute (prefetch/pipeline), so the GPU always has data to consume at every step. Use a shuffle buffer rather than a global shuffle to balance randomness against throughput.
- Locate the bottleneck: figure out whether the bottleneck is network bandwidth, CPU decoding, or GPU compute, and address it accordingly — that determines whether you should add bandwidth, add CPU workers, or switch to a cheaper preprocessing format.
Retrospective
What decides this question isn't "knowing about Snowball" — it's the bandwidth math. Being able to work out 200TB / link speed on the spot and give a quantitative call on "network vs. ship the drives" immediately separates candidates.
"Don't connect directly to a single machine, use object storage to decouple" is the main point and will almost always be tested.
Clarifying "one-time vs. recurring" matters a lot — it decides whether you need to bring in a queue and a persistent pipeline.
For an AI/ML role, they will definitely push toward the training data pipeline / "GPU can't starve" direction, so have the "shard format + streaming reads + input pipeline overlap" line ready ahead of time.
Remember to mention data integrity (checksums) and security (encryption in transit/at rest, network boundaries) throughout — that's what separates a senior candidate from an average one.
Discussion
Loading comments…