Strands Robots + LeRobot + HF Buckets: One Record-Train-Deploy Loop
In this article
Hugging Face and AWS published a detailed integration walkthrough on August 13, 2026, following an earlier post that moved data from the Hub to a physical robot. This one runs data the other way: from a recorded frame through a Storage Bucket, into a streaming training job, and back to a deployed policy on hardware — with the dataset staying in LeRobot format throughout. For robotics and agent developers navigating the agentic era, the post is notable not for what it announces but for what it demonstrates working together: Strands Robots (Apache 2.0, from AWS), LeRobot's dataset stack, and Hugging Face Storage Buckets — a mutable, Xet-backed repository type announced in March 2026 — composing into a record-train-deploy loop that runs from a laptop with three install commands.
The scale of the underlying ecosystem gives the integration immediate reach. LeRobot's dataset format is already in use across more than 90,000 datasets and models on the Hub from over 8,000 publishers. A recording produced by Strands Robots is structurally identical to any other LeRobot dataset, so every tool already built to read that format reads it without conversion.
Architecture: One Object, Four Stages
The pipeline is organised around a single Robot("so100") factory that resolves a name against a catalog of arms, humanoids, mobile bases, and hands. That same object records a LeRobotDataset, streams it back for inspection or training, and — with mode="real" and a port argument — drives the physical arm. The four stages share one backend and one on-disk format.
Recording writes episodes as Parquet shards under data/chunk-000/file-000.parquet (rolling at LeRobot's default of 100 MB) and per-camera MP4 shards under videos/observation.images.front/chunk-000/file-000.mp4 (rolling at 200 MB). sync_dataset_to_bucket(root, bucket, run_id=...) pushes that directory into hf://buckets/{bucket}/{run_id}, decoupled from the recording session. The same sync is available on DatasetRecorder.sync_to_bucket() or inline at stop_recording(bucket=...). For the versioned, reviewed artifact, push_to_hub() to a dataset repository is unchanged; the bucket is explicitly the working layer.
The hardware recording path uses LeRobot's own CLI — lerobot-record with --robot.type=so101_follower and --teleop.type=so101_leader — and produces the same directory layout, so sync_dataset_to_bucket takes it to a bucket with identical arguments.
Storage: Byte-Level Deduplication Changes the Sync Cost
The central economic argument for buckets over versioned dataset repositories is Xet's content-defined chunking. Chunk boundaries follow the content rather than fixed offsets, so inserting or changing a small number of bytes only affects the chunks those bytes land in. Hugging Face's own bucket benchmark measurements show the effect concretely: starting from a 500 MB upload, re-uploading after changing 1% of the bytes transferred 5.5 MB; changing 5% transferred 27.5 MB; changing 10% transferred 55 MB. Without chunk-level deduplication, overwriting an object re-sends every byte. Across the full Hub, content-defined chunking reduces data transferred per upload by approximately four times, and on Enterprise plans billing is on the deduplicated footprint.
Because LeRobot rolls to a new file only when the current one fills, a sync after a day of recording uploads the new trailing shards plus the one partially-filled shard that grew — not the entire dataset.
Training: Streaming vs. Downloading
stream_dataset("my-org/robot-fave/cube_pick", repo_type="bucket") returns a StreamingLeRobotDataset that reads batches directly from the remote shards. The only local write is the small meta/ folder of schema, statistics, and episode index. Camera frames decode from remote MP4 shards on the fly via torchcodec; state and action vectors come from the Parquet shards. For proprioceptive-only workloads, drop_videos=True skips video decode entirely.
The lerobot-train CLI reaches the same engine through --dataset.repo_type=bucket --dataset.streaming=true; the bucket type requires the streaming flag and rejects the combination otherwise. For custom loops, the reader exposes a .dataloader(batch_size=64, num_workers=4) method that feeds a standard PyTorch training step.
On a single NVIDIA L4 (g6.4xlarge), 500 optimizer steps of ACT (51.6M parameters, effective batch size 8) over a 120-frame episode completed in 133 seconds. The checkpoint loads back through create_policy(result.checkpoint_dir), the same entry point used for any other policy. The TrainSpec and create_trainer() lifecycle extends to GR00T and Cosmos 3 behind their own provider strings, with each backend validating its own required fields before training begins.
Throughput on a warm CDN cache reached approximately 1,086 MB/s on a 10 GB payload and approximately 1,124 MB/s at 100 GB, measured on an m5dn.24xlarge in us-east-1, versus approximately 780 MB/s cold. Storage region selection is available on Team and Enterprise plans, currently US and EU, with Asia-Pacific and GCC announced as forthcoming.
Deployment Path and Key Tradeoffs
| Dimension | Storage Bucket (hf://buckets/…) | Versioned Dataset Repository (push_to_hub) |
|---|---|---|
| Mutation model | Overwrite in place, no revision history | Every append is a commit; all revisions retained |
| Deduplication | Xet content-defined chunking; ~4× reduction in bytes transferred (Hub-wide measurement) | File-level; changing one byte in a shard re-uploads the shard |
| Streaming read | stream_dataset(repo_type="bucket"), no local copy required |
Supported; same StreamingLeRobotDataset engine |
| Audit / rollback | None — run_id must be unique per collection run to avoid silent overwrite | Full revision history; every version retrievable |
| Credential setup | hf CLI token scoped to namespace; no IAM roles or CORS rules | Same hf CLI token |
| Intended role | Working layer during active collection campaigns | Reviewed, published artifact |
Deploying the trained checkpoint to hardware requires only adding mode="real", a port, and a cameras dict to the Robot() constructor. Demonstrations recorded on the physical arm return to disk in the same LeRobot format and sync back to the bucket with the same sync_dataset_to_bucket call, closing the loop for the next training run.
The post flags five production security considerations: prompt injection risk, given that the agent writes to shared storage and actuates hardware; keeping collection-write credentials separate from training-read credentials; scoping bucket tokens to a specific namespace; using explicit run_id values per run to avoid silent overwrites; and setting STRANDS_TRUST_REMOTE_CODE=1 only for checkpoints from trusted organisations, with a preference for safetensors format over pickle-based weights.
Bucket streaming was contributed upstream into LeRobot itself, so datasets Strands Robots agents collect are immediately readable by the full LeRobot ecosystem. The reverse is equally true: agents can replay and evaluate against any of the more than 90,000 existing Hub datasets before recording a single new episode — bidirectional compatibility built on an open format rather than a proprietary pipeline.